diff options
| -rw-r--r-- | drivers/acpi/ec.c | 56 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 7 | ||||
| -rw-r--r-- | drivers/platform/x86/sony-laptop.c | 127 |
3 files changed, 102 insertions, 88 deletions
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/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 | ||
