Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270317
b: refs/heads/master
c: 6af8bef
h: refs/heads/master
i:
  270315: 7a42e0f
v: v3
  • Loading branch information
Prarit Bhargava authored and Jesse Barnes committed Oct 14, 2011
1 parent cbf3fe2 commit ab21aef
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 379021d5c0899fcf9410cae4ca7a59a5a94ca769
refs/heads/master: 6af8bef14d6fc9e4e52c83fd646412e9dedadd26
3 changes: 2 additions & 1 deletion trunk/drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq;
static struct workqueue_struct *kacpi_notify_wq;
static struct workqueue_struct *kacpi_hotplug_wq;
struct workqueue_struct *kacpi_hotplug_wq;
EXPORT_SYMBOL(kacpi_hotplug_wq);

struct acpi_res_list {
resource_size_t start;
Expand Down
109 changes: 94 additions & 15 deletions trunk/drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <linux/pci-acpi.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/acpi.h>

#include "../pci.h"
#include "acpiphp.h"
Expand Down Expand Up @@ -1149,27 +1150,54 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK ;
}

/**
* handle_hotplug_event_bridge - handle ACPI event on bridges
* @handle: Notify()'ed acpi_handle
* @type: Notify code
* @context: pointer to acpiphp_bridge structure
*
* Handles ACPI event notification on {host,p2p} bridges.
*/
static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context)
struct acpiphp_hp_work {
struct work_struct work;
acpi_handle handle;
u32 type;
void *context;
};

static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type,
void *context,
void (*func)(struct work_struct *work))
{
struct acpiphp_hp_work *hp_work;
int ret;

hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
if (!hp_work)
return;

hp_work->handle = handle;
hp_work->type = type;
hp_work->context = context;

INIT_WORK(&hp_work->work, func);
ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
if (!ret)
kfree(hp_work);
}

static void _handle_hotplug_event_bridge(struct work_struct *work)
{
struct acpiphp_bridge *bridge;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
struct acpi_device *device;
int num_sub_bridges = 0;
struct acpiphp_hp_work *hp_work;
acpi_handle handle;
u32 type;

hp_work = container_of(work, struct acpiphp_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;

if (acpi_bus_get_device(handle, &device)) {
/* This bridge must have just been physically inserted */
handle_bridge_insertion(handle, type);
return;
goto out;
}

bridge = acpiphp_handle_to_bridge(handle);
Expand All @@ -1180,7 +1208,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont

if (!bridge && !num_sub_bridges) {
err("cannot get bridge info\n");
return;
goto out;
}

acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
Expand Down Expand Up @@ -1241,22 +1269,49 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
break;
}

out:
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
}

/**
* handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
* handle_hotplug_event_bridge - handle ACPI event on bridges
* @handle: Notify()'ed acpi_handle
* @type: Notify code
* @context: pointer to acpiphp_func structure
* @context: pointer to acpiphp_bridge structure
*
* Handles ACPI event notification on slots.
* Handles ACPI event notification on {host,p2p} bridges.
*/
static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
void *context)
{
/*
* Currently the code adds all hotplug events to the kacpid_wq
* queue when it should add hotplug events to the kacpi_hotplug_wq.
* The proper way to fix this is to reorganize the code so that
* drivers (dock, etc.) do not call acpi_os_execute(), etc.
* For now just re-add this work to the kacpi_hotplug_wq so we
* don't deadlock on hotplug actions.
*/
alloc_acpiphp_hp_work(handle, type, context,
_handle_hotplug_event_bridge);
}

static void _handle_hotplug_event_func(struct work_struct *work)
{
struct acpiphp_func *func;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
struct acpiphp_hp_work *hp_work;
acpi_handle handle;
u32 type;
void *context;

hp_work = container_of(work, struct acpiphp_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;
context = hp_work->context;

acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);

Expand Down Expand Up @@ -1291,8 +1346,32 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
break;
}

kfree(hp_work); /* allocated in handle_hotplug_event_func */
}

/**
* handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
* @handle: Notify()'ed acpi_handle
* @type: Notify code
* @context: pointer to acpiphp_func structure
*
* Handles ACPI event notification on slots.
*/
static void handle_hotplug_event_func(acpi_handle handle, u32 type,
void *context)
{
/*
* Currently the code adds all hotplug events to the kacpid_wq
* queue when it should add hotplug events to the kacpi_hotplug_wq.
* The proper way to fix this is to reorganize the code so that
* drivers (dock, etc.) do not call acpi_os_execute(), etc.
* For now just re-add this work to the kacpi_hotplug_wq so we
* don't deadlock on hotplug actions.
*/
alloc_acpiphp_hp_work(handle, type, context,
_handle_hotplug_event_func);
}

static acpi_status
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/acpi/acpiosxf.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ void acpi_os_fixed_event_count(u32 fixed_event_number);
/*
* Threads and Scheduling
*/
extern struct workqueue_struct *kacpi_hotplug_wq;

acpi_thread_id acpi_os_get_thread_id(void);

acpi_status
Expand Down

0 comments on commit ab21aef

Please sign in to comment.