diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/ec.c | 4 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 7 | ||||
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 127 |
3 files changed, 56 insertions, 82 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 2c790b5badb3..baef28c1e630 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -234,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec) | |||
234 | } | 234 | } |
235 | advance_transaction(ec, acpi_ec_read_status(ec)); | 235 | advance_transaction(ec, acpi_ec_read_status(ec)); |
236 | } while (time_before(jiffies, delay)); | 236 | } while (time_before(jiffies, delay)); |
237 | if (!ec->curr->irq_count || | 237 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) |
238 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
239 | break; | 238 | break; |
240 | /* try restart command if we get any false interrupts */ | ||
241 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 239 | pr_debug(PREFIX "controller reset, restart transaction\n"); |
242 | spin_lock_irqsave(&ec->curr_lock, flags); | 240 | spin_lock_irqsave(&ec->curr_lock, flags); |
243 | start_transaction(ec); | 241 | start_transaction(ec); |
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 | ||