aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/sony-laptop.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-10-29 04:02:15 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-29 04:02:20 -0400
commit9de09ace8d518141a4375e1d216ab64db4377799 (patch)
treeda8e7a77f4ea91eb3bb73fc6da72ecf8c99e1c16 /drivers/platform/x86/sony-laptop.c
parent1beee96bae0daf7f491356777c3080cc436950f5 (diff)
parent6d3f1e12f46a2f9a1bb7e7aa433df8dd31ce5647 (diff)
Merge branch 'tracing/urgent' into tracing/core
Merge reason: Pick up fixes and move base from -rc1 to -rc5. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/platform/x86/sony-laptop.c')
-rw-r--r--drivers/platform/x86/sony-laptop.c127
1 files changed, 53 insertions, 74 deletions
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
1402struct device_ctrl { 1393struct 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
1412struct 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
1425static struct sony_pic_dev spic_dev = { 1409static 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
1414static 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
1727static 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
1748static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 1713static 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
1790out: 1770out:
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
2691found: 2669found:
@@ -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
2962out_unregister_pic: 2941out_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);
2965out: 2944out:
2966 return result; 2945 return result;
@@ -2969,7 +2948,7 @@ out:
2969static void __exit sony_laptop_exit(void) 2948static 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