Staging: hv: fix smp problems in the hyperv core code
[sfrench/cifs-2.6.git] / drivers / platform / x86 / eeepc-laptop.c
1 /*
2  *  eeepc-laptop.c - Asus Eee PC extras
3  *
4  *  Based on asus_acpi.c as patched for the Eee PC by Asus:
5  *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
6  *  Based on eee.c from eeepc-linux
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  */
18
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/types.h>
25 #include <linux/platform_device.h>
26 #include <linux/backlight.h>
27 #include <linux/fb.h>
28 #include <linux/hwmon.h>
29 #include <linux/hwmon-sysfs.h>
30 #include <acpi/acpi_drivers.h>
31 #include <acpi/acpi_bus.h>
32 #include <linux/uaccess.h>
33 #include <linux/input.h>
34 #include <linux/rfkill.h>
35 #include <linux/pci.h>
36 #include <linux/pci_hotplug.h>
37 #include <linux/leds.h>
38
39 #define EEEPC_LAPTOP_VERSION    "0.1"
40 #define EEEPC_LAPTOP_NAME       "Eee PC Hotkey Driver"
41 #define EEEPC_LAPTOP_FILE       "eeepc"
42
43 #define EEEPC_ACPI_CLASS        "hotkey"
44 #define EEEPC_ACPI_DEVICE_NAME  "Hotkey"
45 #define EEEPC_ACPI_HID          "ASUS010"
46
47 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
48 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
49 MODULE_LICENSE("GPL");
50
51 /*
52  * Definitions for Asus EeePC
53  */
54 #define NOTIFY_BRN_MIN  0x20
55 #define NOTIFY_BRN_MAX  0x2f
56
57 enum {
58         DISABLE_ASL_WLAN = 0x0001,
59         DISABLE_ASL_BLUETOOTH = 0x0002,
60         DISABLE_ASL_IRDA = 0x0004,
61         DISABLE_ASL_CAMERA = 0x0008,
62         DISABLE_ASL_TV = 0x0010,
63         DISABLE_ASL_GPS = 0x0020,
64         DISABLE_ASL_DISPLAYSWITCH = 0x0040,
65         DISABLE_ASL_MODEM = 0x0080,
66         DISABLE_ASL_CARDREADER = 0x0100,
67         DISABLE_ASL_3G = 0x0200,
68         DISABLE_ASL_WIMAX = 0x0400,
69         DISABLE_ASL_HWCF = 0x0800
70 };
71
72 enum {
73         CM_ASL_WLAN = 0,
74         CM_ASL_BLUETOOTH,
75         CM_ASL_IRDA,
76         CM_ASL_1394,
77         CM_ASL_CAMERA,
78         CM_ASL_TV,
79         CM_ASL_GPS,
80         CM_ASL_DVDROM,
81         CM_ASL_DISPLAYSWITCH,
82         CM_ASL_PANELBRIGHT,
83         CM_ASL_BIOSFLASH,
84         CM_ASL_ACPIFLASH,
85         CM_ASL_CPUFV,
86         CM_ASL_CPUTEMPERATURE,
87         CM_ASL_FANCPU,
88         CM_ASL_FANCHASSIS,
89         CM_ASL_USBPORT1,
90         CM_ASL_USBPORT2,
91         CM_ASL_USBPORT3,
92         CM_ASL_MODEM,
93         CM_ASL_CARDREADER,
94         CM_ASL_3G,
95         CM_ASL_WIMAX,
96         CM_ASL_HWCF,
97         CM_ASL_LID,
98         CM_ASL_TYPE,
99         CM_ASL_PANELPOWER,      /*P901*/
100         CM_ASL_TPD
101 };
102
103 static const char *cm_getv[] = {
104         "WLDG", "BTHG", NULL, NULL,
105         "CAMG", NULL, NULL, NULL,
106         NULL, "PBLG", NULL, NULL,
107         "CFVG", NULL, NULL, NULL,
108         "USBG", NULL, NULL, "MODG",
109         "CRDG", "M3GG", "WIMG", "HWCF",
110         "LIDG", "TYPE", "PBPG", "TPDG"
111 };
112
113 static const char *cm_setv[] = {
114         "WLDS", "BTHS", NULL, NULL,
115         "CAMS", NULL, NULL, NULL,
116         "SDSP", "PBLS", "HDPS", NULL,
117         "CFVS", NULL, NULL, NULL,
118         "USBG", NULL, NULL, "MODS",
119         "CRDS", "M3GS", "WIMS", NULL,
120         NULL, NULL, "PBPS", "TPDS"
121 };
122
123 struct key_entry {
124         char type;
125         u8 code;
126         u16 keycode;
127 };
128
129 enum { KE_KEY, KE_END };
130
131 static const struct key_entry eeepc_keymap[] = {
132         /* Sleep already handled via generic ACPI code */
133         {KE_KEY, 0x10, KEY_WLAN },
134         {KE_KEY, 0x11, KEY_WLAN },
135         {KE_KEY, 0x12, KEY_PROG1 },
136         {KE_KEY, 0x13, KEY_MUTE },
137         {KE_KEY, 0x14, KEY_VOLUMEDOWN },
138         {KE_KEY, 0x15, KEY_VOLUMEUP },
139         {KE_KEY, 0x16, KEY_DISPLAY_OFF },
140         {KE_KEY, 0x1a, KEY_COFFEE },
141         {KE_KEY, 0x1b, KEY_ZOOM },
142         {KE_KEY, 0x1c, KEY_PROG2 },
143         {KE_KEY, 0x1d, KEY_PROG3 },
144         {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
145         {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP },
146         {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
147         {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
148         {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
149         {KE_KEY, 0x37, KEY_F13 }, /* Disable Touchpad */
150         {KE_KEY, 0x38, KEY_F14 },
151         {KE_END, 0},
152 };
153
154
155 /*
156  * This is the main structure, we can use it to store useful information
157  */
158 struct eeepc_laptop {
159         acpi_handle handle;             /* the handle of the acpi device */
160         u32 cm_supported;               /* the control methods supported
161                                            by this BIOS */
162         u16 event_count[128];           /* count for each event */
163
164         struct platform_device *platform_device;
165         struct device *hwmon_device;
166         struct backlight_device *backlight_device;
167
168         struct input_dev *inputdev;
169         struct key_entry *keymap;
170
171         struct rfkill *wlan_rfkill;
172         struct rfkill *bluetooth_rfkill;
173         struct rfkill *wwan3g_rfkill;
174         struct rfkill *wimax_rfkill;
175
176         struct hotplug_slot *hotplug_slot;
177         struct mutex hotplug_lock;
178
179         struct led_classdev tpd_led;
180         int tpd_led_wk;
181         struct workqueue_struct *led_workqueue;
182         struct work_struct tpd_led_work;
183 };
184
185 /*
186  * ACPI Helpers
187  */
188 static int write_acpi_int(acpi_handle handle, const char *method, int val)
189 {
190         struct acpi_object_list params;
191         union acpi_object in_obj;
192         acpi_status status;
193
194         params.count = 1;
195         params.pointer = &in_obj;
196         in_obj.type = ACPI_TYPE_INTEGER;
197         in_obj.integer.value = val;
198
199         status = acpi_evaluate_object(handle, (char *)method, &params, NULL);
200         return (status == AE_OK ? 0 : -1);
201 }
202
203 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
204 {
205         acpi_status status;
206         unsigned long long result;
207
208         status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
209         if (ACPI_FAILURE(status)) {
210                 *val = -1;
211                 return -1;
212         } else {
213                 *val = result;
214                 return 0;
215         }
216 }
217
218 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
219 {
220         const char *method = cm_setv[cm];
221
222         if (method == NULL)
223                 return -ENODEV;
224         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
225                 return -ENODEV;
226
227         if (write_acpi_int(eeepc->handle, method, value))
228                 pr_warning("Error writing %s\n", method);
229         return 0;
230 }
231
232 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
233 {
234         const char *method = cm_getv[cm];
235         int value;
236
237         if (method == NULL)
238                 return -ENODEV;
239         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
240                 return -ENODEV;
241
242         if (read_acpi_int(eeepc->handle, method, &value))
243                 pr_warning("Error reading %s\n", method);
244         return value;
245 }
246
247 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
248                               acpi_handle *handle)
249 {
250         const char *method = cm_setv[cm];
251         acpi_status status;
252
253         if (method == NULL)
254                 return -ENODEV;
255         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
256                 return -ENODEV;
257
258         status = acpi_get_handle(eeepc->handle, (char *)method,
259                                  handle);
260         if (status != AE_OK) {
261                 pr_warning("Error finding %s\n", method);
262                 return -ENODEV;
263         }
264         return 0;
265 }
266
267
268 /*
269  * Sys helpers
270  */
271 static int parse_arg(const char *buf, unsigned long count, int *val)
272 {
273         if (!count)
274                 return 0;
275         if (sscanf(buf, "%i", val) != 1)
276                 return -EINVAL;
277         return count;
278 }
279
280 static ssize_t store_sys_acpi(struct device *dev, int cm,
281                               const char *buf, size_t count)
282 {
283         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
284         int rv, value;
285
286         rv = parse_arg(buf, count, &value);
287         if (rv > 0)
288                 value = set_acpi(eeepc, cm, value);
289         if (value < 0)
290                 return -EIO;
291         return rv;
292 }
293
294 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
295 {
296         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
297         int value = get_acpi(eeepc, cm);
298
299         if (value < 0)
300                 return -EIO;
301         return sprintf(buf, "%d\n", value);
302 }
303
304 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm)                     \
305         static ssize_t show_##_name(struct device *dev,                 \
306                                     struct device_attribute *attr,      \
307                                     char *buf)                          \
308         {                                                               \
309                 return show_sys_acpi(dev, _cm, buf);                    \
310         }                                                               \
311         static ssize_t store_##_name(struct device *dev,                \
312                                      struct device_attribute *attr,     \
313                                      const char *buf, size_t count)     \
314         {                                                               \
315                 return store_sys_acpi(dev, _cm, buf, count);            \
316         }                                                               \
317         static struct device_attribute dev_attr_##_name = {             \
318                 .attr = {                                               \
319                         .name = __stringify(_name),                     \
320                         .mode = _mode },                                \
321                 .show   = show_##_name,                                 \
322                 .store  = store_##_name,                                \
323         }
324
325 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
326 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
327 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
328
329 struct eeepc_cpufv {
330         int num;
331         int cur;
332 };
333
334 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
335 {
336         c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
337         c->num = (c->cur >> 8) & 0xff;
338         c->cur &= 0xff;
339         if (c->cur < 0 || c->num <= 0 || c->num > 12)
340                 return -ENODEV;
341         return 0;
342 }
343
344 static ssize_t show_available_cpufv(struct device *dev,
345                                     struct device_attribute *attr,
346                                     char *buf)
347 {
348         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
349         struct eeepc_cpufv c;
350         int i;
351         ssize_t len = 0;
352
353         if (get_cpufv(eeepc, &c))
354                 return -ENODEV;
355         for (i = 0; i < c.num; i++)
356                 len += sprintf(buf + len, "%d ", i);
357         len += sprintf(buf + len, "\n");
358         return len;
359 }
360
361 static ssize_t show_cpufv(struct device *dev,
362                           struct device_attribute *attr,
363                           char *buf)
364 {
365         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
366         struct eeepc_cpufv c;
367
368         if (get_cpufv(eeepc, &c))
369                 return -ENODEV;
370         return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
371 }
372
373 static ssize_t store_cpufv(struct device *dev,
374                            struct device_attribute *attr,
375                            const char *buf, size_t count)
376 {
377         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
378         struct eeepc_cpufv c;
379         int rv, value;
380
381         if (get_cpufv(eeepc, &c))
382                 return -ENODEV;
383         rv = parse_arg(buf, count, &value);
384         if (rv < 0)
385                 return rv;
386         if (!rv || value < 0 || value >= c.num)
387                 return -EINVAL;
388         set_acpi(eeepc, CM_ASL_CPUFV, value);
389         return rv;
390 }
391
392 static struct device_attribute dev_attr_cpufv = {
393         .attr = {
394                 .name = "cpufv",
395                 .mode = 0644 },
396         .show   = show_cpufv,
397         .store  = store_cpufv
398 };
399
400 static struct device_attribute dev_attr_available_cpufv = {
401         .attr = {
402                 .name = "available_cpufv",
403                 .mode = 0444 },
404         .show   = show_available_cpufv
405 };
406
407 static struct attribute *platform_attributes[] = {
408         &dev_attr_camera.attr,
409         &dev_attr_cardr.attr,
410         &dev_attr_disp.attr,
411         &dev_attr_cpufv.attr,
412         &dev_attr_available_cpufv.attr,
413         NULL
414 };
415
416 static struct attribute_group platform_attribute_group = {
417         .attrs = platform_attributes
418 };
419
420 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
421 {
422         int result;
423
424         eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
425         if (!eeepc->platform_device)
426                 return -ENOMEM;
427         platform_set_drvdata(eeepc->platform_device, eeepc);
428
429         result = platform_device_add(eeepc->platform_device);
430         if (result)
431                 goto fail_platform_device;
432
433         result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
434                                     &platform_attribute_group);
435         if (result)
436                 goto fail_sysfs;
437         return 0;
438
439 fail_sysfs:
440         platform_device_del(eeepc->platform_device);
441 fail_platform_device:
442         platform_device_put(eeepc->platform_device);
443         return result;
444 }
445
446 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
447 {
448         sysfs_remove_group(&eeepc->platform_device->dev.kobj,
449                            &platform_attribute_group);
450         platform_device_unregister(eeepc->platform_device);
451 }
452
453 /*
454  * LEDs
455  */
456 /*
457  * These functions actually update the LED's, and are called from a
458  * workqueue. By doing this as separate work rather than when the LED
459  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
460  * potentially bad time, such as a timer interrupt.
461  */
462 static void tpd_led_update(struct work_struct *work)
463  {
464         struct eeepc_laptop *eeepc;
465
466         eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
467
468         set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
469 }
470
471 static void tpd_led_set(struct led_classdev *led_cdev,
472                         enum led_brightness value)
473 {
474         struct eeepc_laptop *eeepc;
475
476         eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
477
478         eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
479         queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
480 }
481
482 static int eeepc_led_init(struct eeepc_laptop *eeepc)
483 {
484         int rv;
485
486         if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
487                 return 0;
488
489         eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
490         if (!eeepc->led_workqueue)
491                 return -ENOMEM;
492         INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
493
494         eeepc->tpd_led.name = "eeepc::touchpad";
495         eeepc->tpd_led.brightness_set = tpd_led_set;
496         eeepc->tpd_led.max_brightness = 1;
497
498         rv = led_classdev_register(&eeepc->platform_device->dev,
499                                    &eeepc->tpd_led);
500         if (rv) {
501                 destroy_workqueue(eeepc->led_workqueue);
502                 return rv;
503         }
504
505         return 0;
506 }
507
508 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
509 {
510         if (eeepc->tpd_led.dev)
511                 led_classdev_unregister(&eeepc->tpd_led);
512         if (eeepc->led_workqueue)
513                 destroy_workqueue(eeepc->led_workqueue);
514 }
515
516
517 /*
518  * PCI hotplug (for wlan rfkill)
519  */
520 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
521 {
522         if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
523                 return false;
524         return true;
525 }
526
527 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
528 {
529         struct pci_dev *dev;
530         struct pci_bus *bus;
531         bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
532
533         if (eeepc->wlan_rfkill)
534                 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
535
536         mutex_lock(&eeepc->hotplug_lock);
537
538         if (eeepc->hotplug_slot) {
539                 bus = pci_find_bus(0, 1);
540                 if (!bus) {
541                         pr_warning("Unable to find PCI bus 1?\n");
542                         goto out_unlock;
543                 }
544
545                 if (!blocked) {
546                         dev = pci_get_slot(bus, 0);
547                         if (dev) {
548                                 /* Device already present */
549                                 pci_dev_put(dev);
550                                 goto out_unlock;
551                         }
552                         dev = pci_scan_single_device(bus, 0);
553                         if (dev) {
554                                 pci_bus_assign_resources(bus);
555                                 if (pci_bus_add_device(dev))
556                                         pr_err("Unable to hotplug wifi\n");
557                         }
558                 } else {
559                         dev = pci_get_slot(bus, 0);
560                         if (dev) {
561                                 pci_remove_bus_device(dev);
562                                 pci_dev_put(dev);
563                         }
564                 }
565         }
566
567 out_unlock:
568         mutex_unlock(&eeepc->hotplug_lock);
569 }
570
571 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
572 {
573         struct eeepc_laptop *eeepc = data;
574
575         if (event != ACPI_NOTIFY_BUS_CHECK)
576                 return;
577
578         eeepc_rfkill_hotplug(eeepc);
579 }
580
581 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
582                                           char *node)
583 {
584         acpi_status status;
585         acpi_handle handle;
586
587         status = acpi_get_handle(NULL, node, &handle);
588
589         if (ACPI_SUCCESS(status)) {
590                 status = acpi_install_notify_handler(handle,
591                                                      ACPI_SYSTEM_NOTIFY,
592                                                      eeepc_rfkill_notify,
593                                                      eeepc);
594                 if (ACPI_FAILURE(status))
595                         pr_warning("Failed to register notify on %s\n", node);
596         } else
597                 return -ENODEV;
598
599         return 0;
600 }
601
602 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
603                                              char *node)
604 {
605         acpi_status status = AE_OK;
606         acpi_handle handle;
607
608         status = acpi_get_handle(NULL, node, &handle);
609
610         if (ACPI_SUCCESS(status)) {
611                 status = acpi_remove_notify_handler(handle,
612                                                      ACPI_SYSTEM_NOTIFY,
613                                                      eeepc_rfkill_notify);
614                 if (ACPI_FAILURE(status))
615                         pr_err("Error removing rfkill notify handler %s\n",
616                                 node);
617         }
618 }
619
620 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
621                                     u8 *value)
622 {
623         struct eeepc_laptop *eeepc = hotplug_slot->private;
624         int val = get_acpi(eeepc, CM_ASL_WLAN);
625
626         if (val == 1 || val == 0)
627                 *value = val;
628         else
629                 return -EINVAL;
630
631         return 0;
632 }
633
634 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
635 {
636         kfree(hotplug_slot->info);
637         kfree(hotplug_slot);
638 }
639
640 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
641         .owner = THIS_MODULE,
642         .get_adapter_status = eeepc_get_adapter_status,
643         .get_power_status = eeepc_get_adapter_status,
644 };
645
646 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
647 {
648         int ret = -ENOMEM;
649         struct pci_bus *bus = pci_find_bus(0, 1);
650
651         if (!bus) {
652                 pr_err("Unable to find wifi PCI bus\n");
653                 return -ENODEV;
654         }
655
656         eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
657         if (!eeepc->hotplug_slot)
658                 goto error_slot;
659
660         eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
661                                             GFP_KERNEL);
662         if (!eeepc->hotplug_slot->info)
663                 goto error_info;
664
665         eeepc->hotplug_slot->private = eeepc;
666         eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
667         eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
668         eeepc_get_adapter_status(eeepc->hotplug_slot,
669                                  &eeepc->hotplug_slot->info->adapter_status);
670
671         ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
672         if (ret) {
673                 pr_err("Unable to register hotplug slot - %d\n", ret);
674                 goto error_register;
675         }
676
677         return 0;
678
679 error_register:
680         kfree(eeepc->hotplug_slot->info);
681 error_info:
682         kfree(eeepc->hotplug_slot);
683         eeepc->hotplug_slot = NULL;
684 error_slot:
685         return ret;
686 }
687
688 /*
689  * Rfkill devices
690  */
691 static int eeepc_rfkill_set(void *data, bool blocked)
692 {
693         acpi_handle handle = data;
694
695         return write_acpi_int(handle, NULL, !blocked);
696 }
697
698 static const struct rfkill_ops eeepc_rfkill_ops = {
699         .set_block = eeepc_rfkill_set,
700 };
701
702 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
703                             struct rfkill **rfkill,
704                             const char *name,
705                             enum rfkill_type type, int cm)
706 {
707         acpi_handle handle;
708         int result;
709
710         result = acpi_setter_handle(eeepc, cm, &handle);
711         if (result < 0)
712                 return result;
713
714         *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
715                                &eeepc_rfkill_ops, handle);
716
717         if (!*rfkill)
718                 return -EINVAL;
719
720         rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
721         result = rfkill_register(*rfkill);
722         if (result) {
723                 rfkill_destroy(*rfkill);
724                 *rfkill = NULL;
725                 return result;
726         }
727         return 0;
728 }
729
730 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
731 {
732         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
733         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
734         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
735         if (eeepc->wlan_rfkill) {
736                 rfkill_unregister(eeepc->wlan_rfkill);
737                 rfkill_destroy(eeepc->wlan_rfkill);
738                 eeepc->wlan_rfkill = NULL;
739         }
740         /*
741          * Refresh pci hotplug in case the rfkill state was changed after
742          * eeepc_unregister_rfkill_notifier()
743          */
744         eeepc_rfkill_hotplug(eeepc);
745         if (eeepc->hotplug_slot)
746                 pci_hp_deregister(eeepc->hotplug_slot);
747
748         if (eeepc->bluetooth_rfkill) {
749                 rfkill_unregister(eeepc->bluetooth_rfkill);
750                 rfkill_destroy(eeepc->bluetooth_rfkill);
751                 eeepc->bluetooth_rfkill = NULL;
752         }
753         if (eeepc->wwan3g_rfkill) {
754                 rfkill_unregister(eeepc->wwan3g_rfkill);
755                 rfkill_destroy(eeepc->wwan3g_rfkill);
756                 eeepc->wwan3g_rfkill = NULL;
757         }
758         if (eeepc->wimax_rfkill) {
759                 rfkill_unregister(eeepc->wimax_rfkill);
760                 rfkill_destroy(eeepc->wimax_rfkill);
761                 eeepc->wimax_rfkill = NULL;
762         }
763 }
764
765 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
766 {
767         int result = 0;
768
769         mutex_init(&eeepc->hotplug_lock);
770
771         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
772                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
773                                   CM_ASL_WLAN);
774
775         if (result && result != -ENODEV)
776                 goto exit;
777
778         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
779                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
780                                   CM_ASL_BLUETOOTH);
781
782         if (result && result != -ENODEV)
783                 goto exit;
784
785         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
786                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
787                                   CM_ASL_3G);
788
789         if (result && result != -ENODEV)
790                 goto exit;
791
792         result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
793                                   "eeepc-wimax", RFKILL_TYPE_WIMAX,
794                                   CM_ASL_WIMAX);
795
796         if (result && result != -ENODEV)
797                 goto exit;
798
799         result = eeepc_setup_pci_hotplug(eeepc);
800         /*
801          * If we get -EBUSY then something else is handling the PCI hotplug -
802          * don't fail in this case
803          */
804         if (result == -EBUSY)
805                 result = 0;
806
807         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
808         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
809         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
810         /*
811          * Refresh pci hotplug in case the rfkill state was changed during
812          * setup.
813          */
814         eeepc_rfkill_hotplug(eeepc);
815
816 exit:
817         if (result && result != -ENODEV)
818                 eeepc_rfkill_exit(eeepc);
819         return result;
820 }
821
822 /*
823  * Platform driver - hibernate/resume callbacks
824  */
825 static int eeepc_hotk_thaw(struct device *device)
826 {
827         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
828
829         if (eeepc->wlan_rfkill) {
830                 bool wlan;
831
832                 /*
833                  * Work around bios bug - acpi _PTS turns off the wireless led
834                  * during suspend.  Normally it restores it on resume, but
835                  * we should kick it ourselves in case hibernation is aborted.
836                  */
837                 wlan = get_acpi(eeepc, CM_ASL_WLAN);
838                 set_acpi(eeepc, CM_ASL_WLAN, wlan);
839         }
840
841         return 0;
842 }
843
844 static int eeepc_hotk_restore(struct device *device)
845 {
846         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
847
848         /* Refresh both wlan rfkill state and pci hotplug */
849         if (eeepc->wlan_rfkill)
850                 eeepc_rfkill_hotplug(eeepc);
851
852         if (eeepc->bluetooth_rfkill)
853                 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
854                                     get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
855         if (eeepc->wwan3g_rfkill)
856                 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
857                                     get_acpi(eeepc, CM_ASL_3G) != 1);
858         if (eeepc->wimax_rfkill)
859                 rfkill_set_sw_state(eeepc->wimax_rfkill,
860                                     get_acpi(eeepc, CM_ASL_WIMAX) != 1);
861
862         return 0;
863 }
864
865 static const struct dev_pm_ops eeepc_pm_ops = {
866         .thaw = eeepc_hotk_thaw,
867         .restore = eeepc_hotk_restore,
868 };
869
870 static struct platform_driver platform_driver = {
871         .driver = {
872                 .name = EEEPC_LAPTOP_FILE,
873                 .owner = THIS_MODULE,
874                 .pm = &eeepc_pm_ops,
875         }
876 };
877
878 /*
879  * Hwmon device
880  */
881
882 #define EEEPC_EC_SC00      0x61
883 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
884 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
885 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
886
887 #define EEEPC_EC_SFB0      0xD0
888 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
889
890 static int eeepc_get_fan_pwm(void)
891 {
892         u8 value = 0;
893
894         ec_read(EEEPC_EC_FAN_PWM, &value);
895         return value * 255 / 100;
896 }
897
898 static void eeepc_set_fan_pwm(int value)
899 {
900         value = SENSORS_LIMIT(value, 0, 255);
901         value = value * 100 / 255;
902         ec_write(EEEPC_EC_FAN_PWM, value);
903 }
904
905 static int eeepc_get_fan_rpm(void)
906 {
907         u8 high = 0;
908         u8 low = 0;
909
910         ec_read(EEEPC_EC_FAN_HRPM, &high);
911         ec_read(EEEPC_EC_FAN_LRPM, &low);
912         return high << 8 | low;
913 }
914
915 static int eeepc_get_fan_ctrl(void)
916 {
917         u8 value = 0;
918
919         ec_read(EEEPC_EC_FAN_CTRL, &value);
920         if (value & 0x02)
921                 return 1; /* manual */
922         else
923                 return 2; /* automatic */
924 }
925
926 static void eeepc_set_fan_ctrl(int manual)
927 {
928         u8 value = 0;
929
930         ec_read(EEEPC_EC_FAN_CTRL, &value);
931         if (manual == 1)
932                 value |= 0x02;
933         else
934                 value &= ~0x02;
935         ec_write(EEEPC_EC_FAN_CTRL, value);
936 }
937
938 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
939 {
940         int rv, value;
941
942         rv = parse_arg(buf, count, &value);
943         if (rv > 0)
944                 set(value);
945         return rv;
946 }
947
948 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
949 {
950         return sprintf(buf, "%d\n", get());
951 }
952
953 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
954         static ssize_t show_##_name(struct device *dev,                 \
955                                     struct device_attribute *attr,      \
956                                     char *buf)                          \
957         {                                                               \
958                 return show_sys_hwmon(_set, buf);                       \
959         }                                                               \
960         static ssize_t store_##_name(struct device *dev,                \
961                                      struct device_attribute *attr,     \
962                                      const char *buf, size_t count)     \
963         {                                                               \
964                 return store_sys_hwmon(_get, buf, count);               \
965         }                                                               \
966         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
967
968 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
969 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
970                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
971 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
972                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
973
974 static ssize_t
975 show_name(struct device *dev, struct device_attribute *attr, char *buf)
976 {
977         return sprintf(buf, "eeepc\n");
978 }
979 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
980
981 static struct attribute *hwmon_attributes[] = {
982         &sensor_dev_attr_pwm1.dev_attr.attr,
983         &sensor_dev_attr_fan1_input.dev_attr.attr,
984         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
985         &sensor_dev_attr_name.dev_attr.attr,
986         NULL
987 };
988
989 static struct attribute_group hwmon_attribute_group = {
990         .attrs = hwmon_attributes
991 };
992
993 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
994 {
995         struct device *hwmon;
996
997         hwmon = eeepc->hwmon_device;
998         if (!hwmon)
999                 return;
1000         sysfs_remove_group(&hwmon->kobj,
1001                            &hwmon_attribute_group);
1002         hwmon_device_unregister(hwmon);
1003         eeepc->hwmon_device = NULL;
1004 }
1005
1006 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1007 {
1008         struct device *hwmon;
1009         int result;
1010
1011         hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1012         if (IS_ERR(hwmon)) {
1013                 pr_err("Could not register eeepc hwmon device\n");
1014                 eeepc->hwmon_device = NULL;
1015                 return PTR_ERR(hwmon);
1016         }
1017         eeepc->hwmon_device = hwmon;
1018         result = sysfs_create_group(&hwmon->kobj,
1019                                     &hwmon_attribute_group);
1020         if (result)
1021                 eeepc_hwmon_exit(eeepc);
1022         return result;
1023 }
1024
1025 /*
1026  * Backlight device
1027  */
1028 static int read_brightness(struct backlight_device *bd)
1029 {
1030         struct eeepc_laptop *eeepc = bl_get_data(bd);
1031
1032         return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1033 }
1034
1035 static int set_brightness(struct backlight_device *bd, int value)
1036 {
1037         struct eeepc_laptop *eeepc = bl_get_data(bd);
1038
1039         return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1040 }
1041
1042 static int update_bl_status(struct backlight_device *bd)
1043 {
1044         return set_brightness(bd, bd->props.brightness);
1045 }
1046
1047 static struct backlight_ops eeepcbl_ops = {
1048         .get_brightness = read_brightness,
1049         .update_status = update_bl_status,
1050 };
1051
1052 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1053 {
1054         struct backlight_device *bd = eeepc->backlight_device;
1055         int old = bd->props.brightness;
1056
1057         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1058
1059         return old;
1060 }
1061
1062 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1063 {
1064         struct backlight_device *bd;
1065
1066         bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1067                                        &eeepc->platform_device->dev,
1068                                        eeepc, &eeepcbl_ops);
1069         if (IS_ERR(bd)) {
1070                 pr_err("Could not register eeepc backlight device\n");
1071                 eeepc->backlight_device = NULL;
1072                 return PTR_ERR(bd);
1073         }
1074         eeepc->backlight_device = bd;
1075         bd->props.max_brightness = 15;
1076         bd->props.brightness = read_brightness(bd);
1077         bd->props.power = FB_BLANK_UNBLANK;
1078         backlight_update_status(bd);
1079         return 0;
1080 }
1081
1082 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1083 {
1084         if (eeepc->backlight_device)
1085                 backlight_device_unregister(eeepc->backlight_device);
1086         eeepc->backlight_device = NULL;
1087 }
1088
1089
1090 /*
1091  * Input device (i.e. hotkeys)
1092  */
1093 static struct key_entry *eeepc_get_entry_by_scancode(
1094         struct eeepc_laptop *eeepc,
1095         int code)
1096 {
1097         struct key_entry *key;
1098
1099         for (key = eeepc->keymap; key->type != KE_END; key++)
1100                 if (code == key->code)
1101                         return key;
1102
1103         return NULL;
1104 }
1105
1106 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1107 {
1108         static struct key_entry *key;
1109
1110         key = eeepc_get_entry_by_scancode(eeepc, event);
1111         if (key) {
1112                 switch (key->type) {
1113                 case KE_KEY:
1114                         input_report_key(eeepc->inputdev, key->keycode,
1115                                                 1);
1116                         input_sync(eeepc->inputdev);
1117                         input_report_key(eeepc->inputdev, key->keycode,
1118                                                 0);
1119                         input_sync(eeepc->inputdev);
1120                         break;
1121                 }
1122         }
1123 }
1124
1125 static struct key_entry *eeepc_get_entry_by_keycode(
1126         struct eeepc_laptop *eeepc, int code)
1127 {
1128         struct key_entry *key;
1129
1130         for (key = eeepc->keymap; key->type != KE_END; key++)
1131                 if (code == key->keycode && key->type == KE_KEY)
1132                         return key;
1133
1134         return NULL;
1135 }
1136
1137 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1138 {
1139         struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1140         struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
1141
1142         if (key && key->type == KE_KEY) {
1143                 *keycode = key->keycode;
1144                 return 0;
1145         }
1146
1147         return -EINVAL;
1148 }
1149
1150 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
1151 {
1152         struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1153         struct key_entry *key;
1154         int old_keycode;
1155
1156         if (keycode < 0 || keycode > KEY_MAX)
1157                 return -EINVAL;
1158
1159         key = eeepc_get_entry_by_scancode(eeepc, scancode);
1160         if (key && key->type == KE_KEY) {
1161                 old_keycode = key->keycode;
1162                 key->keycode = keycode;
1163                 set_bit(keycode, dev->keybit);
1164                 if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
1165                         clear_bit(old_keycode, dev->keybit);
1166                 return 0;
1167         }
1168
1169         return -EINVAL;
1170 }
1171
1172 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1173 {
1174         const struct key_entry *key;
1175         int result;
1176
1177         eeepc->inputdev = input_allocate_device();
1178         if (!eeepc->inputdev) {
1179                 pr_info("Unable to allocate input device\n");
1180                 return -ENOMEM;
1181         }
1182         eeepc->inputdev->name = "Asus EeePC extra buttons";
1183         eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
1184         eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
1185         eeepc->inputdev->id.bustype = BUS_HOST;
1186         eeepc->inputdev->getkeycode = eeepc_getkeycode;
1187         eeepc->inputdev->setkeycode = eeepc_setkeycode;
1188         input_set_drvdata(eeepc->inputdev, eeepc);
1189
1190         eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
1191                                 GFP_KERNEL);
1192         for (key = eeepc_keymap; key->type != KE_END; key++) {
1193                 switch (key->type) {
1194                 case KE_KEY:
1195                         set_bit(EV_KEY, eeepc->inputdev->evbit);
1196                         set_bit(key->keycode, eeepc->inputdev->keybit);
1197                         break;
1198                 }
1199         }
1200         result = input_register_device(eeepc->inputdev);
1201         if (result) {
1202                 pr_info("Unable to register input device\n");
1203                 input_free_device(eeepc->inputdev);
1204                 return result;
1205         }
1206         return 0;
1207 }
1208
1209 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1210 {
1211         if (eeepc->inputdev) {
1212                 input_unregister_device(eeepc->inputdev);
1213                 kfree(eeepc->keymap);
1214         }
1215 }
1216
1217 /*
1218  * ACPI driver
1219  */
1220 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1221 {
1222         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1223         u16 count;
1224
1225         if (event > ACPI_MAX_SYS_NOTIFY)
1226                 return;
1227         count = eeepc->event_count[event % 128]++;
1228         acpi_bus_generate_proc_event(device, event, count);
1229         acpi_bus_generate_netlink_event(device->pnp.device_class,
1230                                         dev_name(&device->dev), event,
1231                                         count);
1232
1233         /* Brightness events are special */
1234         if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1235
1236                 /* Ignore them completely if the acpi video driver is used */
1237                 if (eeepc->backlight_device != NULL) {
1238                         int old_brightness, new_brightness;
1239
1240                         /* Update the backlight device. */
1241                         old_brightness = eeepc_backlight_notify(eeepc);
1242
1243                         /* Convert event to keypress (obsolescent hack) */
1244                         new_brightness = event - NOTIFY_BRN_MIN;
1245
1246                         if (new_brightness < old_brightness) {
1247                                 event = NOTIFY_BRN_MIN; /* brightness down */
1248                         } else if (new_brightness > old_brightness) {
1249                                 event = NOTIFY_BRN_MAX; /* brightness up */
1250                         } else {
1251                                 /*
1252                                 * no change in brightness - already at min/max,
1253                                 * event will be desired value (or else ignored)
1254                                 */
1255                         }
1256                         eeepc_input_notify(eeepc, event);
1257                 }
1258         } else {
1259                 /* Everything else is a bona-fide keypress event */
1260                 eeepc_input_notify(eeepc, event);
1261         }
1262 }
1263
1264 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1265 {
1266         int dummy;
1267
1268         /* Some BIOSes do not report cm although it is avaliable.
1269            Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1270         if (!(eeepc->cm_supported & (1 << cm))
1271             && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1272                 pr_info("%s (%x) not reported by BIOS,"
1273                         " enabling anyway\n", name, 1 << cm);
1274                 eeepc->cm_supported |= 1 << cm;
1275         }
1276 }
1277
1278 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1279 {
1280         cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1281         cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1282         cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1283         cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1284 }
1285
1286 static int eeepc_acpi_init(struct eeepc_laptop *eeepc,
1287                            struct acpi_device *device)
1288 {
1289         unsigned int init_flags;
1290         int result;
1291
1292         result = acpi_bus_get_status(device);
1293         if (result)
1294                 return result;
1295         if (!device->status.present) {
1296                 pr_err("Hotkey device not present, aborting\n");
1297                 return -ENODEV;
1298         }
1299
1300         init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1301         pr_notice("Hotkey init flags 0x%x\n", init_flags);
1302
1303         if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1304                 pr_err("Hotkey initialization failed\n");
1305                 return -ENODEV;
1306         }
1307
1308         /* get control methods supported */
1309         if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1310                 pr_err("Get control methods supported failed\n");
1311                 return -ENODEV;
1312         }
1313         cmsg_quirks(eeepc);
1314         pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1315
1316         return 0;
1317 }
1318
1319 static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1320 {
1321         /*
1322          * If the following call to set_acpi() fails, it's because there's no
1323          * camera so we can ignore the error.
1324          */
1325         if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1326                 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1327 }
1328
1329 static bool eeepc_device_present;
1330
1331 static int __devinit eeepc_acpi_add(struct acpi_device *device)
1332 {
1333         struct eeepc_laptop *eeepc;
1334         int result;
1335
1336         pr_notice(EEEPC_LAPTOP_NAME "\n");
1337         eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1338         if (!eeepc)
1339                 return -ENOMEM;
1340         eeepc->handle = device->handle;
1341         strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1342         strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1343         device->driver_data = eeepc;
1344
1345         result = eeepc_acpi_init(eeepc, device);
1346         if (result)
1347                 goto fail_platform;
1348         eeepc_enable_camera(eeepc);
1349
1350         /*
1351          * Register the platform device first.  It is used as a parent for the
1352          * sub-devices below.
1353          *
1354          * Note that if there are multiple instances of this ACPI device it
1355          * will bail out, because the platform device is registered with a
1356          * fixed name.  Of course it doesn't make sense to have more than one,
1357          * and machine-specific scripts find the fixed name convenient.  But
1358          * It's also good for us to exclude multiple instances because both
1359          * our hwmon and our wlan rfkill subdevice use global ACPI objects
1360          * (the EC and the wlan PCI slot respectively).
1361          */
1362         result = eeepc_platform_init(eeepc);
1363         if (result)
1364                 goto fail_platform;
1365
1366         if (!acpi_video_backlight_support()) {
1367                 result = eeepc_backlight_init(eeepc);
1368                 if (result)
1369                         goto fail_backlight;
1370         } else
1371                 pr_info("Backlight controlled by ACPI video driver\n");
1372
1373         result = eeepc_input_init(eeepc);
1374         if (result)
1375                 goto fail_input;
1376
1377         result = eeepc_hwmon_init(eeepc);
1378         if (result)
1379                 goto fail_hwmon;
1380
1381         result = eeepc_led_init(eeepc);
1382         if (result)
1383                 goto fail_led;
1384
1385         result = eeepc_rfkill_init(eeepc);
1386         if (result)
1387                 goto fail_rfkill;
1388
1389         eeepc_device_present = true;
1390         return 0;
1391
1392 fail_rfkill:
1393         eeepc_led_exit(eeepc);
1394 fail_led:
1395         eeepc_hwmon_exit(eeepc);
1396 fail_hwmon:
1397         eeepc_input_exit(eeepc);
1398 fail_input:
1399         eeepc_backlight_exit(eeepc);
1400 fail_backlight:
1401         eeepc_platform_exit(eeepc);
1402 fail_platform:
1403         kfree(eeepc);
1404
1405         return result;
1406 }
1407
1408 static int eeepc_acpi_remove(struct acpi_device *device, int type)
1409 {
1410         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1411
1412         eeepc_backlight_exit(eeepc);
1413         eeepc_rfkill_exit(eeepc);
1414         eeepc_input_exit(eeepc);
1415         eeepc_hwmon_exit(eeepc);
1416         eeepc_led_exit(eeepc);
1417         eeepc_platform_exit(eeepc);
1418
1419         kfree(eeepc);
1420         return 0;
1421 }
1422
1423
1424 static const struct acpi_device_id eeepc_device_ids[] = {
1425         {EEEPC_ACPI_HID, 0},
1426         {"", 0},
1427 };
1428 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1429
1430 static struct acpi_driver eeepc_acpi_driver = {
1431         .name = EEEPC_LAPTOP_NAME,
1432         .class = EEEPC_ACPI_CLASS,
1433         .owner = THIS_MODULE,
1434         .ids = eeepc_device_ids,
1435         .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1436         .ops = {
1437                 .add = eeepc_acpi_add,
1438                 .remove = eeepc_acpi_remove,
1439                 .notify = eeepc_acpi_notify,
1440         },
1441 };
1442
1443
1444 static int __init eeepc_laptop_init(void)
1445 {
1446         int result;
1447
1448         result = platform_driver_register(&platform_driver);
1449         if (result < 0)
1450                 return result;
1451
1452         result = acpi_bus_register_driver(&eeepc_acpi_driver);
1453         if (result < 0)
1454                 goto fail_acpi_driver;
1455         if (!eeepc_device_present) {
1456                 result = -ENODEV;
1457                 goto fail_no_device;
1458         }
1459         return 0;
1460
1461 fail_no_device:
1462         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1463 fail_acpi_driver:
1464         platform_driver_unregister(&platform_driver);
1465         return result;
1466 }
1467
1468 static void __exit eeepc_laptop_exit(void)
1469 {
1470         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1471         platform_driver_unregister(&platform_driver);
1472 }
1473
1474 module_init(eeepc_laptop_init);
1475 module_exit(eeepc_laptop_exit);