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: |
