diff options
| author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2007-04-21 10:08:31 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2007-04-21 23:30:33 -0400 |
| commit | 5fba344cfdbaa79e6320da26c3db34dfb219a845 (patch) | |
| tree | 7dd7629444f4ca95b469b56341b40268fad98aab | |
| parent | 132ce09123755ec5e3d3a8ae22f4f753c3baac97 (diff) | |
ACPI: thinkpad-acpi: clean up probing and move init to subdrivers
Move most of the probing code to its own function, and most of the
subdriver-specific init code into subdriver init functions.
This allows us to not define pci_handle unless the dock subdriver is
enabled, as well.
This patch causes a minor userland interface change: if a subdriver doesn't
detect a capability, /proc entries for it are not created anymore (as
opposed to a /proc entry that just returned "unsupported").
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/misc/thinkpad_acpi.c | 231 | ||||
| -rw-r--r-- | drivers/misc/thinkpad_acpi.h | 4 |
2 files changed, 151 insertions, 84 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 7fa906fd45c0..eeab39418c71 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
| @@ -277,9 +277,9 @@ static int _sta(acpi_handle handle) | |||
| 277 | * ACPI device model | 277 | * ACPI device model |
| 278 | */ | 278 | */ |
| 279 | 279 | ||
| 280 | static void __init ibm_handle_init(char *name, | 280 | static void ibm_handle_init(char *name, |
| 281 | acpi_handle * handle, acpi_handle parent, | 281 | acpi_handle *handle, acpi_handle parent, |
| 282 | char **paths, int num_paths, char **path) | 282 | char **paths, int num_paths, char **path) |
| 283 | { | 283 | { |
| 284 | int i; | 284 | int i; |
| 285 | acpi_status status; | 285 | acpi_status status; |
| @@ -351,8 +351,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
| 351 | 351 | ||
| 352 | ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); | 352 | ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); |
| 353 | if (!ibm->driver) { | 353 | if (!ibm->driver) { |
| 354 | printk(IBM_ERR "kmalloc(ibm->driver) failed\n"); | 354 | printk(IBM_ERR "kzalloc(ibm->driver) failed\n"); |
| 355 | return -1; | 355 | return -ENOMEM; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name); | 358 | sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name); |
| @@ -364,7 +364,9 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
| 364 | printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n", | 364 | printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n", |
| 365 | ibm->hid, ret); | 365 | ibm->hid, ret); |
| 366 | kfree(ibm->driver); | 366 | kfree(ibm->driver); |
| 367 | } | 367 | ibm->driver = NULL; |
| 368 | } else if (!ret) | ||
| 369 | ibm->driver_registered = 1; | ||
| 368 | 370 | ||
| 369 | return ret; | 371 | return ret; |
| 370 | } | 372 | } |
| @@ -495,6 +497,8 @@ static int hotkey_orig_mask; | |||
| 495 | 497 | ||
| 496 | static int hotkey_init(void) | 498 | static int hotkey_init(void) |
| 497 | { | 499 | { |
| 500 | IBM_HANDLE_INIT(hkey); | ||
| 501 | |||
| 498 | /* hotkey not supported on 570 */ | 502 | /* hotkey not supported on 570 */ |
| 499 | hotkey_supported = hkey_handle != NULL; | 503 | hotkey_supported = hkey_handle != NULL; |
| 500 | 504 | ||
| @@ -508,13 +512,14 @@ static int hotkey_init(void) | |||
| 508 | return -ENODEV; | 512 | return -ENODEV; |
| 509 | } | 513 | } |
| 510 | 514 | ||
| 511 | return 0; | 515 | return (hotkey_supported)? 0 : 1; |
| 512 | } | 516 | } |
| 513 | 517 | ||
| 514 | static void hotkey_exit(void) | 518 | static void hotkey_exit(void) |
| 515 | { | 519 | { |
| 516 | if (hotkey_supported) | 520 | if (hotkey_supported) { |
| 517 | hotkey_set(hotkey_orig_status, hotkey_orig_mask); | 521 | hotkey_set(hotkey_orig_status, hotkey_orig_mask); |
| 522 | } | ||
| 518 | } | 523 | } |
| 519 | 524 | ||
| 520 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) | 525 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) |
| @@ -628,12 +633,14 @@ static int bluetooth_supported; | |||
| 628 | 633 | ||
| 629 | static int bluetooth_init(void) | 634 | static int bluetooth_init(void) |
| 630 | { | 635 | { |
| 636 | IBM_HANDLE_INIT(hkey); | ||
| 637 | |||
| 631 | /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, | 638 | /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, |
| 632 | G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ | 639 | G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ |
| 633 | bluetooth_supported = hkey_handle && | 640 | bluetooth_supported = hkey_handle && |
| 634 | acpi_evalf(hkey_handle, NULL, "GBDC", "qv"); | 641 | acpi_evalf(hkey_handle, NULL, "GBDC", "qv"); |
| 635 | 642 | ||
| 636 | return 0; | 643 | return (bluetooth_supported)? 0 : 1; |
| 637 | } | 644 | } |
| 638 | 645 | ||
| 639 | static int bluetooth_status(void) | 646 | static int bluetooth_status(void) |
| @@ -697,10 +704,12 @@ static int wan_supported; | |||
| 697 | 704 | ||
| 698 | static int wan_init(void) | 705 | static int wan_init(void) |
| 699 | { | 706 | { |
| 707 | IBM_HANDLE_INIT(hkey); | ||
| 708 | |||
| 700 | wan_supported = hkey_handle && | 709 | wan_supported = hkey_handle && |
| 701 | acpi_evalf(hkey_handle, NULL, "GWAN", "qv"); | 710 | acpi_evalf(hkey_handle, NULL, "GWAN", "qv"); |
| 702 | 711 | ||
| 703 | return 0; | 712 | return (wan_supported)? 0 : 1; |
| 704 | } | 713 | } |
| 705 | 714 | ||
| 706 | static int wan_status(void) | 715 | static int wan_status(void) |
| @@ -775,6 +784,9 @@ static int video_init(void) | |||
| 775 | { | 784 | { |
| 776 | int ivga; | 785 | int ivga; |
| 777 | 786 | ||
| 787 | IBM_HANDLE_INIT(vid); | ||
| 788 | IBM_HANDLE_INIT(vid2); | ||
| 789 | |||
| 778 | if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) | 790 | if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) |
| 779 | /* G41, assume IVGA doesn't change */ | 791 | /* G41, assume IVGA doesn't change */ |
| 780 | vid_handle = vid2_handle; | 792 | vid_handle = vid2_handle; |
| @@ -792,7 +804,7 @@ static int video_init(void) | |||
| 792 | /* all others */ | 804 | /* all others */ |
| 793 | video_supported = TPACPI_VIDEO_NEW; | 805 | video_supported = TPACPI_VIDEO_NEW; |
| 794 | 806 | ||
| 795 | return 0; | 807 | return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1; |
| 796 | } | 808 | } |
| 797 | 809 | ||
| 798 | static void video_exit(void) | 810 | static void video_exit(void) |
| @@ -979,6 +991,10 @@ IBM_HANDLE(ledb, ec, "LEDB"); /* G4x */ | |||
| 979 | 991 | ||
| 980 | static int light_init(void) | 992 | static int light_init(void) |
| 981 | { | 993 | { |
| 994 | IBM_HANDLE_INIT(ledb); | ||
| 995 | IBM_HANDLE_INIT(lght); | ||
| 996 | IBM_HANDLE_INIT(cmos); | ||
| 997 | |||
| 982 | /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ | 998 | /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ |
| 983 | light_supported = (cmos_handle || lght_handle) && !ledb_handle; | 999 | light_supported = (cmos_handle || lght_handle) && !ledb_handle; |
| 984 | 1000 | ||
| @@ -988,7 +1004,7 @@ static int light_init(void) | |||
| 988 | light_status_supported = acpi_evalf(ec_handle, NULL, | 1004 | light_status_supported = acpi_evalf(ec_handle, NULL, |
| 989 | "KBLT", "qv"); | 1005 | "KBLT", "qv"); |
| 990 | 1006 | ||
| 991 | return 0; | 1007 | return (light_supported)? 0 : 1; |
| 992 | } | 1008 | } |
| 993 | 1009 | ||
| 994 | static int light_read(char *p) | 1010 | static int light_read(char *p) |
| @@ -1044,9 +1060,6 @@ static int light_write(char *buf) | |||
| 1044 | * Dock subdriver | 1060 | * Dock subdriver |
| 1045 | */ | 1061 | */ |
| 1046 | 1062 | ||
| 1047 | /* don't list other alternatives as we install a notify handler on the 570 */ | ||
| 1048 | IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ | ||
| 1049 | |||
| 1050 | #ifdef CONFIG_THINKPAD_ACPI_DOCK | 1063 | #ifdef CONFIG_THINKPAD_ACPI_DOCK |
| 1051 | 1064 | ||
| 1052 | IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ | 1065 | IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ |
| @@ -1055,8 +1068,19 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ | |||
| 1055 | "\\_SB.PCI.ISA.SLCE", /* 570 */ | 1068 | "\\_SB.PCI.ISA.SLCE", /* 570 */ |
| 1056 | ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ | 1069 | ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ |
| 1057 | 1070 | ||
| 1071 | /* don't list other alternatives as we install a notify handler on the 570 */ | ||
| 1072 | IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ | ||
| 1073 | |||
| 1058 | #define dock_docked() (_sta(dock_handle) & 1) | 1074 | #define dock_docked() (_sta(dock_handle) & 1) |
| 1059 | 1075 | ||
| 1076 | static int dock_init(void) | ||
| 1077 | { | ||
| 1078 | IBM_HANDLE_INIT(dock); | ||
| 1079 | IBM_HANDLE_INIT(pci); | ||
| 1080 | |||
| 1081 | return (dock_handle)? 0 : 1; | ||
| 1082 | } | ||
| 1083 | |||
| 1060 | static void dock_notify(struct ibm_struct *ibm, u32 event) | 1084 | static void dock_notify(struct ibm_struct *ibm, u32 event) |
| 1061 | { | 1085 | { |
| 1062 | int docked = dock_docked(); | 1086 | int docked = dock_docked(); |
| @@ -1147,6 +1171,13 @@ IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ | |||
| 1147 | 1171 | ||
| 1148 | static int bay_init(void) | 1172 | static int bay_init(void) |
| 1149 | { | 1173 | { |
| 1174 | IBM_HANDLE_INIT(bay); | ||
| 1175 | if (bay_handle) | ||
| 1176 | IBM_HANDLE_INIT(bay_ej); | ||
| 1177 | IBM_HANDLE_INIT(bay2); | ||
| 1178 | if (bay2_handle) | ||
| 1179 | IBM_HANDLE_INIT(bay2_ej); | ||
| 1180 | |||
| 1150 | bay_status_supported = bay_handle && | 1181 | bay_status_supported = bay_handle && |
| 1151 | acpi_evalf(bay_handle, NULL, "_STA", "qv"); | 1182 | acpi_evalf(bay_handle, NULL, "_STA", "qv"); |
| 1152 | bay_status2_supported = bay2_handle && | 1183 | bay_status2_supported = bay2_handle && |
| @@ -1157,7 +1188,8 @@ static int bay_init(void) | |||
| 1157 | bay_eject2_supported = bay2_handle && bay2_ej_handle && | 1188 | bay_eject2_supported = bay2_handle && bay2_ej_handle && |
| 1158 | (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); | 1189 | (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); |
| 1159 | 1190 | ||
| 1160 | return 0; | 1191 | return (bay_status_supported || bay_eject_supported || |
| 1192 | bay_status2_supported || bay_eject2_supported)? 0 : 1; | ||
| 1161 | } | 1193 | } |
| 1162 | 1194 | ||
| 1163 | static void bay_notify(struct ibm_struct *ibm, u32 event) | 1195 | static void bay_notify(struct ibm_struct *ibm, u32 event) |
| @@ -1221,6 +1253,13 @@ static int bay_write(char *buf) | |||
| 1221 | * CMOS subdriver | 1253 | * CMOS subdriver |
| 1222 | */ | 1254 | */ |
| 1223 | 1255 | ||
| 1256 | static int cmos_init(void) | ||
| 1257 | { | ||
| 1258 | IBM_HANDLE_INIT(cmos); | ||
| 1259 | |||
| 1260 | return (cmos_handle)? 0 : 1; | ||
| 1261 | } | ||
| 1262 | |||
| 1224 | static int cmos_eval(int cmos_cmd) | 1263 | static int cmos_eval(int cmos_cmd) |
| 1225 | { | 1264 | { |
| 1226 | if (cmos_handle) | 1265 | if (cmos_handle) |
| @@ -1281,6 +1320,8 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */ | |||
| 1281 | 1320 | ||
| 1282 | static int led_init(void) | 1321 | static int led_init(void) |
| 1283 | { | 1322 | { |
| 1323 | IBM_HANDLE_INIT(led); | ||
| 1324 | |||
| 1284 | if (!led_handle) | 1325 | if (!led_handle) |
| 1285 | /* led not supported on R30, R31 */ | 1326 | /* led not supported on R30, R31 */ |
| 1286 | led_supported = TPACPI_LED_NONE; | 1327 | led_supported = TPACPI_LED_NONE; |
| @@ -1294,7 +1335,7 @@ static int led_init(void) | |||
| 1294 | /* all others */ | 1335 | /* all others */ |
| 1295 | led_supported = TPACPI_LED_NEW; | 1336 | led_supported = TPACPI_LED_NEW; |
| 1296 | 1337 | ||
| 1297 | return 0; | 1338 | return (led_supported != TPACPI_LED_NONE)? 0 : 1; |
| 1298 | } | 1339 | } |
| 1299 | 1340 | ||
| 1300 | #define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking")) | 1341 | #define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking")) |
| @@ -1391,6 +1432,13 @@ static int led_write(char *buf) | |||
| 1391 | 1432 | ||
| 1392 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ | 1433 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ |
| 1393 | 1434 | ||
| 1435 | static int beep_init(void) | ||
| 1436 | { | ||
| 1437 | IBM_HANDLE_INIT(beep); | ||
| 1438 | |||
| 1439 | return (beep_handle)? 0 : 1; | ||
| 1440 | } | ||
| 1441 | |||
| 1394 | static int beep_read(char *p) | 1442 | static int beep_read(char *p) |
| 1395 | { | 1443 | { |
| 1396 | int len = 0; | 1444 | int len = 0; |
| @@ -1436,7 +1484,9 @@ static int thermal_init(void) | |||
| 1436 | { | 1484 | { |
| 1437 | u8 t, ta1, ta2; | 1485 | u8 t, ta1, ta2; |
| 1438 | int i; | 1486 | int i; |
| 1439 | int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); | 1487 | int acpi_tmp7; |
| 1488 | |||
| 1489 | acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); | ||
| 1440 | 1490 | ||
| 1441 | if (ibm_thinkpad_ec_found && experimental) { | 1491 | if (ibm_thinkpad_ec_found && experimental) { |
| 1442 | /* | 1492 | /* |
| @@ -1492,7 +1542,7 @@ static int thermal_init(void) | |||
| 1492 | thermal_read_mode = TPACPI_THERMAL_NONE; | 1542 | thermal_read_mode = TPACPI_THERMAL_NONE; |
| 1493 | } | 1543 | } |
| 1494 | 1544 | ||
| 1495 | return 0; | 1545 | return (thermal_read_mode != TPACPI_THERMAL_NONE)? 0 : 1; |
| 1496 | } | 1546 | } |
| 1497 | 1547 | ||
| 1498 | static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) | 1548 | static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) |
| @@ -1973,6 +2023,10 @@ static int fan_init(void) | |||
| 1973 | fan_control_status_known = 1; | 2023 | fan_control_status_known = 1; |
| 1974 | fan_watchdog_maxinterval = 0; | 2024 | fan_watchdog_maxinterval = 0; |
| 1975 | 2025 | ||
| 2026 | IBM_HANDLE_INIT(fans); | ||
| 2027 | IBM_HANDLE_INIT(gfan); | ||
| 2028 | IBM_HANDLE_INIT(sfan); | ||
| 2029 | |||
| 1976 | if (gfan_handle) { | 2030 | if (gfan_handle) { |
| 1977 | /* 570, 600e/x, 770e, 770x */ | 2031 | /* 570, 600e/x, 770e, 770x */ |
| 1978 | fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; | 2032 | fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; |
| @@ -2010,7 +2064,7 @@ static int fan_init(void) | |||
| 2010 | printk(IBM_ERR | 2064 | printk(IBM_ERR |
| 2011 | "ThinkPad ACPI EC access misbehaving, " | 2065 | "ThinkPad ACPI EC access misbehaving, " |
| 2012 | "fan status and control unavailable\n"); | 2066 | "fan status and control unavailable\n"); |
| 2013 | return 0; | 2067 | return 1; |
| 2014 | } | 2068 | } |
| 2015 | } | 2069 | } |
| 2016 | 2070 | ||
| @@ -2041,7 +2095,9 @@ static int fan_init(void) | |||
| 2041 | } | 2095 | } |
| 2042 | } | 2096 | } |
| 2043 | 2097 | ||
| 2044 | return 0; | 2098 | return (fan_status_access_mode != TPACPI_FAN_NONE || |
| 2099 | fan_control_access_mode != TPACPI_FAN_WR_NONE)? | ||
| 2100 | 0 : 1; | ||
| 2045 | } | 2101 | } |
| 2046 | 2102 | ||
| 2047 | static int fan_get_status(u8 *status) | 2103 | static int fan_get_status(u8 *status) |
| @@ -2485,6 +2541,7 @@ static struct ibm_struct ibms[] = { | |||
| 2485 | #ifdef CONFIG_THINKPAD_ACPI_DOCK | 2541 | #ifdef CONFIG_THINKPAD_ACPI_DOCK |
| 2486 | { | 2542 | { |
| 2487 | .name = "dock", | 2543 | .name = "dock", |
| 2544 | .init = dock_init, | ||
| 2488 | .read = dock_read, | 2545 | .read = dock_read, |
| 2489 | .write = dock_write, | 2546 | .write = dock_write, |
| 2490 | .notify = dock_notify, | 2547 | .notify = dock_notify, |
| @@ -2512,6 +2569,7 @@ static struct ibm_struct ibms[] = { | |||
| 2512 | #endif /* CONFIG_THINKPAD_ACPI_BAY */ | 2569 | #endif /* CONFIG_THINKPAD_ACPI_BAY */ |
| 2513 | { | 2570 | { |
| 2514 | .name = "cmos", | 2571 | .name = "cmos", |
| 2572 | .init = cmos_init, | ||
| 2515 | .read = cmos_read, | 2573 | .read = cmos_read, |
| 2516 | .write = cmos_write, | 2574 | .write = cmos_write, |
| 2517 | }, | 2575 | }, |
| @@ -2523,6 +2581,7 @@ static struct ibm_struct ibms[] = { | |||
| 2523 | }, | 2581 | }, |
| 2524 | { | 2582 | { |
| 2525 | .name = "beep", | 2583 | .name = "beep", |
| 2584 | .init = beep_init, | ||
| 2526 | .read = beep_read, | 2585 | .read = beep_read, |
| 2527 | .write = beep_write, | 2586 | .write = beep_write, |
| 2528 | }, | 2587 | }, |
| @@ -2571,20 +2630,33 @@ static int __init ibm_init(struct ibm_struct *ibm) | |||
| 2571 | if (ibm->experimental && !experimental) | 2630 | if (ibm->experimental && !experimental) |
| 2572 | return 0; | 2631 | return 0; |
| 2573 | 2632 | ||
| 2574 | if (ibm->hid) { | ||
| 2575 | ret = register_tpacpi_subdriver(ibm); | ||
| 2576 | if (ret < 0) | ||
| 2577 | return ret; | ||
| 2578 | ibm->driver_registered = 1; | ||
| 2579 | } | ||
| 2580 | |||
| 2581 | if (ibm->init) { | 2633 | if (ibm->init) { |
| 2582 | ret = ibm->init(); | 2634 | ret = ibm->init(); |
| 2583 | if (ret != 0) | 2635 | if (ret > 0) |
| 2636 | return 0; /* probe failed */ | ||
| 2637 | if (ret) | ||
| 2584 | return ret; | 2638 | return ret; |
| 2585 | ibm->init_called = 1; | 2639 | ibm->init_called = 1; |
| 2586 | } | 2640 | } |
| 2587 | 2641 | ||
| 2642 | if (ibm->hid) { | ||
| 2643 | ret = register_tpacpi_subdriver(ibm); | ||
| 2644 | if (ret) | ||
| 2645 | goto err_out; | ||
| 2646 | } | ||
| 2647 | |||
| 2648 | if (ibm->notify) { | ||
| 2649 | ret = setup_notify(ibm); | ||
| 2650 | if (ret == -ENODEV) { | ||
| 2651 | printk(IBM_NOTICE "disabling subdriver %s\n", | ||
| 2652 | ibm->name); | ||
| 2653 | ret = 0; | ||
| 2654 | goto err_out; | ||
| 2655 | } | ||
| 2656 | if (ret < 0) | ||
| 2657 | goto err_out; | ||
| 2658 | } | ||
| 2659 | |||
| 2588 | if (ibm->read) { | 2660 | if (ibm->read) { |
| 2589 | entry = create_proc_entry(ibm->name, | 2661 | entry = create_proc_entry(ibm->name, |
| 2590 | S_IFREG | S_IRUGO | S_IWUSR, | 2662 | S_IFREG | S_IRUGO | S_IWUSR, |
| @@ -2592,7 +2664,8 @@ static int __init ibm_init(struct ibm_struct *ibm) | |||
| 2592 | if (!entry) { | 2664 | if (!entry) { |
| 2593 | printk(IBM_ERR "unable to create proc entry %s\n", | 2665 | printk(IBM_ERR "unable to create proc entry %s\n", |
| 2594 | ibm->name); | 2666 | ibm->name); |
| 2595 | return -ENODEV; | 2667 | ret = -ENODEV; |
| 2668 | goto err_out; | ||
| 2596 | } | 2669 | } |
| 2597 | entry->owner = THIS_MODULE; | 2670 | entry->owner = THIS_MODULE; |
| 2598 | entry->data = ibm; | 2671 | entry->data = ibm; |
| @@ -2602,36 +2675,36 @@ static int __init ibm_init(struct ibm_struct *ibm) | |||
| 2602 | ibm->proc_created = 1; | 2675 | ibm->proc_created = 1; |
| 2603 | } | 2676 | } |
| 2604 | 2677 | ||
| 2605 | if (ibm->notify) { | ||
| 2606 | ret = setup_notify(ibm); | ||
| 2607 | if (ret == -ENODEV) { | ||
| 2608 | printk(IBM_NOTICE "disabling subdriver %s\n", | ||
| 2609 | ibm->name); | ||
| 2610 | ibm_exit(ibm); | ||
| 2611 | return 0; | ||
| 2612 | } | ||
| 2613 | if (ret < 0) | ||
| 2614 | return ret; | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | return 0; | 2678 | return 0; |
| 2679 | |||
| 2680 | err_out: | ||
| 2681 | ibm_exit(ibm); | ||
| 2682 | return (ret < 0)? ret : 0; | ||
| 2618 | } | 2683 | } |
| 2619 | 2684 | ||
| 2620 | static void ibm_exit(struct ibm_struct *ibm) | 2685 | static void ibm_exit(struct ibm_struct *ibm) |
| 2621 | { | 2686 | { |
| 2622 | if (ibm->notify_installed) | 2687 | if (ibm->notify_installed) { |
| 2623 | acpi_remove_notify_handler(*ibm->handle, ibm->type, | 2688 | acpi_remove_notify_handler(*ibm->handle, ibm->type, |
| 2624 | dispatch_notify); | 2689 | dispatch_notify); |
| 2690 | ibm->notify_installed = 0; | ||
| 2691 | } | ||
| 2625 | 2692 | ||
| 2626 | if (ibm->proc_created) | 2693 | if (ibm->proc_created) { |
| 2627 | remove_proc_entry(ibm->name, proc_dir); | 2694 | remove_proc_entry(ibm->name, proc_dir); |
| 2628 | 2695 | ibm->proc_created = 0; | |
| 2629 | if (ibm->init_called && ibm->exit) | 2696 | } |
| 2630 | ibm->exit(); | ||
| 2631 | 2697 | ||
| 2632 | if (ibm->driver_registered) { | 2698 | if (ibm->driver_registered) { |
| 2633 | acpi_bus_unregister_driver(ibm->driver); | 2699 | acpi_bus_unregister_driver(ibm->driver); |
| 2634 | kfree(ibm->driver); | 2700 | kfree(ibm->driver); |
| 2701 | ibm->driver = NULL; | ||
| 2702 | ibm->driver_registered = 0; | ||
| 2703 | } | ||
| 2704 | |||
| 2705 | if (ibm->init_called && ibm->exit) { | ||
| 2706 | ibm->exit(); | ||
| 2707 | ibm->init_called = 0; | ||
| 2635 | } | 2708 | } |
| 2636 | } | 2709 | } |
| 2637 | 2710 | ||
| @@ -2663,6 +2736,32 @@ static char* __init check_dmi_for_ec(void) | |||
| 2663 | return NULL; | 2736 | return NULL; |
| 2664 | } | 2737 | } |
| 2665 | 2738 | ||
| 2739 | static int __init probe_for_thinkpad(void) | ||
| 2740 | { | ||
| 2741 | int is_thinkpad; | ||
| 2742 | |||
| 2743 | if (acpi_disabled) | ||
| 2744 | return -ENODEV; | ||
| 2745 | |||
| 2746 | /* | ||
| 2747 | * Non-ancient models have better DMI tagging, but very old models | ||
| 2748 | * don't. | ||
| 2749 | */ | ||
| 2750 | is_thinkpad = dmi_name_in_vendors("ThinkPad"); | ||
| 2751 | |||
| 2752 | /* ec is required because many other handles are relative to it */ | ||
| 2753 | IBM_HANDLE_INIT(ec); | ||
| 2754 | if (!ec_handle) { | ||
| 2755 | if (is_thinkpad) | ||
| 2756 | printk(IBM_ERR | ||
| 2757 | "Not yet supported ThinkPad detected!\n"); | ||
| 2758 | return -ENODEV; | ||
| 2759 | } | ||
| 2760 | |||
| 2761 | return 0; | ||
| 2762 | } | ||
| 2763 | |||
| 2764 | |||
| 2666 | /* Module init, exit, parameters */ | 2765 | /* Module init, exit, parameters */ |
| 2667 | 2766 | ||
| 2668 | static int __init set_ibm_param(const char *val, struct kernel_param *kp) | 2767 | static int __init set_ibm_param(const char *val, struct kernel_param *kp) |
| @@ -2712,45 +2811,13 @@ static int __init thinkpad_acpi_module_init(void) | |||
| 2712 | { | 2811 | { |
| 2713 | int ret, i; | 2812 | int ret, i; |
| 2714 | 2813 | ||
| 2715 | if (acpi_disabled) | 2814 | ret = probe_for_thinkpad(); |
| 2716 | return -ENODEV; | 2815 | if (ret) |
| 2816 | return ret; | ||
| 2717 | 2817 | ||
| 2718 | /* ec is required because many other handles are relative to it */ | ||
| 2719 | IBM_HANDLE_INIT(ec); | ||
| 2720 | if (!ec_handle) { | ||
| 2721 | printk(IBM_ERR "ec object not found\n"); | ||
| 2722 | return -ENODEV; | ||
| 2723 | } | ||
| 2724 | |||
| 2725 | /* Models with newer firmware report the EC in DMI */ | ||
| 2726 | ibm_thinkpad_ec_found = check_dmi_for_ec(); | 2818 | ibm_thinkpad_ec_found = check_dmi_for_ec(); |
| 2727 | |||
| 2728 | /* these handles are not required */ | ||
| 2729 | IBM_HANDLE_INIT(vid); | ||
| 2730 | IBM_HANDLE_INIT(vid2); | ||
| 2731 | IBM_HANDLE_INIT(ledb); | ||
| 2732 | IBM_HANDLE_INIT(led); | ||
| 2733 | IBM_HANDLE_INIT(hkey); | ||
| 2734 | IBM_HANDLE_INIT(lght); | ||
| 2735 | IBM_HANDLE_INIT(cmos); | ||
| 2736 | #ifdef CONFIG_THINKPAD_ACPI_DOCK | ||
| 2737 | IBM_HANDLE_INIT(dock); | ||
| 2738 | #endif | ||
| 2739 | IBM_HANDLE_INIT(pci); | ||
| 2740 | #ifdef CONFIG_THINKPAD_ACPI_BAY | ||
| 2741 | IBM_HANDLE_INIT(bay); | ||
| 2742 | if (bay_handle) | ||
| 2743 | IBM_HANDLE_INIT(bay_ej); | ||
| 2744 | IBM_HANDLE_INIT(bay2); | ||
| 2745 | if (bay2_handle) | ||
| 2746 | IBM_HANDLE_INIT(bay2_ej); | ||
| 2747 | #endif /* CONFIG_THINKPAD_ACPI_BAY */ | ||
| 2748 | IBM_HANDLE_INIT(beep); | ||
| 2749 | IBM_HANDLE_INIT(ecrd); | 2819 | IBM_HANDLE_INIT(ecrd); |
| 2750 | IBM_HANDLE_INIT(ecwr); | 2820 | IBM_HANDLE_INIT(ecwr); |
| 2751 | IBM_HANDLE_INIT(fans); | ||
| 2752 | IBM_HANDLE_INIT(gfan); | ||
| 2753 | IBM_HANDLE_INIT(sfan); | ||
| 2754 | 2821 | ||
| 2755 | proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir); | 2822 | proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir); |
| 2756 | if (!proc_dir) { | 2823 | if (!proc_dir) { |
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index b2348d7a07c4..06d4c3839afd 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
| @@ -104,7 +104,7 @@ static acpi_handle ecrd_handle, ecwr_handle; /* 570 EC access */ | |||
| 104 | static acpi_handle cmos_handle, hkey_handle; /* basic thinkpad handles */ | 104 | static acpi_handle cmos_handle, hkey_handle; /* basic thinkpad handles */ |
| 105 | 105 | ||
| 106 | static void ibm_handle_init(char *name, | 106 | static void ibm_handle_init(char *name, |
| 107 | acpi_handle * handle, acpi_handle parent, | 107 | acpi_handle *handle, acpi_handle parent, |
| 108 | char **paths, int num_paths, char **path); | 108 | char **paths, int num_paths, char **path); |
| 109 | #define IBM_HANDLE_INIT(object) \ | 109 | #define IBM_HANDLE_INIT(object) \ |
| 110 | ibm_handle_init(#object, &object##_handle, *object##_parent, \ | 110 | ibm_handle_init(#object, &object##_handle, *object##_parent, \ |
| @@ -242,8 +242,8 @@ static int cmos_write(char *buf); | |||
| 242 | * Dock subdriver | 242 | * Dock subdriver |
| 243 | */ | 243 | */ |
| 244 | 244 | ||
| 245 | static acpi_handle pci_handle; | ||
| 246 | #ifdef CONFIG_THINKPAD_ACPI_DOCK | 245 | #ifdef CONFIG_THINKPAD_ACPI_DOCK |
| 246 | static acpi_handle pci_handle; | ||
| 247 | static acpi_handle dock_handle; | 247 | static acpi_handle dock_handle; |
| 248 | 248 | ||
| 249 | static void dock_notify(struct ibm_struct *ibm, u32 event); | 249 | static void dock_notify(struct ibm_struct *ibm, u32 event); |
