aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/x86/sony-laptop.c109
1 files changed, 47 insertions, 62 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index f9f68e0e7344..4dee1a2848de 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1390,27 +1390,20 @@ struct sonypi_eventtypes {
1390 struct sonypi_event *events; 1390 struct sonypi_event *events;
1391}; 1391};
1392 1392
1393struct 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);
1394 int model; 1402 int model;
1395 int (*handle_irq)(const u8, const u8);
1396 u16 evport_offset; 1403 u16 evport_offset;
1397 u8 has_camera; 1404 u8 camera_power;
1398 u8 has_bluetooth; 1405 u8 bluetooth_power;
1399 u8 has_wwan; 1406 u8 wwan_power;
1400 struct sonypi_eventtypes *event_types;
1401};
1402
1403struct sony_pic_dev {
1404 struct device_ctrl *control;
1405 struct acpi_device *acpi_dev;
1406 struct sony_pic_irq *cur_irq;
1407 struct sony_pic_ioport *cur_ioport;
1408 struct list_head interrupts;
1409 struct list_head ioports;
1410 struct mutex lock;
1411 u8 camera_power;
1412 u8 bluetooth_power;
1413 u8 wwan_power;
1414}; 1407};
1415 1408
1416static struct sony_pic_dev spic_dev = { 1409static struct sony_pic_dev spic_dev = {
@@ -1715,27 +1708,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev)
1715 return 1; 1708 return 1;
1716} 1709}
1717 1710
1718static struct device_ctrl spic_types[] = {
1719 {
1720 .model = SONYPI_DEVICE_TYPE1,
1721 .handle_irq = NULL,
1722 .evport_offset = SONYPI_TYPE1_OFFSET,
1723 .event_types = type1_events,
1724 },
1725 {
1726 .model = SONYPI_DEVICE_TYPE2,
1727 .handle_irq = NULL,
1728 .evport_offset = SONYPI_TYPE2_OFFSET,
1729 .event_types = type2_events,
1730 },
1731 {
1732 .model = SONYPI_DEVICE_TYPE3,
1733 .handle_irq = type3_handle_irq,
1734 .evport_offset = SONYPI_TYPE3_OFFSET,
1735 .event_types = type3_events,
1736 },
1737};
1738
1739static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 1711static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
1740{ 1712{
1741 struct pci_dev *pcidev; 1713 struct pci_dev *pcidev;
@@ -1743,48 +1715,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
1743 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1715 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1744 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 1716 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
1745 if (pcidev) { 1717 if (pcidev) {
1746 dev->control = &spic_types[0]; 1718 dev->model = SONYPI_DEVICE_TYPE1;
1719 dev->evport_offset = SONYPI_TYPE1_OFFSET;
1720 dev->event_types = type1_events;
1747 goto out; 1721 goto out;
1748 } 1722 }
1749 1723
1750 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1724 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1751 PCI_DEVICE_ID_INTEL_ICH6_1, NULL); 1725 PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
1752 if (pcidev) { 1726 if (pcidev) {
1753 dev->control = &spic_types[2]; 1727 dev->model = SONYPI_DEVICE_TYPE2;
1728 dev->evport_offset = SONYPI_TYPE2_OFFSET;
1729 dev->event_types = type2_events;
1754 goto out; 1730 goto out;
1755 } 1731 }
1756 1732
1757 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1733 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1758 PCI_DEVICE_ID_INTEL_ICH7_1, NULL); 1734 PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
1759 if (pcidev) { 1735 if (pcidev) {
1760 dev->control = &spic_types[2]; 1736 dev->model = SONYPI_DEVICE_TYPE3;
1737 dev->handle_irq = type3_handle_irq;
1738 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1739 dev->event_types = type3_events;
1761 goto out; 1740 goto out;
1762 } 1741 }
1763 1742
1764 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1743 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1765 PCI_DEVICE_ID_INTEL_ICH8_4, NULL); 1744 PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
1766 if (pcidev) { 1745 if (pcidev) {
1767 dev->control = &spic_types[2]; 1746 dev->model = SONYPI_DEVICE_TYPE3;
1747 dev->handle_irq = type3_handle_irq;
1748 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1749 dev->event_types = type3_events;
1768 goto out; 1750 goto out;
1769 } 1751 }
1770 1752
1771 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1753 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1772 PCI_DEVICE_ID_INTEL_ICH9_1, NULL); 1754 PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
1773 if (pcidev) { 1755 if (pcidev) {
1774 dev->control = &spic_types[2]; 1756 dev->model = SONYPI_DEVICE_TYPE3;
1757 dev->handle_irq = type3_handle_irq;
1758 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1759 dev->event_types = type3_events;
1775 goto out; 1760 goto out;
1776 } 1761 }
1777 1762
1778 /* default */ 1763 /* default */
1779 dev->control = &spic_types[1]; 1764 dev->model = SONYPI_DEVICE_TYPE2;
1765 dev->evport_offset = SONYPI_TYPE2_OFFSET;
1766 dev->event_types = type2_events;
1780 1767
1781out: 1768out:
1782 if (pcidev) 1769 if (pcidev)
1783 pci_dev_put(pcidev); 1770 pci_dev_put(pcidev);
1784 1771
1785 printk(KERN_INFO DRV_PFX "detected Type%d model\n", 1772 printk(KERN_INFO DRV_PFX "detected Type%d model\n",
1786 dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : 1773 dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
1787 dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); 1774 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
1788} 1775}
1789 1776
1790/* camera tests and poweron/poweroff */ 1777/* camera tests and poweron/poweroff */
@@ -2557,7 +2544,7 @@ static int sony_pic_enable(struct acpi_device *device,
2557 buffer.pointer = resource; 2544 buffer.pointer = resource;
2558 2545
2559 /* setup Type 1 resources */ 2546 /* setup Type 1 resources */
2560 if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { 2547 if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
2561 2548
2562 /* setup io resources */ 2549 /* setup io resources */
2563 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 2550 resource->res1.type = ACPI_RESOURCE_TYPE_IO;
@@ -2640,29 +2627,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2640 data_mask = inb_p(dev->cur_ioport->io2.minimum); 2627 data_mask = inb_p(dev->cur_ioport->io2.minimum);
2641 else 2628 else
2642 data_mask = inb_p(dev->cur_ioport->io1.minimum + 2629 data_mask = inb_p(dev->cur_ioport->io1.minimum +
2643 dev->control->evport_offset); 2630 dev->evport_offset);
2644 2631
2645 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2632 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2646 ev, data_mask, dev->cur_ioport->io1.minimum, 2633 ev, data_mask, dev->cur_ioport->io1.minimum,
2647 dev->control->evport_offset); 2634 dev->evport_offset);
2648 2635
2649 if (ev == 0x00 || ev == 0xff) 2636 if (ev == 0x00 || ev == 0xff)
2650 return IRQ_HANDLED; 2637 return IRQ_HANDLED;
2651 2638
2652 for (i = 0; dev->control->event_types[i].mask; i++) { 2639 for (i = 0; dev->event_types[i].mask; i++) {
2653 2640
2654 if ((data_mask & dev->control->event_types[i].data) != 2641 if ((data_mask & dev->event_types[i].data) !=
2655 dev->control->event_types[i].data) 2642 dev->event_types[i].data)
2656 continue; 2643 continue;
2657 2644
2658 if (!(mask & dev->control->event_types[i].mask)) 2645 if (!(mask & dev->event_types[i].mask))
2659 continue; 2646 continue;
2660 2647
2661 for (j = 0; dev->control->event_types[i].events[j].event; j++) { 2648 for (j = 0; dev->event_types[i].events[j].event; j++) {
2662 if (ev == dev->control->event_types[i].events[j].data) { 2649 if (ev == dev->event_types[i].events[j].data) {
2663 device_event = 2650 device_event =
2664 dev->control-> 2651 dev->event_types[i].events[j].event;
2665 event_types[i].events[j].event;
2666 goto found; 2652 goto found;
2667 } 2653 }
2668 } 2654 }
@@ -2670,13 +2656,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2670 /* Still not able to decode the event try to pass 2656 /* Still not able to decode the event try to pass
2671 * it over to the minidriver 2657 * it over to the minidriver
2672 */ 2658 */
2673 if (dev->control->handle_irq && 2659 if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0)
2674 dev->control->handle_irq(data_mask, ev) == 0)
2675 return IRQ_HANDLED; 2660 return IRQ_HANDLED;
2676 2661
2677 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2662 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2678 ev, data_mask, dev->cur_ioport->io1.minimum, 2663 ev, data_mask, dev->cur_ioport->io1.minimum,
2679 dev->control->evport_offset); 2664 dev->evport_offset);
2680 return IRQ_HANDLED; 2665 return IRQ_HANDLED;
2681 2666
2682found: 2667found: