aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIke Panhc <ike.pan@canonical.com>2010-12-13 05:00:15 -0500
committerMatthew Garrett <mjg@redhat.com>2011-01-07 17:03:45 -0500
commit98ee69191d3af68e2292528cbb16dcba3d8e2b81 (patch)
treed363de22466fd93f486323c4507aeef6a01db2c6 /drivers
parent9c23225006b695ceba31c035b287f5a7a0b0304e (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')
-rw-r--r--drivers/platform/x86/ideapad-laptop.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 5ff12205aa6b..5998ae14a220 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -27,6 +27,7 @@
27#include <acpi/acpi_bus.h> 27#include <acpi/acpi_bus.h>
28#include <acpi/acpi_drivers.h> 28#include <acpi/acpi_drivers.h>
29#include <linux/rfkill.h> 29#include <linux/rfkill.h>
30#include <linux/platform_device.h>
30 31
31#define IDEAPAD_DEV_CAMERA 0 32#define IDEAPAD_DEV_CAMERA 0
32#define IDEAPAD_DEV_WLAN 1 33#define IDEAPAD_DEV_WLAN 1
@@ -37,6 +38,7 @@
37struct ideapad_private { 38struct ideapad_private {
38 acpi_handle handle; 39 acpi_handle handle;
39 struct rfkill *rfk[5]; 40 struct rfkill *rfk[5];
41 struct platform_device *platform_device;
40} *ideapad_priv; 42} *ideapad_priv;
41 43
42static struct { 44static struct {
@@ -277,6 +279,35 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
277 rfkill_destroy(priv->rfk[dev]); 279 rfkill_destroy(priv->rfk[dev]);
278} 280}
279 281
282/*
283 * Platform device
284 */
285static int __devinit ideapad_platform_init(void)
286{
287 int result;
288
289 ideapad_priv->platform_device = platform_device_alloc("ideapad", -1);
290 if (!ideapad_priv->platform_device)
291 return -ENOMEM;
292 platform_set_drvdata(ideapad_priv->platform_device, ideapad_priv);
293
294 result = platform_device_add(ideapad_priv->platform_device);
295 if (result)
296 goto fail_platform_device;
297
298 return 0;
299
300fail_platform_device:
301 platform_device_put(ideapad_priv->platform_device);
302 return result;
303}
304
305static void ideapad_platform_exit(void)
306{
307 platform_device_unregister(ideapad_priv->platform_device);
308}
309/* the above is platform device */
310
280static const struct acpi_device_id ideapad_device_ids[] = { 311static const struct acpi_device_id ideapad_device_ids[] = {
281 { "VPC2004", 0}, 312 { "VPC2004", 0},
282 { "", 0}, 313 { "", 0},
@@ -285,7 +316,7 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
285 316
286static int ideapad_acpi_add(struct acpi_device *adevice) 317static int ideapad_acpi_add(struct acpi_device *adevice)
287{ 318{
288 int i, cfg; 319 int ret, i, cfg;
289 int devs_present[5]; 320 int devs_present[5];
290 struct ideapad_private *priv; 321 struct ideapad_private *priv;
291 322
@@ -305,18 +336,20 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
305 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 336 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
306 if (!priv) 337 if (!priv)
307 return -ENOMEM; 338 return -ENOMEM;
339 ideapad_priv = priv;
340
341 ret = ideapad_platform_init();
342 if (ret)
343 goto platform_failed;
308 344
309 if (devs_present[IDEAPAD_DEV_CAMERA]) { 345 if (devs_present[IDEAPAD_DEV_CAMERA]) {
310 int ret = device_create_file(&adevice->dev, &dev_attr_camera_power); 346 ret = device_create_file(&adevice->dev, &dev_attr_camera_power);
311 if (ret) { 347 if (ret)
312 kfree(priv); 348 goto camera_failed;
313 return ret;
314 }
315 } 349 }
316 350
317 priv->handle = adevice->handle; 351 priv->handle = adevice->handle;
318 dev_set_drvdata(&adevice->dev, priv); 352 dev_set_drvdata(&adevice->dev, priv);
319 ideapad_priv = priv;
320 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) { 353 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
321 if (!devs_present[i]) 354 if (!devs_present[i])
322 continue; 355 continue;
@@ -325,6 +358,12 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
325 } 358 }
326 ideapad_sync_rfk_state(adevice); 359 ideapad_sync_rfk_state(adevice);
327 return 0; 360 return 0;
361
362camera_failed:
363 ideapad_platform_exit();
364platform_failed:
365 kfree(priv);
366 return ret;
328} 367}
329 368
330static int ideapad_acpi_remove(struct acpi_device *adevice, int type) 369static 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)
337 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) 376 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++)
338 ideapad_unregister_rfkill(adevice, i); 377 ideapad_unregister_rfkill(adevice, i);
339 378
379 ideapad_platform_exit();
340 dev_set_drvdata(&adevice->dev, NULL); 380 dev_set_drvdata(&adevice->dev, NULL);
341 kfree(priv); 381 kfree(priv);
342 return 0; 382 return 0;