ACPI / hotplug / PCI: Embed function struct into struct acpiphp_context
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 13 Jul 2013 21:27:25 +0000 (23:27 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 23 Jul 2013 02:00:23 +0000 (04:00 +0200)
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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_glue.c

index 990fbfd110f1565ce407905fe8b21ddbebe0080b..31c84bdd2bef51c1c09e15b5fedb1bb59c1e339f 100644 (file)
@@ -116,7 +116,6 @@ struct acpiphp_slot {
  * typically 8 objects per slot (i.e. for each PCI function)
  */
 struct acpiphp_func {
-       struct acpiphp_context *context;
        struct acpiphp_slot *slot;      /* parent */
 
        struct list_head sibling;
@@ -128,11 +127,16 @@ struct acpiphp_func {
 
 struct acpiphp_context {
        acpi_handle handle;
-       struct acpiphp_func *func;
+       struct acpiphp_func func;
        struct acpiphp_bridge *bridge;
        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
  *
index 5d79175b9a09dd2b5e544c403d2473b5564b0de7..cc7453e0722e56d305433ccb5b5964b0958ec928 100644 (file)
@@ -128,7 +128,7 @@ static void acpiphp_put_context(struct acpiphp_context *context)
        if (--context->refcount)
                return;
 
-       WARN_ON(context->func || context->bridge);
+       WARN_ON(context->bridge);
        acpi_detach_data(context->handle, acpiphp_context_handler);
        kfree(context);
 }
@@ -155,12 +155,9 @@ static void free_bridge(struct kref *kref)
        bridge = container_of(kref, struct acpiphp_bridge, ref);
 
        list_for_each_entry_safe(slot, next, &bridge->slots, node) {
-               list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
-                       context = func->context;
-                       context->func = NULL;
-                       acpiphp_put_context(context);
-                       kfree(func);
-               }
+               list_for_each_entry_safe(func, tmp, &slot->funcs, sibling)
+                       acpiphp_put_context(func_to_context(func));
+
                kfree(slot);
        }
 
@@ -168,7 +165,7 @@ static void free_bridge(struct kref *kref)
        /* Root bridges will not have hotplug context. */
        if (context) {
                /* Release the reference taken by acpiphp_enumerate_slots(). */
-               put_bridge(context->func->slot->bridge);
+               put_bridge(context->func.slot->bridge);
                context->bridge = NULL;
                acpiphp_put_context(context);
        }
@@ -190,7 +187,7 @@ static void free_bridge(struct kref *kref)
 static void post_dock_fixups(acpi_handle not_used, u32 event, void *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;
 
        if (!bus->self)
@@ -251,14 +248,14 @@ static void acpiphp_dock_init(void *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)
 {
        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 */
@@ -288,23 +285,16 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
        device = (adr >> 16) & 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);
        context = acpiphp_init_context(handle);
        if (!context) {
                mutex_unlock(&acpiphp_context_lock);
                acpi_handle_err(handle, "No hotplug context\n");
-               kfree(newfunc);
                return AE_NOT_EXIST;
        }
-       newfunc->context = context;
-       context->func = newfunc;
+       newfunc = &context->func;
+       newfunc->handle = handle;
+       newfunc->function = function;
        mutex_unlock(&acpiphp_context_lock);
 
        if (acpi_has_method(handle, "_EJ0"))
@@ -404,10 +394,8 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
 
  err:
        mutex_lock(&acpiphp_context_lock);
-       context->func = NULL;
        acpiphp_put_context(context);
        mutex_unlock(&acpiphp_context_lock);
-       kfree(newfunc);
        return status;
 }
 
@@ -938,7 +926,7 @@ void acpiphp_check_host_bridge(acpi_handle handle)
 static void hotplug_event(acpi_handle handle, u32 type, void *data)
 {
        struct acpiphp_context *context = data;
-       struct acpiphp_func *func = context->func;
+       struct acpiphp_func *func = &context->func;
        struct acpiphp_bridge *bridge;
        char objname[64];
        struct acpi_buffer buffer = { .length = sizeof(objname),
@@ -1029,7 +1017,7 @@ static void hotplug_event_work(struct work_struct *work)
 
        acpi_scan_lock_release();
        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)
        mutex_lock(&acpiphp_context_lock);
        context = acpiphp_get_context(handle);
        if (context) {
-               get_bridge(context->func->slot->bridge);
+               get_bridge(context->func.slot->bridge);
                acpiphp_put_context(context);
        }
        mutex_unlock(&acpiphp_context_lock);
@@ -1109,7 +1097,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
                 */
                mutex_lock(&acpiphp_context_lock);
                context = acpiphp_get_context(handle);
-               if (WARN_ON(!context || !context->func)) {
+               if (WARN_ON(!context)) {
                        mutex_unlock(&acpiphp_context_lock);
                        put_device(&bus->dev);
                        kfree(bridge);
@@ -1118,7 +1106,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
                bridge->context = context;
                context->bridge = 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);
        }