diff options
author | Ike Panhc <ike.pan@canonical.com> | 2010-12-13 18:00:15 +0800 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2011-01-07 17:03:45 -0500 |
commit | 98ee69191d3af68e2292528cbb16dcba3d8e2b81 (patch) | |
tree | d363de22466fd93f486323c4507aeef6a01db2c6 /drivers/platform/x86 | |
parent | 9c23225006b695ceba31c035b287f5a7a0b0304e (diff) |
ideapad: add platform driver for ideapad
Create /sys/devices/platform/ideapad for nodes of ideapad landing.
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r-- | drivers/platform/x86/ideapad-laptop.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 5ff12205aa6..5998ae14a22 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -27,6 +27,7 @@ #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> #include <linux/rfkill.h> +#include <linux/platform_device.h> #define IDEAPAD_DEV_CAMERA 0 #define IDEAPAD_DEV_WLAN 1 @@ -37,6 +38,7 @@ struct ideapad_private { acpi_handle handle; struct rfkill *rfk[5]; + struct platform_device *platform_device; } *ideapad_priv; static struct { @@ -277,6 +279,35 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) rfkill_destroy(priv->rfk[dev]); } +/* + * Platform device + */ +static int __devinit ideapad_platform_init(void) +{ + int result; + + ideapad_priv->platform_device = platform_device_alloc("ideapad", -1); + if (!ideapad_priv->platform_device) + return -ENOMEM; + platform_set_drvdata(ideapad_priv->platform_device, ideapad_priv); + + result = platform_device_add(ideapad_priv->platform_device); + if (result) + goto fail_platform_device; + + return 0; + +fail_platform_device: + platform_device_put(ideapad_priv->platform_device); + return result; +} + +static void ideapad_platform_exit(void) +{ + platform_device_unregister(ideapad_priv->platform_device); +} +/* the above is platform device */ + static const struct acpi_device_id ideapad_device_ids[] = { { "VPC2004", 0}, { "", 0}, @@ -285,7 +316,7 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); static int ideapad_acpi_add(struct acpi_device *adevice) { - int i, cfg; + int ret, i, cfg; int devs_present[5]; struct ideapad_private *priv; @@ -305,18 +336,20 @@ static int ideapad_acpi_add(struct acpi_device *adevice) priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + ideapad_priv = priv; + + ret = ideapad_platform_init(); + if (ret) + goto platform_failed; if (devs_present[IDEAPAD_DEV_CAMERA]) { - int ret = device_create_file(&adevice->dev, &dev_attr_camera_power); - if (ret) { - kfree(priv); - return ret; - } + ret = device_create_file(&adevice->dev, &dev_attr_camera_power); + if (ret) + goto camera_failed; } priv->handle = adevice->handle; dev_set_drvdata(&adevice->dev, priv); - ideapad_priv = priv; for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) { if (!devs_present[i]) continue; @@ -325,6 +358,12 @@ static int ideapad_acpi_add(struct acpi_device *adevice) } ideapad_sync_rfk_state(adevice); return 0; + +camera_failed: + ideapad_platform_exit(); +platform_failed: + kfree(priv); + return ret; } static int ideapad_acpi_remove(struct acpi_device *adevice, int type) @@ -337,6 +376,7 @@ static int ideapad_acpi_remove(struct acpi_device *adevice, int type) for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) ideapad_unregister_rfkill(adevice, i); + ideapad_platform_exit(); dev_set_drvdata(&adevice->dev, NULL); kfree(priv); return 0; |