diff options
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 109 |
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 | ||
1393 | 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); | ||
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 | |||
1403 | struct 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 | ||
1416 | static struct sony_pic_dev spic_dev = { | 1409 | static 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 | ||
1718 | static 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 | |||
1739 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | 1711 | static 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 | ||
1781 | out: | 1768 | out: |
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 | ||
2682 | found: | 2667 | found: |