diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-04 17:59:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-04 17:59:53 -0400 |
commit | 5001f861219a082e6a64ae61fccea2272bc6751a (patch) | |
tree | 83902964d005b026b9f450ff1d7ae6d6d964373b | |
parent | 663cc813a8da4dcc35043998c8856e6ff2ee48fd (diff) | |
parent | c7db7ba5fc84e76044f403efbbba3af5fb01d19b (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
ACPI: EC: Don't parse DSDT for EC early init on Compal
ACPI: EC: Rewrite DMI checks
ACPI: dock: fix "sibiling" typo
ACPI: kill overly verbose "throttling states" log messages
ACPI: Fix bound checks for copy_from_user in the acpi /proc code
ACPI: fix bus scanning memory leaks
ACPI: EC: Restart command even if no interrupts from EC
sony-laptop: Don't unregister the SPIC driver if it wasn't registered
sony-laptop: remove _INI call at init time
sony-laptop: SPIC unset IRQF_SHARED, set IRQF_DISABLED
sony-laptop: remove device_ctrl and the SPIC mini drivers
-rw-r--r-- | drivers/acpi/dock.c | 16 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 56 | ||||
-rw-r--r-- | drivers/acpi/proc.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 7 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 7 | ||||
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 127 |
6 files changed, 112 insertions, 103 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3a2cfefc71ab..7338b6a3e049 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -67,7 +67,7 @@ struct dock_station { | |||
67 | struct list_head dependent_devices; | 67 | struct list_head dependent_devices; |
68 | struct list_head hotplug_devices; | 68 | struct list_head hotplug_devices; |
69 | 69 | ||
70 | struct list_head sibiling; | 70 | struct list_head sibling; |
71 | struct platform_device *dock_device; | 71 | struct platform_device *dock_device; |
72 | }; | 72 | }; |
73 | static LIST_HEAD(dock_stations); | 73 | static LIST_HEAD(dock_stations); |
@@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle) | |||
275 | 275 | ||
276 | if (is_dock(handle)) | 276 | if (is_dock(handle)) |
277 | return 1; | 277 | return 1; |
278 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 278 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
279 | if (find_dock_dependent_device(dock_station, handle)) | 279 | if (find_dock_dependent_device(dock_station, handle)) |
280 | return 1; | 280 | return 1; |
281 | } | 281 | } |
@@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, | |||
619 | * make sure this handle is for a device dependent on the dock, | 619 | * make sure this handle is for a device dependent on the dock, |
620 | * this would include the dock station itself | 620 | * this would include the dock station itself |
621 | */ | 621 | */ |
622 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 622 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
623 | /* | 623 | /* |
624 | * An ATA bay can be in a dock and itself can be ejected | 624 | * An ATA bay can be in a dock and itself can be ejected |
625 | * seperately, so there are two 'dock stations' which need the | 625 | * seperately, so there are two 'dock stations' which need the |
@@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle) | |||
651 | if (!dock_station_count) | 651 | if (!dock_station_count) |
652 | return; | 652 | return; |
653 | 653 | ||
654 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 654 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
655 | dd = find_dock_dependent_device(dock_station, handle); | 655 | dd = find_dock_dependent_device(dock_station, handle); |
656 | if (dd) | 656 | if (dd) |
657 | dock_del_hotplug_device(dock_station, dd); | 657 | dock_del_hotplug_device(dock_station, dd); |
@@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this, | |||
787 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 787 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
788 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 788 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
789 | return 0; | 789 | return 0; |
790 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 790 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
791 | if (dock_station->handle == handle) { | 791 | if (dock_station->handle == handle) { |
792 | struct dock_data *dock_data; | 792 | struct dock_data *dock_data; |
793 | 793 | ||
@@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle) | |||
958 | dock_station->last_dock_time = jiffies - HZ; | 958 | dock_station->last_dock_time = jiffies - HZ; |
959 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 959 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
960 | INIT_LIST_HEAD(&dock_station->hotplug_devices); | 960 | INIT_LIST_HEAD(&dock_station->hotplug_devices); |
961 | INIT_LIST_HEAD(&dock_station->sibiling); | 961 | INIT_LIST_HEAD(&dock_station->sibling); |
962 | spin_lock_init(&dock_station->dd_lock); | 962 | spin_lock_init(&dock_station->dd_lock); |
963 | mutex_init(&dock_station->hp_lock); | 963 | mutex_init(&dock_station->hp_lock); |
964 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 964 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
@@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle) | |||
1044 | add_dock_dependent_device(dock_station, dd); | 1044 | add_dock_dependent_device(dock_station, dd); |
1045 | 1045 | ||
1046 | dock_station_count++; | 1046 | dock_station_count++; |
1047 | list_add(&dock_station->sibiling, &dock_stations); | 1047 | list_add(&dock_station->sibling, &dock_stations); |
1048 | return 0; | 1048 | return 0; |
1049 | 1049 | ||
1050 | dock_add_err_unregister: | 1050 | dock_add_err_unregister: |
@@ -1149,7 +1149,7 @@ static void __exit dock_exit(void) | |||
1149 | struct dock_station *tmp; | 1149 | struct dock_station *tmp; |
1150 | 1150 | ||
1151 | unregister_acpi_bus_notifier(&dock_acpi_notifier); | 1151 | unregister_acpi_bus_notifier(&dock_acpi_notifier); |
1152 | list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling) | 1152 | list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) |
1153 | dock_remove(dock_station); | 1153 | dock_remove(dock_station); |
1154 | } | 1154 | } |
1155 | 1155 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f70796081c4c..baef28c1e630 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -119,6 +119,8 @@ static struct acpi_ec { | |||
119 | } *boot_ec, *first_ec; | 119 | } *boot_ec, *first_ec; |
120 | 120 | ||
121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
122 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | ||
123 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | ||
122 | 124 | ||
123 | /* -------------------------------------------------------------------------- | 125 | /* -------------------------------------------------------------------------- |
124 | Transaction Management | 126 | Transaction Management |
@@ -232,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec) | |||
232 | } | 234 | } |
233 | advance_transaction(ec, acpi_ec_read_status(ec)); | 235 | advance_transaction(ec, acpi_ec_read_status(ec)); |
234 | } while (time_before(jiffies, delay)); | 236 | } while (time_before(jiffies, delay)); |
235 | if (!ec->curr->irq_count || | 237 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) |
236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
237 | break; | 238 | break; |
238 | /* try restart command if we get any false interrupts */ | ||
239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 239 | pr_debug(PREFIX "controller reset, restart transaction\n"); |
240 | spin_lock_irqsave(&ec->curr_lock, flags); | 240 | spin_lock_irqsave(&ec->curr_lock, flags); |
241 | start_transaction(ec); | 241 | start_transaction(ec); |
@@ -899,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
899 | {"", 0}, | 899 | {"", 0}, |
900 | }; | 900 | }; |
901 | 901 | ||
902 | /* Some BIOS do not survive early DSDT scan, skip it */ | ||
903 | static int ec_skip_dsdt_scan(const struct dmi_system_id *id) | ||
904 | { | ||
905 | EC_FLAGS_SKIP_DSDT_SCAN = 1; | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | /* ASUStek often supplies us with broken ECDT, validate it */ | ||
910 | static int ec_validate_ecdt(const struct dmi_system_id *id) | ||
911 | { | ||
912 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | /* MSI EC needs special treatment, enable it */ | ||
917 | static int ec_flag_msi(const struct dmi_system_id *id) | ||
918 | { | ||
919 | EC_FLAGS_MSI = 1; | ||
920 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static struct dmi_system_id __initdata ec_dmi_table[] = { | ||
925 | { | ||
926 | ec_skip_dsdt_scan, "Compal JFL92", { | ||
927 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
928 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, | ||
929 | { | ||
930 | ec_flag_msi, "MSI hardware", { | ||
931 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), | ||
932 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, | ||
933 | { | ||
934 | ec_validate_ecdt, "ASUS hardware", { | ||
935 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | ||
936 | {}, | ||
937 | }; | ||
938 | |||
939 | |||
902 | int __init acpi_ec_ecdt_probe(void) | 940 | int __init acpi_ec_ecdt_probe(void) |
903 | { | 941 | { |
904 | acpi_status status; | 942 | acpi_status status; |
@@ -911,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
911 | /* | 949 | /* |
912 | * Generate a boot ec context | 950 | * Generate a boot ec context |
913 | */ | 951 | */ |
914 | if (dmi_name_in_vendors("Micro-Star") || | 952 | dmi_check_system(ec_dmi_table); |
915 | dmi_name_in_vendors("Notebook")) { | ||
916 | pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); | ||
917 | EC_FLAGS_MSI = 1; | ||
918 | } | ||
919 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 953 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
920 | (struct acpi_table_header **)&ecdt_ptr); | 954 | (struct acpi_table_header **)&ecdt_ptr); |
921 | if (ACPI_SUCCESS(status)) { | 955 | if (ACPI_SUCCESS(status)) { |
@@ -926,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
926 | boot_ec->handle = ACPI_ROOT_OBJECT; | 960 | boot_ec->handle = ACPI_ROOT_OBJECT; |
927 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 961 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
928 | /* Don't trust ECDT, which comes from ASUSTek */ | 962 | /* Don't trust ECDT, which comes from ASUSTek */ |
929 | if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) | 963 | if (!EC_FLAGS_VALIDATE_ECDT) |
930 | goto install; | 964 | goto install; |
931 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 965 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
932 | if (!saved_ec) | 966 | if (!saved_ec) |
@@ -934,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void) | |||
934 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); | 968 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); |
935 | /* fall through */ | 969 | /* fall through */ |
936 | } | 970 | } |
971 | |||
972 | if (EC_FLAGS_SKIP_DSDT_SCAN) | ||
973 | return -ENODEV; | ||
974 | |||
937 | /* This workaround is needed only on some broken machines, | 975 | /* This workaround is needed only on some broken machines, |
938 | * which require early EC, but fail to provide ECDT */ | 976 | * which require early EC, but fail to provide ECDT */ |
939 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 977 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index d0d550d22a6d..f8b6f555ba52 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -398,6 +398,8 @@ acpi_system_write_wakeup_device(struct file *file, | |||
398 | 398 | ||
399 | if (len > 4) | 399 | if (len > 4) |
400 | len = 4; | 400 | len = 4; |
401 | if (len < 0) | ||
402 | return -EFAULT; | ||
401 | 403 | ||
402 | if (copy_from_user(strbuf, buffer, len)) | 404 | if (copy_from_user(strbuf, buffer, len)) |
403 | return -EFAULT; | 405 | return -EFAULT; |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c2d4d6e09364..c567b46dfa0f 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -863,13 +863,6 @@ static int acpi_processor_add(struct acpi_device *device) | |||
863 | goto err_remove_sysfs; | 863 | goto err_remove_sysfs; |
864 | } | 864 | } |
865 | 865 | ||
866 | if (pr->flags.throttling) { | ||
867 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
868 | acpi_device_name(device), acpi_device_bid(device)); | ||
869 | printk(" %d throttling states", pr->throttling.state_count); | ||
870 | printk(")\n"); | ||
871 | } | ||
872 | |||
873 | return 0; | 866 | return 0; |
874 | 867 | ||
875 | err_remove_sysfs: | 868 | err_remove_sysfs: |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 468921bed22f..14a7481c97d7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1052,6 +1052,8 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
1052 | device->flags.bus_address = 1; | 1052 | device->flags.bus_address = 1; |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | kfree(info); | ||
1056 | |||
1055 | /* | 1057 | /* |
1056 | * Some devices don't reliably have _HIDs & _CIDs, so add | 1058 | * Some devices don't reliably have _HIDs & _CIDs, so add |
1057 | * synthetic HIDs to make sure drivers can find them. | 1059 | * synthetic HIDs to make sure drivers can find them. |
@@ -1325,13 +1327,8 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, | |||
1325 | struct acpi_device **child) | 1327 | struct acpi_device **child) |
1326 | { | 1328 | { |
1327 | acpi_status status; | 1329 | acpi_status status; |
1328 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1329 | void *device = NULL; | 1330 | void *device = NULL; |
1330 | 1331 | ||
1331 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1332 | printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n", | ||
1333 | (char *) buffer.pointer); | ||
1334 | |||
1335 | status = acpi_bus_check_add(handle, 0, ops, &device); | 1332 | status = acpi_bus_check_add(handle, 0, ops, &device); |
1336 | if (ACPI_SUCCESS(status)) | 1333 | if (ACPI_SUCCESS(status)) |
1337 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1334 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index afdbdaaf80cb..a2a742c8ff7e 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -1211,15 +1211,6 @@ static int sony_nc_add(struct acpi_device *device) | |||
1211 | } | 1211 | } |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 | ||
1215 | * should be respected as we already checked for the device presence above */ | ||
1216 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { | ||
1217 | dprintk("Invoking _INI\n"); | ||
1218 | if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, | ||
1219 | NULL, NULL))) | ||
1220 | dprintk("_INI Method failed\n"); | ||
1221 | } | ||
1222 | |||
1223 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", | 1214 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", |
1224 | &handle))) { | 1215 | &handle))) { |
1225 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) | 1216 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) |
@@ -1399,27 +1390,20 @@ struct sonypi_eventtypes { | |||
1399 | struct sonypi_event *events; | 1390 | struct sonypi_event *events; |
1400 | }; | 1391 | }; |
1401 | 1392 | ||
1402 | struct device_ctrl { | 1393 | struct sony_pic_dev { |
1394 | struct acpi_device *acpi_dev; | ||
1395 | struct sony_pic_irq *cur_irq; | ||
1396 | struct sony_pic_ioport *cur_ioport; | ||
1397 | struct list_head interrupts; | ||
1398 | struct list_head ioports; | ||
1399 | struct mutex lock; | ||
1400 | struct sonypi_eventtypes *event_types; | ||
1401 | int (*handle_irq)(const u8, const u8); | ||
1403 | int model; | 1402 | int model; |
1404 | int (*handle_irq)(const u8, const u8); | ||
1405 | u16 evport_offset; | 1403 | u16 evport_offset; |
1406 | u8 has_camera; | 1404 | u8 camera_power; |
1407 | u8 has_bluetooth; | 1405 | u8 bluetooth_power; |
1408 | u8 has_wwan; | 1406 | u8 wwan_power; |
1409 | struct sonypi_eventtypes *event_types; | ||
1410 | }; | ||
1411 | |||
1412 | struct sony_pic_dev { | ||
1413 | struct device_ctrl *control; | ||
1414 | struct acpi_device *acpi_dev; | ||
1415 | struct sony_pic_irq *cur_irq; | ||
1416 | struct sony_pic_ioport *cur_ioport; | ||
1417 | struct list_head interrupts; | ||
1418 | struct list_head ioports; | ||
1419 | struct mutex lock; | ||
1420 | u8 camera_power; | ||
1421 | u8 bluetooth_power; | ||
1422 | u8 wwan_power; | ||
1423 | }; | 1407 | }; |
1424 | 1408 | ||
1425 | static struct sony_pic_dev spic_dev = { | 1409 | static struct sony_pic_dev spic_dev = { |
@@ -1427,6 +1411,8 @@ static struct sony_pic_dev spic_dev = { | |||
1427 | .ioports = LIST_HEAD_INIT(spic_dev.ioports), | 1411 | .ioports = LIST_HEAD_INIT(spic_dev.ioports), |
1428 | }; | 1412 | }; |
1429 | 1413 | ||
1414 | static int spic_drv_registered; | ||
1415 | |||
1430 | /* Event masks */ | 1416 | /* Event masks */ |
1431 | #define SONYPI_JOGGER_MASK 0x00000001 | 1417 | #define SONYPI_JOGGER_MASK 0x00000001 |
1432 | #define SONYPI_CAPTURE_MASK 0x00000002 | 1418 | #define SONYPI_CAPTURE_MASK 0x00000002 |
@@ -1724,27 +1710,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev) | |||
1724 | return 1; | 1710 | return 1; |
1725 | } | 1711 | } |
1726 | 1712 | ||
1727 | static struct device_ctrl spic_types[] = { | ||
1728 | { | ||
1729 | .model = SONYPI_DEVICE_TYPE1, | ||
1730 | .handle_irq = NULL, | ||
1731 | .evport_offset = SONYPI_TYPE1_OFFSET, | ||
1732 | .event_types = type1_events, | ||
1733 | }, | ||
1734 | { | ||
1735 | .model = SONYPI_DEVICE_TYPE2, | ||
1736 | .handle_irq = NULL, | ||
1737 | .evport_offset = SONYPI_TYPE2_OFFSET, | ||
1738 | .event_types = type2_events, | ||
1739 | }, | ||
1740 | { | ||
1741 | .model = SONYPI_DEVICE_TYPE3, | ||
1742 | .handle_irq = type3_handle_irq, | ||
1743 | .evport_offset = SONYPI_TYPE3_OFFSET, | ||
1744 | .event_types = type3_events, | ||
1745 | }, | ||
1746 | }; | ||
1747 | |||
1748 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | 1713 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) |
1749 | { | 1714 | { |
1750 | struct pci_dev *pcidev; | 1715 | struct pci_dev *pcidev; |
@@ -1752,48 +1717,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | |||
1752 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1717 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1753 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); | 1718 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); |
1754 | if (pcidev) { | 1719 | if (pcidev) { |
1755 | dev->control = &spic_types[0]; | 1720 | dev->model = SONYPI_DEVICE_TYPE1; |
1721 | dev->evport_offset = SONYPI_TYPE1_OFFSET; | ||
1722 | dev->event_types = type1_events; | ||
1756 | goto out; | 1723 | goto out; |
1757 | } | 1724 | } |
1758 | 1725 | ||
1759 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1726 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1760 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL); | 1727 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL); |
1761 | if (pcidev) { | 1728 | if (pcidev) { |
1762 | dev->control = &spic_types[2]; | 1729 | dev->model = SONYPI_DEVICE_TYPE2; |
1730 | dev->evport_offset = SONYPI_TYPE2_OFFSET; | ||
1731 | dev->event_types = type2_events; | ||
1763 | goto out; | 1732 | goto out; |
1764 | } | 1733 | } |
1765 | 1734 | ||
1766 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1735 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1767 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); | 1736 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); |
1768 | if (pcidev) { | 1737 | if (pcidev) { |
1769 | dev->control = &spic_types[2]; | 1738 | dev->model = SONYPI_DEVICE_TYPE3; |
1739 | dev->handle_irq = type3_handle_irq; | ||
1740 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
1741 | dev->event_types = type3_events; | ||
1770 | goto out; | 1742 | goto out; |
1771 | } | 1743 | } |
1772 | 1744 | ||
1773 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1745 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1774 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); | 1746 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); |
1775 | if (pcidev) { | 1747 | if (pcidev) { |
1776 | dev->control = &spic_types[2]; | 1748 | dev->model = SONYPI_DEVICE_TYPE3; |
1749 | dev->handle_irq = type3_handle_irq; | ||
1750 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
1751 | dev->event_types = type3_events; | ||
1777 | goto out; | 1752 | goto out; |
1778 | } | 1753 | } |
1779 | 1754 | ||
1780 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1755 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1781 | PCI_DEVICE_ID_INTEL_ICH9_1, NULL); | 1756 | PCI_DEVICE_ID_INTEL_ICH9_1, NULL); |
1782 | if (pcidev) { | 1757 | if (pcidev) { |
1783 | dev->control = &spic_types[2]; | 1758 | dev->model = SONYPI_DEVICE_TYPE3; |
1759 | dev->handle_irq = type3_handle_irq; | ||
1760 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
1761 | dev->event_types = type3_events; | ||
1784 | goto out; | 1762 | goto out; |
1785 | } | 1763 | } |
1786 | 1764 | ||
1787 | /* default */ | 1765 | /* default */ |
1788 | dev->control = &spic_types[1]; | 1766 | dev->model = SONYPI_DEVICE_TYPE2; |
1767 | dev->evport_offset = SONYPI_TYPE2_OFFSET; | ||
1768 | dev->event_types = type2_events; | ||
1789 | 1769 | ||
1790 | out: | 1770 | out: |
1791 | if (pcidev) | 1771 | if (pcidev) |
1792 | pci_dev_put(pcidev); | 1772 | pci_dev_put(pcidev); |
1793 | 1773 | ||
1794 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", | 1774 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", |
1795 | dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : | 1775 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : |
1796 | dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); | 1776 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); |
1797 | } | 1777 | } |
1798 | 1778 | ||
1799 | /* camera tests and poweron/poweroff */ | 1779 | /* camera tests and poweron/poweroff */ |
@@ -2566,7 +2546,7 @@ static int sony_pic_enable(struct acpi_device *device, | |||
2566 | buffer.pointer = resource; | 2546 | buffer.pointer = resource; |
2567 | 2547 | ||
2568 | /* setup Type 1 resources */ | 2548 | /* setup Type 1 resources */ |
2569 | if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { | 2549 | if (spic_dev.model == SONYPI_DEVICE_TYPE1) { |
2570 | 2550 | ||
2571 | /* setup io resources */ | 2551 | /* setup io resources */ |
2572 | resource->res1.type = ACPI_RESOURCE_TYPE_IO; | 2552 | resource->res1.type = ACPI_RESOURCE_TYPE_IO; |
@@ -2649,29 +2629,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) | |||
2649 | data_mask = inb_p(dev->cur_ioport->io2.minimum); | 2629 | data_mask = inb_p(dev->cur_ioport->io2.minimum); |
2650 | else | 2630 | else |
2651 | data_mask = inb_p(dev->cur_ioport->io1.minimum + | 2631 | data_mask = inb_p(dev->cur_ioport->io1.minimum + |
2652 | dev->control->evport_offset); | 2632 | dev->evport_offset); |
2653 | 2633 | ||
2654 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", | 2634 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
2655 | ev, data_mask, dev->cur_ioport->io1.minimum, | 2635 | ev, data_mask, dev->cur_ioport->io1.minimum, |
2656 | dev->control->evport_offset); | 2636 | dev->evport_offset); |
2657 | 2637 | ||
2658 | if (ev == 0x00 || ev == 0xff) | 2638 | if (ev == 0x00 || ev == 0xff) |
2659 | return IRQ_HANDLED; | 2639 | return IRQ_HANDLED; |
2660 | 2640 | ||
2661 | for (i = 0; dev->control->event_types[i].mask; i++) { | 2641 | for (i = 0; dev->event_types[i].mask; i++) { |
2662 | 2642 | ||
2663 | if ((data_mask & dev->control->event_types[i].data) != | 2643 | if ((data_mask & dev->event_types[i].data) != |
2664 | dev->control->event_types[i].data) | 2644 | dev->event_types[i].data) |
2665 | continue; | 2645 | continue; |
2666 | 2646 | ||
2667 | if (!(mask & dev->control->event_types[i].mask)) | 2647 | if (!(mask & dev->event_types[i].mask)) |
2668 | continue; | 2648 | continue; |
2669 | 2649 | ||
2670 | for (j = 0; dev->control->event_types[i].events[j].event; j++) { | 2650 | for (j = 0; dev->event_types[i].events[j].event; j++) { |
2671 | if (ev == dev->control->event_types[i].events[j].data) { | 2651 | if (ev == dev->event_types[i].events[j].data) { |
2672 | device_event = | 2652 | device_event = |
2673 | dev->control-> | 2653 | dev->event_types[i].events[j].event; |
2674 | event_types[i].events[j].event; | ||
2675 | goto found; | 2654 | goto found; |
2676 | } | 2655 | } |
2677 | } | 2656 | } |
@@ -2679,13 +2658,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) | |||
2679 | /* Still not able to decode the event try to pass | 2658 | /* Still not able to decode the event try to pass |
2680 | * it over to the minidriver | 2659 | * it over to the minidriver |
2681 | */ | 2660 | */ |
2682 | if (dev->control->handle_irq && | 2661 | if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0) |
2683 | dev->control->handle_irq(data_mask, ev) == 0) | ||
2684 | return IRQ_HANDLED; | 2662 | return IRQ_HANDLED; |
2685 | 2663 | ||
2686 | dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", | 2664 | dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
2687 | ev, data_mask, dev->cur_ioport->io1.minimum, | 2665 | ev, data_mask, dev->cur_ioport->io1.minimum, |
2688 | dev->control->evport_offset); | 2666 | dev->evport_offset); |
2689 | return IRQ_HANDLED; | 2667 | return IRQ_HANDLED; |
2690 | 2668 | ||
2691 | found: | 2669 | found: |
@@ -2816,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
2816 | /* request IRQ */ | 2794 | /* request IRQ */ |
2817 | list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { | 2795 | list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { |
2818 | if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, | 2796 | if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, |
2819 | IRQF_SHARED, "sony-laptop", &spic_dev)) { | 2797 | IRQF_DISABLED, "sony-laptop", &spic_dev)) { |
2820 | dprintk("IRQ: %d - triggering: %d - " | 2798 | dprintk("IRQ: %d - triggering: %d - " |
2821 | "polarity: %d - shr: %d\n", | 2799 | "polarity: %d - shr: %d\n", |
2822 | irq->irq.interrupts[0], | 2800 | irq->irq.interrupts[0], |
@@ -2949,6 +2927,7 @@ static int __init sony_laptop_init(void) | |||
2949 | "Unable to register SPIC driver."); | 2927 | "Unable to register SPIC driver."); |
2950 | goto out; | 2928 | goto out; |
2951 | } | 2929 | } |
2930 | spic_drv_registered = 1; | ||
2952 | } | 2931 | } |
2953 | 2932 | ||
2954 | result = acpi_bus_register_driver(&sony_nc_driver); | 2933 | result = acpi_bus_register_driver(&sony_nc_driver); |
@@ -2960,7 +2939,7 @@ static int __init sony_laptop_init(void) | |||
2960 | return 0; | 2939 | return 0; |
2961 | 2940 | ||
2962 | out_unregister_pic: | 2941 | out_unregister_pic: |
2963 | if (!no_spic) | 2942 | if (spic_drv_registered) |
2964 | acpi_bus_unregister_driver(&sony_pic_driver); | 2943 | acpi_bus_unregister_driver(&sony_pic_driver); |
2965 | out: | 2944 | out: |
2966 | return result; | 2945 | return result; |
@@ -2969,7 +2948,7 @@ out: | |||
2969 | static void __exit sony_laptop_exit(void) | 2948 | static void __exit sony_laptop_exit(void) |
2970 | { | 2949 | { |
2971 | acpi_bus_unregister_driver(&sony_nc_driver); | 2950 | acpi_bus_unregister_driver(&sony_nc_driver); |
2972 | if (!no_spic) | 2951 | if (spic_drv_registered) |
2973 | acpi_bus_unregister_driver(&sony_pic_driver); | 2952 | acpi_bus_unregister_driver(&sony_pic_driver); |
2974 | } | 2953 | } |
2975 | 2954 | ||