aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/eeepc-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/eeepc-laptop.c')
-rw-r--r--drivers/platform/x86/eeepc-laptop.c108
1 files changed, 74 insertions, 34 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 6b8e06206c46..1c45d92e2163 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -165,6 +165,7 @@ struct eeepc_laptop {
165 u16 event_count[128]; /* count for each event */ 165 u16 event_count[128]; /* count for each event */
166 166
167 struct platform_device *platform_device; 167 struct platform_device *platform_device;
168 struct acpi_device *device; /* the device we are in */
168 struct device *hwmon_device; 169 struct device *hwmon_device;
169 struct backlight_device *backlight_device; 170 struct backlight_device *backlight_device;
170 171
@@ -227,7 +228,7 @@ static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
227 return -ENODEV; 228 return -ENODEV;
228 229
229 if (write_acpi_int(eeepc->handle, method, value)) 230 if (write_acpi_int(eeepc->handle, method, value))
230 pr_warning("Error writing %s\n", method); 231 pr_warn("Error writing %s\n", method);
231 return 0; 232 return 0;
232} 233}
233 234
@@ -242,7 +243,7 @@ static int get_acpi(struct eeepc_laptop *eeepc, int cm)
242 return -ENODEV; 243 return -ENODEV;
243 244
244 if (read_acpi_int(eeepc->handle, method, &value)) 245 if (read_acpi_int(eeepc->handle, method, &value))
245 pr_warning("Error reading %s\n", method); 246 pr_warn("Error reading %s\n", method);
246 return value; 247 return value;
247} 248}
248 249
@@ -260,7 +261,7 @@ static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
260 status = acpi_get_handle(eeepc->handle, (char *)method, 261 status = acpi_get_handle(eeepc->handle, (char *)method,
261 handle); 262 handle);
262 if (status != AE_OK) { 263 if (status != AE_OK) {
263 pr_warning("Error finding %s\n", method); 264 pr_warn("Error finding %s\n", method);
264 return -ENODEV; 265 return -ENODEV;
265 } 266 }
266 return 0; 267 return 0;
@@ -416,7 +417,7 @@ static ssize_t store_cpufv_disabled(struct device *dev,
416 switch (value) { 417 switch (value) {
417 case 0: 418 case 0:
418 if (eeepc->cpufv_disabled) 419 if (eeepc->cpufv_disabled)
419 pr_warning("cpufv enabled (not officially supported " 420 pr_warn("cpufv enabled (not officially supported "
420 "on this model)\n"); 421 "on this model)\n");
421 eeepc->cpufv_disabled = false; 422 eeepc->cpufv_disabled = false;
422 return rv; 423 return rv;
@@ -528,6 +529,15 @@ static void tpd_led_set(struct led_classdev *led_cdev,
528 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work); 529 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
529} 530}
530 531
532static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
533{
534 struct eeepc_laptop *eeepc;
535
536 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
537
538 return get_acpi(eeepc, CM_ASL_TPD);
539}
540
531static int eeepc_led_init(struct eeepc_laptop *eeepc) 541static int eeepc_led_init(struct eeepc_laptop *eeepc)
532{ 542{
533 int rv; 543 int rv;
@@ -542,6 +552,8 @@ static int eeepc_led_init(struct eeepc_laptop *eeepc)
542 552
543 eeepc->tpd_led.name = "eeepc::touchpad"; 553 eeepc->tpd_led.name = "eeepc::touchpad";
544 eeepc->tpd_led.brightness_set = tpd_led_set; 554 eeepc->tpd_led.brightness_set = tpd_led_set;
555 if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
556 eeepc->tpd_led.brightness_get = tpd_led_get;
545 eeepc->tpd_led.max_brightness = 1; 557 eeepc->tpd_led.max_brightness = 1;
546 558
547 rv = led_classdev_register(&eeepc->platform_device->dev, 559 rv = led_classdev_register(&eeepc->platform_device->dev,
@@ -573,8 +585,9 @@ static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
573 return true; 585 return true;
574} 586}
575 587
576static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) 588static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
577{ 589{
590 struct pci_dev *port;
578 struct pci_dev *dev; 591 struct pci_dev *dev;
579 struct pci_bus *bus; 592 struct pci_bus *bus;
580 bool blocked = eeepc_wlan_rfkill_blocked(eeepc); 593 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
@@ -587,9 +600,16 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
587 mutex_lock(&eeepc->hotplug_lock); 600 mutex_lock(&eeepc->hotplug_lock);
588 601
589 if (eeepc->hotplug_slot) { 602 if (eeepc->hotplug_slot) {
590 bus = pci_find_bus(0, 1); 603 port = acpi_get_pci_dev(handle);
604 if (!port) {
605 pr_warning("Unable to find port\n");
606 goto out_unlock;
607 }
608
609 bus = port->subordinate;
610
591 if (!bus) { 611 if (!bus) {
592 pr_warning("Unable to find PCI bus 1?\n"); 612 pr_warn("Unable to find PCI bus 1?\n");
593 goto out_unlock; 613 goto out_unlock;
594 } 614 }
595 615
@@ -597,15 +617,16 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
597 pr_err("Unable to read PCI config space?\n"); 617 pr_err("Unable to read PCI config space?\n");
598 goto out_unlock; 618 goto out_unlock;
599 } 619 }
620
600 absent = (l == 0xffffffff); 621 absent = (l == 0xffffffff);
601 622
602 if (blocked != absent) { 623 if (blocked != absent) {
603 pr_warning("BIOS says wireless lan is %s, " 624 pr_warn("BIOS says wireless lan is %s, "
604 "but the pci device is %s\n", 625 "but the pci device is %s\n",
605 blocked ? "blocked" : "unblocked", 626 blocked ? "blocked" : "unblocked",
606 absent ? "absent" : "present"); 627 absent ? "absent" : "present");
607 pr_warning("skipped wireless hotplug as probably " 628 pr_warn("skipped wireless hotplug as probably "
608 "inappropriate for this model\n"); 629 "inappropriate for this model\n");
609 goto out_unlock; 630 goto out_unlock;
610 } 631 }
611 632
@@ -635,6 +656,17 @@ out_unlock:
635 mutex_unlock(&eeepc->hotplug_lock); 656 mutex_unlock(&eeepc->hotplug_lock);
636} 657}
637 658
659static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
660{
661 acpi_status status = AE_OK;
662 acpi_handle handle;
663
664 status = acpi_get_handle(NULL, node, &handle);
665
666 if (ACPI_SUCCESS(status))
667 eeepc_rfkill_hotplug(eeepc, handle);
668}
669
638static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 670static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
639{ 671{
640 struct eeepc_laptop *eeepc = data; 672 struct eeepc_laptop *eeepc = data;
@@ -642,7 +674,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
642 if (event != ACPI_NOTIFY_BUS_CHECK) 674 if (event != ACPI_NOTIFY_BUS_CHECK)
643 return; 675 return;
644 676
645 eeepc_rfkill_hotplug(eeepc); 677 eeepc_rfkill_hotplug(eeepc, handle);
646} 678}
647 679
648static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, 680static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
@@ -659,7 +691,13 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
659 eeepc_rfkill_notify, 691 eeepc_rfkill_notify,
660 eeepc); 692 eeepc);
661 if (ACPI_FAILURE(status)) 693 if (ACPI_FAILURE(status))
662 pr_warning("Failed to register notify on %s\n", node); 694 pr_warn("Failed to register notify on %s\n", node);
695
696 /*
697 * Refresh pci hotplug in case the rfkill state was
698 * changed during setup.
699 */
700 eeepc_rfkill_hotplug(eeepc, handle);
663 } else 701 } else
664 return -ENODEV; 702 return -ENODEV;
665 703
@@ -681,6 +719,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
681 if (ACPI_FAILURE(status)) 719 if (ACPI_FAILURE(status))
682 pr_err("Error removing rfkill notify handler %s\n", 720 pr_err("Error removing rfkill notify handler %s\n",
683 node); 721 node);
722 /*
723 * Refresh pci hotplug in case the rfkill
724 * state was changed after
725 * eeepc_unregister_rfkill_notifier()
726 */
727 eeepc_rfkill_hotplug(eeepc, handle);
684 } 728 }
685} 729}
686 730
@@ -804,11 +848,7 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
804 rfkill_destroy(eeepc->wlan_rfkill); 848 rfkill_destroy(eeepc->wlan_rfkill);
805 eeepc->wlan_rfkill = NULL; 849 eeepc->wlan_rfkill = NULL;
806 } 850 }
807 /* 851
808 * Refresh pci hotplug in case the rfkill state was changed after
809 * eeepc_unregister_rfkill_notifier()
810 */
811 eeepc_rfkill_hotplug(eeepc);
812 if (eeepc->hotplug_slot) 852 if (eeepc->hotplug_slot)
813 pci_hp_deregister(eeepc->hotplug_slot); 853 pci_hp_deregister(eeepc->hotplug_slot);
814 854
@@ -877,11 +917,6 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
877 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); 917 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
878 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); 918 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
879 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); 919 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
880 /*
881 * Refresh pci hotplug in case the rfkill state was changed during
882 * setup.
883 */
884 eeepc_rfkill_hotplug(eeepc);
885 920
886exit: 921exit:
887 if (result && result != -ENODEV) 922 if (result && result != -ENODEV)
@@ -916,8 +951,11 @@ static int eeepc_hotk_restore(struct device *device)
916 struct eeepc_laptop *eeepc = dev_get_drvdata(device); 951 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
917 952
918 /* Refresh both wlan rfkill state and pci hotplug */ 953 /* Refresh both wlan rfkill state and pci hotplug */
919 if (eeepc->wlan_rfkill) 954 if (eeepc->wlan_rfkill) {
920 eeepc_rfkill_hotplug(eeepc); 955 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
956 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
957 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
958 }
921 959
922 if (eeepc->bluetooth_rfkill) 960 if (eeepc->bluetooth_rfkill)
923 rfkill_set_sw_state(eeepc->bluetooth_rfkill, 961 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
@@ -1114,7 +1152,7 @@ static int update_bl_status(struct backlight_device *bd)
1114 return set_brightness(bd, bd->props.brightness); 1152 return set_brightness(bd, bd->props.brightness);
1115} 1153}
1116 1154
1117static struct backlight_ops eeepcbl_ops = { 1155static const struct backlight_ops eeepcbl_ops = {
1118 .get_brightness = read_brightness, 1156 .get_brightness = read_brightness,
1119 .update_status = update_bl_status, 1157 .update_status = update_bl_status,
1120}; 1158};
@@ -1135,6 +1173,7 @@ static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1135 struct backlight_device *bd; 1173 struct backlight_device *bd;
1136 1174
1137 memset(&props, 0, sizeof(struct backlight_properties)); 1175 memset(&props, 0, sizeof(struct backlight_properties));
1176 props.type = BACKLIGHT_PLATFORM;
1138 props.max_brightness = 15; 1177 props.max_brightness = 15;
1139 bd = backlight_device_register(EEEPC_LAPTOP_FILE, 1178 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1140 &eeepc->platform_device->dev, eeepc, 1179 &eeepc->platform_device->dev, eeepc,
@@ -1193,9 +1232,9 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc)
1193 eeepc->inputdev = input; 1232 eeepc->inputdev = input;
1194 return 0; 1233 return 0;
1195 1234
1196 err_free_keymap: 1235err_free_keymap:
1197 sparse_keymap_free(input); 1236 sparse_keymap_free(input);
1198 err_free_dev: 1237err_free_dev:
1199 input_free_device(input); 1238 input_free_device(input);
1200 return error; 1239 return error;
1201} 1240}
@@ -1206,6 +1245,7 @@ static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1206 sparse_keymap_free(eeepc->inputdev); 1245 sparse_keymap_free(eeepc->inputdev);
1207 input_unregister_device(eeepc->inputdev); 1246 input_unregister_device(eeepc->inputdev);
1208 } 1247 }
1248 eeepc->inputdev = NULL;
1209} 1249}
1210 1250
1211/* 1251/*
@@ -1308,7 +1348,7 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1308{ 1348{
1309 int dummy; 1349 int dummy;
1310 1350
1311 /* Some BIOSes do not report cm although it is avaliable. 1351 /* Some BIOSes do not report cm although it is available.
1312 Check if cm_getv[cm] works and, if yes, assume cm should be set. */ 1352 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1313 if (!(eeepc->cm_supported & (1 << cm)) 1353 if (!(eeepc->cm_supported & (1 << cm))
1314 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) { 1354 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
@@ -1326,16 +1366,15 @@ static void cmsg_quirks(struct eeepc_laptop *eeepc)
1326 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD"); 1366 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1327} 1367}
1328 1368
1329static int eeepc_acpi_init(struct eeepc_laptop *eeepc, 1369static int __devinit eeepc_acpi_init(struct eeepc_laptop *eeepc)
1330 struct acpi_device *device)
1331{ 1370{
1332 unsigned int init_flags; 1371 unsigned int init_flags;
1333 int result; 1372 int result;
1334 1373
1335 result = acpi_bus_get_status(device); 1374 result = acpi_bus_get_status(eeepc->device);
1336 if (result) 1375 if (result)
1337 return result; 1376 return result;
1338 if (!device->status.present) { 1377 if (!eeepc->device->status.present) {
1339 pr_err("Hotkey device not present, aborting\n"); 1378 pr_err("Hotkey device not present, aborting\n");
1340 return -ENODEV; 1379 return -ENODEV;
1341 } 1380 }
@@ -1384,12 +1423,13 @@ static int __devinit eeepc_acpi_add(struct acpi_device *device)
1384 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME); 1423 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1385 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS); 1424 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1386 device->driver_data = eeepc; 1425 device->driver_data = eeepc;
1426 eeepc->device = device;
1387 1427
1388 eeepc->hotplug_disabled = hotplug_disabled; 1428 eeepc->hotplug_disabled = hotplug_disabled;
1389 1429
1390 eeepc_dmi_check(eeepc); 1430 eeepc_dmi_check(eeepc);
1391 1431
1392 result = eeepc_acpi_init(eeepc, device); 1432 result = eeepc_acpi_init(eeepc);
1393 if (result) 1433 if (result)
1394 goto fail_platform; 1434 goto fail_platform;
1395 eeepc_enable_camera(eeepc); 1435 eeepc_enable_camera(eeepc);