ACPI / scan: Make container driver use struct acpi_scan_handler
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 8 Feb 2013 22:52:39 +0000 (23:52 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 13 Feb 2013 12:43:01 +0000 (13:43 +0100)
Make the ACPI container driver use struct acpi_scan_handler for
representing the object used to initialize ACPI containers and remove
the ACPI driver structure used previously and the data structures
created by it, since in fact they were not used for any purpose.

This simplifies the code and reduces the kernel's memory footprint by
avoiding the registration of a struct device_driver object with the
driver core and creation of its sysfs directory which is unnecessary.

In addition to that, make the namespace walk callback used for
installing the notify handlers for ACPI containers more
straightforward.

This change includes fixes from Toshi Kani.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Tested-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
Tested-by: Toshi Kani <toshi.kani@hp.com>
drivers/acpi/Kconfig
drivers/acpi/container.c
drivers/acpi/internal.h
drivers/acpi/scan.c

index 38c5078da11d67ea9db98cf936812982b62f313c..78105b3a52623e9b22be90f71dcaa5b1ae33b725 100644 (file)
@@ -337,7 +337,7 @@ config X86_PM_TIMER
          systems require this timer. 
 
 config ACPI_CONTAINER
-       tristate "Container and Module Devices (EXPERIMENTAL)"
+       bool "Container and Module Devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
        help
index cc0bf4613e0d62d101b745b9e0f30fd9cf603af3..9053e86e99045d19132d9947acc91db261ecdba7 100644 (file)
 
 #define PREFIX "ACPI: "
 
-#define ACPI_CONTAINER_DEVICE_NAME     "ACPI container device"
-#define ACPI_CONTAINER_CLASS           "container"
-
-#define INSTALL_NOTIFY_HANDLER         1
-#define UNINSTALL_NOTIFY_HANDLER       2
-
 #define _COMPONENT                     ACPI_CONTAINER_COMPONENT
 ACPI_MODULE_NAME("container");
 
-MODULE_AUTHOR("Anil S Keshavamurthy");
-MODULE_DESCRIPTION("ACPI container driver");
-MODULE_LICENSE("GPL");
-
-static int acpi_container_add(struct acpi_device *device);
-static int acpi_container_remove(struct acpi_device *device);
-
 static const struct acpi_device_id container_device_ids[] = {
        {"ACPI0004", 0},
        {"PNP0A05", 0},
        {"PNP0A06", 0},
        {"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, container_device_ids);
 
-static struct acpi_driver acpi_container_driver = {
-       .name = "container",
-       .class = ACPI_CONTAINER_CLASS,
+static int container_device_attach(struct acpi_device *device,
+                                  const struct acpi_device_id *not_used)
+{
+       /*
+        * FIXME: This is necessary, so that acpi_eject_store() doesn't return
+        * -ENODEV for containers.
+        */
+       return 1;
+}
+
+static struct acpi_scan_handler container_device_handler = {
        .ids = container_device_ids,
-       .ops = {
-               .add = acpi_container_add,
-               .remove = acpi_container_remove,
-               },
+       .attach = container_device_attach,
 };
 
-/*******************************************************************/
-
 static int is_device_present(acpi_handle handle)
 {
        acpi_handle temp;
@@ -92,49 +81,6 @@ static int is_device_present(acpi_handle handle)
        return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
 }
 
-static bool is_container_device(const char *hid)
-{
-       const struct acpi_device_id *container_id;
-
-       for (container_id = container_device_ids;
-            container_id->id[0]; container_id++) {
-               if (!strcmp((char *)container_id->id, hid))
-                       return true;
-       }
-
-       return false;
-}
-
-/*******************************************************************/
-static int acpi_container_add(struct acpi_device *device)
-{
-       struct acpi_container *container;
-
-       container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
-       if (!container)
-               return -ENOMEM;
-
-       container->handle = device->handle;
-       strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
-       strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
-       device->driver_data = container;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
-                         acpi_device_name(device), acpi_device_bid(device)));
-
-       return 0;
-}
-
-static int acpi_container_remove(struct acpi_device *device)
-{
-       acpi_status status = AE_OK;
-       struct acpi_container *pc = NULL;
-
-       pc = acpi_driver_data(device);
-       kfree(pc);
-       return status;
-}
-
 static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 {
        struct acpi_device *device = NULL;
@@ -199,84 +145,43 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
        return;
 }
 
-static acpi_status
-container_walk_namespace_cb(acpi_handle handle,
-                           u32 lvl, void *context, void **rv)
+static bool is_container(acpi_handle handle)
 {
-       char *hid = NULL;
        struct acpi_device_info *info;
-       acpi_status status;
-       int *action = context;
-
-       status = acpi_get_object_info(handle, &info);
-       if (ACPI_FAILURE(status)) {
-               return AE_OK;
-       }
+       bool ret = false;
 
-       if (info->valid & ACPI_VALID_HID)
-               hid = info->hardware_id.string;
+       if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
+               return false;
 
-       if (hid == NULL) {
-               goto end;
-       }
-
-       if (!is_container_device(hid))
-               goto end;
+       if (info->valid & ACPI_VALID_HID) {
+               const struct acpi_device_id *id;
 
-       switch (*action) {
-       case INSTALL_NOTIFY_HANDLER:
-               acpi_install_notify_handler(handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           container_notify_cb, NULL);
-               break;
-       case UNINSTALL_NOTIFY_HANDLER:
-               acpi_remove_notify_handler(handle,
-                                          ACPI_SYSTEM_NOTIFY,
-                                          container_notify_cb);
-               break;
-       default:
-               break;
+               for (id = container_device_ids; id->id[0]; id++) {
+                       ret = !strcmp((char *)id->id, info->hardware_id.string);
+                       if (ret)
+                               break;
+               }
        }
-
-      end:
        kfree(info);
-
-       return AE_OK;
+       return ret;
 }
 
-static int __init acpi_container_init(void)
+static acpi_status acpi_container_register_notify_handler(acpi_handle handle,
+                                                         u32 lvl, void *ctxt,
+                                                         void **retv)
 {
-       int result = 0;
-       int action = INSTALL_NOTIFY_HANDLER;
-
-       result = acpi_bus_register_driver(&acpi_container_driver);
-       if (result < 0) {
-               return (result);
-       }
-
-       /* register notify handler to every container device */
-       acpi_walk_namespace(ACPI_TYPE_DEVICE,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           container_walk_namespace_cb, NULL, &action, NULL);
+       if (is_container(handle))
+               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                                           container_notify_cb, NULL);
 
-       return (0);
+       return AE_OK;
 }
 
-static void __exit acpi_container_exit(void)
+void __init acpi_container_init(void)
 {
-       int action = UNINSTALL_NOTIFY_HANDLER;
-
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           container_walk_namespace_cb, NULL, &action, NULL);
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+                           acpi_container_register_notify_handler, NULL,
+                           NULL, NULL);
 
-       acpi_bus_unregister_driver(&acpi_container_driver);
-
-       return;
+       acpi_scan_add_handler(&container_device_handler);
 }
-
-module_init(acpi_container_init);
-module_exit(acpi_container_exit);
index 0d1397dc7003d4084e6a0c3692f5d2aad8dc4f56..79092328cf064b237c090690c29b64ec1a733063 100644 (file)
@@ -30,6 +30,11 @@ void acpi_pci_link_init(void);
 void acpi_platform_init(void);
 int acpi_sysfs_init(void);
 void acpi_csrt_init(void);
+#ifdef CONFIG_ACPI_CONTAINER
+void acpi_container_init(void);
+#else
+static inline void acpi_container_init(void) {}
+#endif
 
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *acpi_debugfs_dir;
index 5bc2641fba8aebe06b43c56de3f7b1c68fc38a79..a48b6e92f9f815afb87f29ca4dfbc94f5f24a9bc 100644 (file)
@@ -1758,6 +1758,7 @@ int __init acpi_scan_init(void)
        acpi_pci_link_init();
        acpi_platform_init();
        acpi_csrt_init();
+       acpi_container_init();
 
        /*
         * Enumerate devices in the ACPI namespace.