Commit bd4674df authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

ACPI / hotplug / PCI: Embed function struct into struct acpiphp_context

Since there has to be a struct acpiphp_func object for every struct
acpiphp_context created by register_slot(), the struct acpiphp_func
one can be embedded into the struct acpiphp_context one, which allows
some code simplifications to be made.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 75a33ed1
...@@ -116,7 +116,6 @@ struct acpiphp_slot { ...@@ -116,7 +116,6 @@ struct acpiphp_slot {
* typically 8 objects per slot (i.e. for each PCI function) * typically 8 objects per slot (i.e. for each PCI function)
*/ */
struct acpiphp_func { struct acpiphp_func {
struct acpiphp_context *context;
struct acpiphp_slot *slot; /* parent */ struct acpiphp_slot *slot; /* parent */
struct list_head sibling; struct list_head sibling;
...@@ -128,11 +127,16 @@ struct acpiphp_func { ...@@ -128,11 +127,16 @@ struct acpiphp_func {
struct acpiphp_context { struct acpiphp_context {
acpi_handle handle; acpi_handle handle;
struct acpiphp_func *func; struct acpiphp_func func;
struct acpiphp_bridge *bridge; struct acpiphp_bridge *bridge;
unsigned int refcount; unsigned int refcount;
}; };
static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func)
{
return container_of(func, struct acpiphp_context, func);
}
/* /*
* struct acpiphp_attention_info - device specific attention registration * struct acpiphp_attention_info - device specific attention registration
* *
......
...@@ -128,7 +128,7 @@ static void acpiphp_put_context(struct acpiphp_context *context) ...@@ -128,7 +128,7 @@ static void acpiphp_put_context(struct acpiphp_context *context)
if (--context->refcount) if (--context->refcount)
return; return;
WARN_ON(context->func || context->bridge); WARN_ON(context->bridge);
acpi_detach_data(context->handle, acpiphp_context_handler); acpi_detach_data(context->handle, acpiphp_context_handler);
kfree(context); kfree(context);
} }
...@@ -155,12 +155,9 @@ static void free_bridge(struct kref *kref) ...@@ -155,12 +155,9 @@ static void free_bridge(struct kref *kref)
bridge = container_of(kref, struct acpiphp_bridge, ref); bridge = container_of(kref, struct acpiphp_bridge, ref);
list_for_each_entry_safe(slot, next, &bridge->slots, node) { list_for_each_entry_safe(slot, next, &bridge->slots, node) {
list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { list_for_each_entry_safe(func, tmp, &slot->funcs, sibling)
context = func->context; acpiphp_put_context(func_to_context(func));
context->func = NULL;
acpiphp_put_context(context);
kfree(func);
}
kfree(slot); kfree(slot);
} }
...@@ -168,7 +165,7 @@ static void free_bridge(struct kref *kref) ...@@ -168,7 +165,7 @@ static void free_bridge(struct kref *kref)
/* Root bridges will not have hotplug context. */ /* Root bridges will not have hotplug context. */
if (context) { if (context) {
/* Release the reference taken by acpiphp_enumerate_slots(). */ /* Release the reference taken by acpiphp_enumerate_slots(). */
put_bridge(context->func->slot->bridge); put_bridge(context->func.slot->bridge);
context->bridge = NULL; context->bridge = NULL;
acpiphp_put_context(context); acpiphp_put_context(context);
} }
...@@ -190,7 +187,7 @@ static void free_bridge(struct kref *kref) ...@@ -190,7 +187,7 @@ static void free_bridge(struct kref *kref)
static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) static void post_dock_fixups(acpi_handle not_used, u32 event, void *data)
{ {
struct acpiphp_context *context = data; struct acpiphp_context *context = data;
struct pci_bus *bus = context->func->slot->bridge->pci_bus; struct pci_bus *bus = context->func.slot->bridge->pci_bus;
u32 buses; u32 buses;
if (!bus->self) if (!bus->self)
...@@ -251,14 +248,14 @@ static void acpiphp_dock_init(void *data) ...@@ -251,14 +248,14 @@ static void acpiphp_dock_init(void *data)
{ {
struct acpiphp_context *context = data; struct acpiphp_context *context = data;
get_bridge(context->func->slot->bridge); get_bridge(context->func.slot->bridge);
} }
static void acpiphp_dock_release(void *data) static void acpiphp_dock_release(void *data)
{ {
struct acpiphp_context *context = data; struct acpiphp_context *context = data;
put_bridge(context->func->slot->bridge); put_bridge(context->func.slot->bridge);
} }
/* callback routine to register each ACPI PCI slot object */ /* callback routine to register each ACPI PCI slot object */
...@@ -288,23 +285,16 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, ...@@ -288,23 +285,16 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
device = (adr >> 16) & 0xffff; device = (adr >> 16) & 0xffff;
function = adr & 0xffff; function = adr & 0xffff;
newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
if (!newfunc)
return AE_NO_MEMORY;
newfunc->handle = handle;
newfunc->function = function;
mutex_lock(&acpiphp_context_lock); mutex_lock(&acpiphp_context_lock);
context = acpiphp_init_context(handle); context = acpiphp_init_context(handle);
if (!context) { if (!context) {
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
acpi_handle_err(handle, "No hotplug context\n"); acpi_handle_err(handle, "No hotplug context\n");
kfree(newfunc);
return AE_NOT_EXIST; return AE_NOT_EXIST;
} }
newfunc->context = context; newfunc = &context->func;
context->func = newfunc; newfunc->handle = handle;
newfunc->function = function;
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
if (acpi_has_method(handle, "_EJ0")) if (acpi_has_method(handle, "_EJ0"))
...@@ -404,10 +394,8 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, ...@@ -404,10 +394,8 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
err: err:
mutex_lock(&acpiphp_context_lock); mutex_lock(&acpiphp_context_lock);
context->func = NULL;
acpiphp_put_context(context); acpiphp_put_context(context);
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
kfree(newfunc);
return status; return status;
} }
...@@ -938,7 +926,7 @@ void acpiphp_check_host_bridge(acpi_handle handle) ...@@ -938,7 +926,7 @@ void acpiphp_check_host_bridge(acpi_handle handle)
static void hotplug_event(acpi_handle handle, u32 type, void *data) static void hotplug_event(acpi_handle handle, u32 type, void *data)
{ {
struct acpiphp_context *context = data; struct acpiphp_context *context = data;
struct acpiphp_func *func = context->func; struct acpiphp_func *func = &context->func;
struct acpiphp_bridge *bridge; struct acpiphp_bridge *bridge;
char objname[64]; char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname), struct acpi_buffer buffer = { .length = sizeof(objname),
...@@ -1029,7 +1017,7 @@ static void hotplug_event_work(struct work_struct *work) ...@@ -1029,7 +1017,7 @@ static void hotplug_event_work(struct work_struct *work)
acpi_scan_lock_release(); acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event() */ kfree(hp_work); /* allocated in handle_hotplug_event() */
put_bridge(context->func->slot->bridge); put_bridge(context->func.slot->bridge);
} }
/** /**
...@@ -1047,7 +1035,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) ...@@ -1047,7 +1035,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
mutex_lock(&acpiphp_context_lock); mutex_lock(&acpiphp_context_lock);
context = acpiphp_get_context(handle); context = acpiphp_get_context(handle);
if (context) { if (context) {
get_bridge(context->func->slot->bridge); get_bridge(context->func.slot->bridge);
acpiphp_put_context(context); acpiphp_put_context(context);
} }
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
...@@ -1109,7 +1097,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) ...@@ -1109,7 +1097,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
*/ */
mutex_lock(&acpiphp_context_lock); mutex_lock(&acpiphp_context_lock);
context = acpiphp_get_context(handle); context = acpiphp_get_context(handle);
if (WARN_ON(!context || !context->func)) { if (WARN_ON(!context)) {
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
put_device(&bus->dev); put_device(&bus->dev);
kfree(bridge); kfree(bridge);
...@@ -1118,7 +1106,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) ...@@ -1118,7 +1106,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
bridge->context = context; bridge->context = context;
context->bridge = bridge; context->bridge = bridge;
/* Get a reference to the parent bridge. */ /* Get a reference to the parent bridge. */
get_bridge(context->func->slot->bridge); get_bridge(context->func.slot->bridge);
mutex_unlock(&acpiphp_context_lock); mutex_unlock(&acpiphp_context_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment