asus-laptop: change initialization order
authorCorentin Chary <corentincj@iksaif.net>
Mon, 30 Nov 2009 20:42:42 +0000 (21:42 +0100)
committerCorentin Chary <corentincj@iksaif.net>
Sun, 28 Feb 2010 18:35:10 +0000 (19:35 +0100)
Clean asus-laptop initialization to match new eeepc-laptop code.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
drivers/platform/x86/asus-laptop.c

index 74463a0..8834405 100644 (file)
@@ -201,6 +201,8 @@ ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB");
  */
 struct asus_hotk {
        char *name;             /* laptop name */
+
+       struct platform_device *platform_device;
        struct acpi_device *device;     /* the device we are in */
        acpi_handle handle;     /* the handle of the hotk device */
        char status;            /* status of the hotk, for LEDs, ... */
@@ -222,33 +224,6 @@ static struct acpi_table_header *asus_info;
 /* The actual device the driver binds to */
 static struct asus_hotk *hotk;
 
-/*
- * The hotkey driver declaration
- */
-static const struct acpi_device_id asus_device_ids[] = {
-       {"ATK0100", 0},
-       {"ATK0101", 0},
-       {"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, asus_device_ids);
-
-static int asus_hotk_add(struct acpi_device *device);
-static int asus_hotk_remove(struct acpi_device *device, int type);
-static void asus_hotk_notify(struct acpi_device *device, u32 event);
-
-static struct acpi_driver asus_hotk_driver = {
-       .name = ASUS_HOTK_NAME,
-       .class = ASUS_HOTK_CLASS,
-       .owner = THIS_MODULE,
-       .ids = asus_device_ids,
-       .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
-       .ops = {
-               .add = asus_hotk_add,
-               .remove = asus_hotk_remove,
-               .notify = asus_hotk_notify,
-               },
-};
-
 /* The backlight device /sys/class/backlight */
 static struct backlight_device *asus_backlight_device;
 
@@ -936,7 +911,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
        return -EINVAL;
 }
 
-static void asus_hotk_notify(struct acpi_device *device, u32 event)
+static void asus_acpi_notify(struct acpi_device *device, u32 event)
 {
        static struct key_entry *key;
        u16 count;
@@ -1013,19 +988,49 @@ static struct attribute *asuspf_attributes[] = {
        NULL
 };
 
-static struct attribute_group asuspf_attribute_group = {
+static struct attribute_group platform_attribute_group = {
        .attrs = asuspf_attributes
 };
 
-static struct platform_driver asuspf_driver = {
+static int asus_platform_init(void)
+{
+       int result;
+
+       hotk->platform_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
+       if (!hotk->platform_device)
+               return -ENOMEM;
+
+       result = platform_device_add(hotk->platform_device);
+       if (result)
+               goto fail_platform_device;
+
+       result = sysfs_create_group(&hotk->platform_device->dev.kobj,
+                                   &platform_attribute_group);
+       if (result)
+               goto fail_sysfs;
+       return 0;
+
+fail_sysfs:
+       platform_device_del(hotk->platform_device);
+fail_platform_device:
+       platform_device_put(hotk->platform_device);
+       return result;
+}
+
+static void asus_platform_exit(void)
+{
+       sysfs_remove_group(&hotk->platform_device->dev.kobj,
+                          &platform_attribute_group);
+       platform_device_unregister(hotk->platform_device);
+}
+
+static struct platform_driver platform_driver = {
        .driver = {
                   .name = ASUS_HOTK_FILE,
                   .owner = THIS_MODULE,
                   }
 };
 
-static struct platform_device *asuspf_device;
-
 static void asus_hotk_add_fs(void)
 {
        ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL);
@@ -1196,7 +1201,7 @@ static int asus_hotk_get_info(void)
        return AE_OK;
 }
 
-static int asus_input_init(void)
+static int asus_input_init(struct device *dev)
 {
        const struct key_entry *key;
        int result;
@@ -1207,6 +1212,7 @@ static int asus_input_init(void)
                return 0;
        }
        hotk->inputdev->name = "Asus Laptop extra buttons";
+       hotk->inputdev->dev.parent = dev;
        hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
        hotk->inputdev->id.bustype = BUS_HOST;
        hotk->inputdev->getkeycode = asus_getkeycode;
@@ -1228,101 +1234,6 @@ static int asus_input_init(void)
        return result;
 }
 
-static int asus_hotk_check(void)
-{
-       int result = 0;
-
-       result = acpi_bus_get_status(hotk->device);
-       if (result)
-               return result;
-
-       if (hotk->device->status.present) {
-               result = asus_hotk_get_info();
-       } else {
-               pr_err("Hotkey device not present, aborting\n");
-               return -EINVAL;
-       }
-
-       return result;
-}
-
-static int asus_hotk_found;
-
-static int asus_hotk_add(struct acpi_device *device)
-{
-       int result;
-
-       pr_notice("Asus Laptop Support version %s\n",
-              ASUS_LAPTOP_VERSION);
-
-       hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
-       if (!hotk)
-               return -ENOMEM;
-
-       hotk->handle = device->handle;
-       strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
-       strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
-       device->driver_data = hotk;
-       hotk->device = device;
-
-       result = asus_hotk_check();
-       if (result)
-               goto end;
-
-       asus_hotk_add_fs();
-
-       asus_hotk_found = 1;
-
-       /* WLED and BLED are on by default */
-       if (bluetooth_status != -1)
-               write_status(bt_switch_handle, !!bluetooth_status, BT_ON);
-       if (wireless_status != -1)
-               write_status(wl_switch_handle, !!wireless_status, WL_ON);
-
-       /* If the h/w switch is off, we need to check the real status */
-       write_status(NULL, read_status(BT_ON), BT_ON);
-       write_status(NULL, read_status(WL_ON), WL_ON);
-
-       /* LCD Backlight is on by default */
-       write_status(NULL, 1, LCD_ON);
-
-       /* Keyboard Backlight is on by default */
-       if (kled_set_handle)
-               set_kled_lvl(1);
-
-       /* LED display is off by default */
-       hotk->ledd_status = 0xFFF;
-
-       /* Set initial values of light sensor and level */
-       hotk->light_switch = 0; /* Default to light sensor disabled */
-       hotk->light_level = 5;  /* level 5 for sensor sensitivity */
-
-       if (ls_switch_handle)
-               set_light_sens_switch(hotk->light_switch);
-
-       if (ls_level_handle)
-               set_light_sens_level(hotk->light_level);
-
-       /* GPS is on by default */
-       write_status(NULL, 1, GPS_ON);
-
-end:
-       if (result) {
-               kfree(hotk->name);
-               kfree(hotk);
-       }
-
-       return result;
-}
-
-static int asus_hotk_remove(struct acpi_device *device, int type)
-{
-       kfree(hotk->name);
-       kfree(hotk);
-
-       return 0;
-}
-
 static void asus_backlight_exit(void)
 {
        if (asus_backlight_device)
@@ -1350,18 +1261,6 @@ static void asus_input_exit(void)
                input_unregister_device(hotk->inputdev);
 }
 
-static void __exit asus_laptop_exit(void)
-{
-       asus_backlight_exit();
-       asus_led_exit();
-       asus_input_exit();
-
-       acpi_bus_unregister_driver(&asus_hotk_driver);
-       sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
-       platform_device_unregister(asuspf_device);
-       platform_driver_unregister(&asuspf_driver);
-}
-
 static int asus_backlight_init(struct device *dev)
 {
        struct backlight_device *bd;
@@ -1448,87 +1347,179 @@ out:
        return rv;
 }
 
-static int __init asus_laptop_init(void)
+
+static bool asus_device_present;
+
+static int __devinit asus_acpi_init(struct acpi_device *device)
 {
-       int result;
+       int result = 0;
 
-       result = acpi_bus_register_driver(&asus_hotk_driver);
-       if (result < 0)
+       result = acpi_bus_get_status(hotk->device);
+       if (result)
                return result;
-
-       /*
-        * This is a bit of a kludge.  We only want this module loaded
-        * for ASUS systems, but there's currently no way to probe the
-        * ACPI namespace for ASUS HIDs.  So we just return failure if
-        * we didn't find one, which will cause the module to be
-        * unloaded.
-        */
-       if (!asus_hotk_found) {
-               acpi_bus_unregister_driver(&asus_hotk_driver);
+       if (!hotk->device->status.present) {
+               pr_err("Hotkey device not present, aborting\n");
                return -ENODEV;
        }
 
-       result = asus_input_init();
+       result = asus_hotk_get_info();
        if (result)
-               goto fail_input;
+               return result;
 
-       /* Register platform stuff */
-       result = platform_driver_register(&asuspf_driver);
-       if (result)
-               goto fail_platform_driver;
+       asus_hotk_add_fs();
 
-       asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
-       if (!asuspf_device) {
-               result = -ENOMEM;
-               goto fail_platform_device1;
-       }
+       /* WLED and BLED are on by default */
+       write_status(bt_switch_handle, 1, BT_ON);
+       write_status(wl_switch_handle, 1, WL_ON);
 
-       result = platform_device_add(asuspf_device);
-       if (result)
-               goto fail_platform_device2;
+       /* If the h/w switch is off, we need to check the real status */
+       write_status(NULL, read_status(BT_ON), BT_ON);
+       write_status(NULL, read_status(WL_ON), WL_ON);
+
+       /* LCD Backlight is on by default */
+       write_status(NULL, 1, LCD_ON);
 
-       result = sysfs_create_group(&asuspf_device->dev.kobj,
-                                   &asuspf_attribute_group);
+       /* Keyboard Backlight is on by default */
+       if (kled_set_handle)
+               set_kled_lvl(1);
+
+       /* LED display is off by default */
+       hotk->ledd_status = 0xFFF;
+
+       /* Set initial values of light sensor and level */
+       hotk->light_switch = 0; /* Default to light sensor disabled */
+       hotk->light_level = 5;  /* level 5 for sensor sensitivity */
+
+       if (ls_switch_handle)
+               set_light_sens_switch(hotk->light_switch);
+
+       if (ls_level_handle)
+               set_light_sens_level(hotk->light_level);
+
+       /* GPS is on by default */
+       write_status(NULL, 1, GPS_ON);
+       return result;
+}
+
+static int __devinit asus_acpi_add(struct acpi_device *device)
+{
+       int result;
+
+       pr_notice("Asus Laptop Support version %s\n",
+                 ASUS_LAPTOP_VERSION);
+       hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+       if (!hotk)
+               return -ENOMEM;
+       hotk->handle = device->handle;
+       strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
+       strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
+       device->driver_data = hotk;
+       hotk->device = device;
+
+       result = asus_acpi_init(device);
        if (result)
-               goto fail_sysfs;
+               goto fail_platform;
 
-       result = asus_led_init(&asuspf_device->dev);
+       /*
+        * Register the platform device first.  It is used as a parent for the
+        * sub-devices below.
+        */
+       result = asus_platform_init();
        if (result)
-               goto fail_led;
+               goto fail_platform;
 
        if (!acpi_video_backlight_support()) {
-               result = asus_backlight_init(&asuspf_device->dev);
+               result = asus_backlight_init(&hotk->platform_device->dev);
                if (result)
                        goto fail_backlight;
        } else
-               pr_info("Brightness ignored, must be controlled by "
-                      "ACPI video driver\n");
+               pr_info("Backlight controlled by ACPI video driver\n");
 
+       result = asus_input_init(&hotk->platform_device->dev);
+       if (result)
+               goto fail_input;
+
+       result = asus_led_init(&hotk->platform_device->dev);
+       if (result)
+               goto fail_led;
+
+       asus_device_present = true;
        return 0;
 
+fail_led:
+       asus_input_exit();
+fail_input:
+       asus_backlight_exit();
 fail_backlight:
-       asus_led_exit();
+       asus_platform_exit();
+fail_platform:
+       kfree(hotk->name);
+       kfree(hotk);
 
-fail_led:
-       sysfs_remove_group(&asuspf_device->dev.kobj,
-                         &asuspf_attribute_group);
+       return result;
+}
 
-fail_sysfs:
-       platform_device_del(asuspf_device);
+static int asus_acpi_remove(struct acpi_device *device, int type)
+{
+       asus_backlight_exit();
+       asus_led_exit();
+       asus_input_exit();
+       asus_platform_exit();
+
+       kfree(hotk->name);
+       kfree(hotk);
+       return 0;
+}
+
+static const struct acpi_device_id asus_device_ids[] = {
+       {"ATK0100", 0},
+       {"ATK0101", 0},
+       {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, asus_device_ids);
 
-fail_platform_device2:
-       platform_device_put(asuspf_device);
+static struct acpi_driver asus_acpi_driver = {
+       .name = ASUS_HOTK_NAME,
+       .class = ASUS_HOTK_CLASS,
+       .owner = THIS_MODULE,
+       .ids = asus_device_ids,
+       .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
+       .ops = {
+               .add = asus_acpi_add,
+               .remove = asus_acpi_remove,
+               .notify = asus_acpi_notify,
+               },
+};
 
-fail_platform_device1:
-       platform_driver_unregister(&asuspf_driver);
+static int __init asus_laptop_init(void)
+{
+       int result;
 
-fail_platform_driver:
-       asus_input_exit();
+       result = platform_driver_register(&platform_driver);
+       if (result < 0)
+               return result;
 
-fail_input:
+       result = acpi_bus_register_driver(&asus_acpi_driver);
+       if (result < 0)
+               goto fail_acpi_driver;
+       if (!asus_device_present) {
+               result = -ENODEV;
+               goto fail_no_device;
+       }
+       return 0;
 
+fail_no_device:
+       acpi_bus_unregister_driver(&asus_acpi_driver);
+fail_acpi_driver:
+       platform_driver_unregister(&platform_driver);
        return result;
 }
 
+static void __exit asus_laptop_exit(void)
+{
+       acpi_bus_unregister_driver(&asus_acpi_driver);
+       platform_driver_unregister(&platform_driver);
+}
+
 module_init(asus_laptop_init);
 module_exit(asus_laptop_exit);