diff options
author | Len Brown <len.brown@intel.com> | 2005-12-06 17:31:30 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-06 17:31:30 -0500 |
commit | 3d5271f9883cba7b54762bc4fe027d4172f06db7 (patch) | |
tree | ab8a881a14478598a0c8bda0d26c62cdccfffd6d /drivers/usb/host/sl811-hcd.c | |
parent | 378b2556f4e09fa6f87ff0cb5c4395ff28257d02 (diff) | |
parent | 9115a6c787596e687df03010d97fccc5e0762506 (diff) |
Pull release into acpica branch
Diffstat (limited to 'drivers/usb/host/sl811-hcd.c')
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 101 |
1 files changed, 52 insertions, 49 deletions
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index d2a1fd40dfcb..a7722a6a5a5b 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/usb.h> | 55 | #include <linux/usb.h> |
56 | #include <linux/usb_sl811.h> | 56 | #include <linux/usb_sl811.h> |
57 | #include <linux/platform_device.h> | ||
57 | 58 | ||
58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
59 | #include <asm/irq.h> | 60 | #include <asm/irq.h> |
@@ -782,6 +783,9 @@ retry: | |||
782 | /* usb 1.1 says max 90% of a frame is available for periodic transfers. | 783 | /* usb 1.1 says max 90% of a frame is available for periodic transfers. |
783 | * this driver doesn't promise that much since it's got to handle an | 784 | * this driver doesn't promise that much since it's got to handle an |
784 | * IRQ per packet; irq handling latencies also use up that time. | 785 | * IRQ per packet; irq handling latencies also use up that time. |
786 | * | ||
787 | * NOTE: the periodic schedule is a sparse tree, with the load for | ||
788 | * each branch minimized. see fig 3.5 in the OHCI spec for example. | ||
785 | */ | 789 | */ |
786 | #define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */ | 790 | #define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */ |
787 | 791 | ||
@@ -815,7 +819,7 @@ static int sl811h_urb_enqueue( | |||
815 | struct usb_hcd *hcd, | 819 | struct usb_hcd *hcd, |
816 | struct usb_host_endpoint *hep, | 820 | struct usb_host_endpoint *hep, |
817 | struct urb *urb, | 821 | struct urb *urb, |
818 | unsigned mem_flags | 822 | gfp_t mem_flags |
819 | ) { | 823 | ) { |
820 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 824 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
821 | struct usb_device *udev = urb->dev; | 825 | struct usb_device *udev = urb->dev; |
@@ -843,6 +847,7 @@ static int sl811h_urb_enqueue( | |||
843 | if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE)) | 847 | if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE)) |
844 | || !HC_IS_RUNNING(hcd->state)) { | 848 | || !HC_IS_RUNNING(hcd->state)) { |
845 | retval = -ENODEV; | 849 | retval = -ENODEV; |
850 | kfree(ep); | ||
846 | goto fail; | 851 | goto fail; |
847 | } | 852 | } |
848 | 853 | ||
@@ -911,8 +916,16 @@ static int sl811h_urb_enqueue( | |||
911 | case PIPE_ISOCHRONOUS: | 916 | case PIPE_ISOCHRONOUS: |
912 | case PIPE_INTERRUPT: | 917 | case PIPE_INTERRUPT: |
913 | urb->interval = ep->period; | 918 | urb->interval = ep->period; |
914 | if (ep->branch < PERIODIC_SIZE) | 919 | if (ep->branch < PERIODIC_SIZE) { |
920 | /* NOTE: the phase is correct here, but the value | ||
921 | * needs offsetting by the transfer queue depth. | ||
922 | * All current drivers ignore start_frame, so this | ||
923 | * is unlikely to ever matter... | ||
924 | */ | ||
925 | urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) | ||
926 | + ep->branch; | ||
915 | break; | 927 | break; |
928 | } | ||
916 | 929 | ||
917 | retval = balance(sl811, ep->period, ep->load); | 930 | retval = balance(sl811, ep->period, ep->load); |
918 | if (retval < 0) | 931 | if (retval < 0) |
@@ -1122,7 +1135,7 @@ sl811h_hub_descriptor ( | |||
1122 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); | 1135 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); |
1123 | 1136 | ||
1124 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ | 1137 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ |
1125 | desc->bitmap[0] = 1 << 1; | 1138 | desc->bitmap[0] = 0 << 1; |
1126 | desc->bitmap[1] = ~0; | 1139 | desc->bitmap[1] = ~0; |
1127 | } | 1140 | } |
1128 | 1141 | ||
@@ -1351,7 +1364,7 @@ error: | |||
1351 | #ifdef CONFIG_PM | 1364 | #ifdef CONFIG_PM |
1352 | 1365 | ||
1353 | static int | 1366 | static int |
1354 | sl811h_hub_suspend(struct usb_hcd *hcd) | 1367 | sl811h_bus_suspend(struct usb_hcd *hcd) |
1355 | { | 1368 | { |
1356 | // SOFs off | 1369 | // SOFs off |
1357 | DBG("%s\n", __FUNCTION__); | 1370 | DBG("%s\n", __FUNCTION__); |
@@ -1359,7 +1372,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd) | |||
1359 | } | 1372 | } |
1360 | 1373 | ||
1361 | static int | 1374 | static int |
1362 | sl811h_hub_resume(struct usb_hcd *hcd) | 1375 | sl811h_bus_resume(struct usb_hcd *hcd) |
1363 | { | 1376 | { |
1364 | // SOFs on | 1377 | // SOFs on |
1365 | DBG("%s\n", __FUNCTION__); | 1378 | DBG("%s\n", __FUNCTION__); |
@@ -1368,8 +1381,8 @@ sl811h_hub_resume(struct usb_hcd *hcd) | |||
1368 | 1381 | ||
1369 | #else | 1382 | #else |
1370 | 1383 | ||
1371 | #define sl811h_hub_suspend NULL | 1384 | #define sl811h_bus_suspend NULL |
1372 | #define sl811h_hub_resume NULL | 1385 | #define sl811h_bus_resume NULL |
1373 | 1386 | ||
1374 | #endif | 1387 | #endif |
1375 | 1388 | ||
@@ -1611,31 +1624,28 @@ static struct hc_driver sl811h_hc_driver = { | |||
1611 | */ | 1624 | */ |
1612 | .hub_status_data = sl811h_hub_status_data, | 1625 | .hub_status_data = sl811h_hub_status_data, |
1613 | .hub_control = sl811h_hub_control, | 1626 | .hub_control = sl811h_hub_control, |
1614 | .hub_suspend = sl811h_hub_suspend, | 1627 | .bus_suspend = sl811h_bus_suspend, |
1615 | .hub_resume = sl811h_hub_resume, | 1628 | .bus_resume = sl811h_bus_resume, |
1616 | }; | 1629 | }; |
1617 | 1630 | ||
1618 | /*-------------------------------------------------------------------------*/ | 1631 | /*-------------------------------------------------------------------------*/ |
1619 | 1632 | ||
1620 | static int __devexit | 1633 | static int __devexit |
1621 | sl811h_remove(struct device *dev) | 1634 | sl811h_remove(struct platform_device *dev) |
1622 | { | 1635 | { |
1623 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1636 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1624 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1637 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1625 | struct platform_device *pdev; | ||
1626 | struct resource *res; | 1638 | struct resource *res; |
1627 | 1639 | ||
1628 | pdev = container_of(dev, struct platform_device, dev); | ||
1629 | |||
1630 | remove_debug_file(sl811); | 1640 | remove_debug_file(sl811); |
1631 | usb_remove_hcd(hcd); | 1641 | usb_remove_hcd(hcd); |
1632 | 1642 | ||
1633 | /* some platforms may use IORESOURCE_IO */ | 1643 | /* some platforms may use IORESOURCE_IO */ |
1634 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1644 | res = platform_get_resource(dev, IORESOURCE_MEM, 1); |
1635 | if (res) | 1645 | if (res) |
1636 | iounmap(sl811->data_reg); | 1646 | iounmap(sl811->data_reg); |
1637 | 1647 | ||
1638 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1648 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
1639 | if (res) | 1649 | if (res) |
1640 | iounmap(sl811->addr_reg); | 1650 | iounmap(sl811->addr_reg); |
1641 | 1651 | ||
@@ -1644,11 +1654,10 @@ sl811h_remove(struct device *dev) | |||
1644 | } | 1654 | } |
1645 | 1655 | ||
1646 | static int __devinit | 1656 | static int __devinit |
1647 | sl811h_probe(struct device *dev) | 1657 | sl811h_probe(struct platform_device *dev) |
1648 | { | 1658 | { |
1649 | struct usb_hcd *hcd; | 1659 | struct usb_hcd *hcd; |
1650 | struct sl811 *sl811; | 1660 | struct sl811 *sl811; |
1651 | struct platform_device *pdev; | ||
1652 | struct resource *addr, *data; | 1661 | struct resource *addr, *data; |
1653 | int irq; | 1662 | int irq; |
1654 | void __iomem *addr_reg; | 1663 | void __iomem *addr_reg; |
@@ -1661,24 +1670,23 @@ sl811h_probe(struct device *dev) | |||
1661 | * specific platform_data. we don't probe for IRQs, and do only | 1670 | * specific platform_data. we don't probe for IRQs, and do only |
1662 | * minimal sanity checking. | 1671 | * minimal sanity checking. |
1663 | */ | 1672 | */ |
1664 | pdev = container_of(dev, struct platform_device, dev); | 1673 | irq = platform_get_irq(dev, 0); |
1665 | irq = platform_get_irq(pdev, 0); | 1674 | if (dev->num_resources < 3 || irq < 0) |
1666 | if (pdev->num_resources < 3 || irq < 0) | ||
1667 | return -ENODEV; | 1675 | return -ENODEV; |
1668 | 1676 | ||
1669 | /* refuse to confuse usbcore */ | 1677 | /* refuse to confuse usbcore */ |
1670 | if (dev->dma_mask) { | 1678 | if (dev->dev.dma_mask) { |
1671 | DBG("no we won't dma\n"); | 1679 | DBG("no we won't dma\n"); |
1672 | return -EINVAL; | 1680 | return -EINVAL; |
1673 | } | 1681 | } |
1674 | 1682 | ||
1675 | /* the chip may be wired for either kind of addressing */ | 1683 | /* the chip may be wired for either kind of addressing */ |
1676 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1684 | addr = platform_get_resource(dev, IORESOURCE_MEM, 0); |
1677 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1685 | data = platform_get_resource(dev, IORESOURCE_MEM, 1); |
1678 | retval = -EBUSY; | 1686 | retval = -EBUSY; |
1679 | if (!addr || !data) { | 1687 | if (!addr || !data) { |
1680 | addr = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1688 | addr = platform_get_resource(dev, IORESOURCE_IO, 0); |
1681 | data = platform_get_resource(pdev, IORESOURCE_IO, 1); | 1689 | data = platform_get_resource(dev, IORESOURCE_IO, 1); |
1682 | if (!addr || !data) | 1690 | if (!addr || !data) |
1683 | return -ENODEV; | 1691 | return -ENODEV; |
1684 | ioaddr = 1; | 1692 | ioaddr = 1; |
@@ -1700,7 +1708,7 @@ sl811h_probe(struct device *dev) | |||
1700 | } | 1708 | } |
1701 | 1709 | ||
1702 | /* allocate and initialize hcd */ | 1710 | /* allocate and initialize hcd */ |
1703 | hcd = usb_create_hcd(&sl811h_hc_driver, dev, dev->bus_id); | 1711 | hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev->dev.bus_id); |
1704 | if (!hcd) { | 1712 | if (!hcd) { |
1705 | retval = -ENOMEM; | 1713 | retval = -ENOMEM; |
1706 | goto err5; | 1714 | goto err5; |
@@ -1710,7 +1718,7 @@ sl811h_probe(struct device *dev) | |||
1710 | 1718 | ||
1711 | spin_lock_init(&sl811->lock); | 1719 | spin_lock_init(&sl811->lock); |
1712 | INIT_LIST_HEAD(&sl811->async); | 1720 | INIT_LIST_HEAD(&sl811->async); |
1713 | sl811->board = dev->platform_data; | 1721 | sl811->board = dev->dev.platform_data; |
1714 | init_timer(&sl811->timer); | 1722 | init_timer(&sl811->timer); |
1715 | sl811->timer.function = sl811h_timer; | 1723 | sl811->timer.function = sl811h_timer; |
1716 | sl811->timer.data = (unsigned long) sl811; | 1724 | sl811->timer.data = (unsigned long) sl811; |
@@ -1772,45 +1780,39 @@ sl811h_probe(struct device *dev) | |||
1772 | */ | 1780 | */ |
1773 | 1781 | ||
1774 | static int | 1782 | static int |
1775 | sl811h_suspend(struct device *dev, pm_message_t state, u32 phase) | 1783 | sl811h_suspend(struct platform_device *dev, pm_message_t state) |
1776 | { | 1784 | { |
1777 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1785 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1778 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1786 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1779 | int retval = 0; | 1787 | int retval = 0; |
1780 | 1788 | ||
1781 | if (phase != SUSPEND_POWER_DOWN) | ||
1782 | return retval; | ||
1783 | |||
1784 | if (state.event == PM_EVENT_FREEZE) | 1789 | if (state.event == PM_EVENT_FREEZE) |
1785 | retval = sl811h_hub_suspend(hcd); | 1790 | retval = sl811h_bus_suspend(hcd); |
1786 | else if (state.event == PM_EVENT_SUSPEND) | 1791 | else if (state.event == PM_EVENT_SUSPEND) |
1787 | port_power(sl811, 0); | 1792 | port_power(sl811, 0); |
1788 | if (retval == 0) | 1793 | if (retval == 0) |
1789 | dev->power.power_state = state; | 1794 | dev->dev.power.power_state = state; |
1790 | return retval; | 1795 | return retval; |
1791 | } | 1796 | } |
1792 | 1797 | ||
1793 | static int | 1798 | static int |
1794 | sl811h_resume(struct device *dev, u32 phase) | 1799 | sl811h_resume(struct platform_device *dev) |
1795 | { | 1800 | { |
1796 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1801 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1797 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1802 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1798 | 1803 | ||
1799 | if (phase != RESUME_POWER_ON) | ||
1800 | return 0; | ||
1801 | |||
1802 | /* with no "check to see if VBUS is still powered" board hook, | 1804 | /* with no "check to see if VBUS is still powered" board hook, |
1803 | * let's assume it'd only be powered to enable remote wakeup. | 1805 | * let's assume it'd only be powered to enable remote wakeup. |
1804 | */ | 1806 | */ |
1805 | if (dev->power.power_state.event == PM_EVENT_SUSPEND | 1807 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND |
1806 | || !hcd->can_wakeup) { | 1808 | || !hcd->can_wakeup) { |
1807 | sl811->port1 = 0; | 1809 | sl811->port1 = 0; |
1808 | port_power(sl811, 1); | 1810 | port_power(sl811, 1); |
1809 | return 0; | 1811 | return 0; |
1810 | } | 1812 | } |
1811 | 1813 | ||
1812 | dev->power.power_state = PMSG_ON; | 1814 | dev->dev.power.power_state = PMSG_ON; |
1813 | return sl811h_hub_resume(hcd); | 1815 | return sl811h_bus_resume(hcd); |
1814 | } | 1816 | } |
1815 | 1817 | ||
1816 | #else | 1818 | #else |
@@ -1822,15 +1824,16 @@ sl811h_resume(struct device *dev, u32 phase) | |||
1822 | 1824 | ||
1823 | 1825 | ||
1824 | /* this driver is exported so sl811_cs can depend on it */ | 1826 | /* this driver is exported so sl811_cs can depend on it */ |
1825 | struct device_driver sl811h_driver = { | 1827 | struct platform_driver sl811h_driver = { |
1826 | .name = (char *) hcd_name, | ||
1827 | .bus = &platform_bus_type, | ||
1828 | |||
1829 | .probe = sl811h_probe, | 1828 | .probe = sl811h_probe, |
1830 | .remove = __devexit_p(sl811h_remove), | 1829 | .remove = __devexit_p(sl811h_remove), |
1831 | 1830 | ||
1832 | .suspend = sl811h_suspend, | 1831 | .suspend = sl811h_suspend, |
1833 | .resume = sl811h_resume, | 1832 | .resume = sl811h_resume, |
1833 | .driver = { | ||
1834 | .name = (char *) hcd_name, | ||
1835 | .owner = THIS_MODULE, | ||
1836 | }, | ||
1834 | }; | 1837 | }; |
1835 | EXPORT_SYMBOL(sl811h_driver); | 1838 | EXPORT_SYMBOL(sl811h_driver); |
1836 | 1839 | ||
@@ -1842,12 +1845,12 @@ static int __init sl811h_init(void) | |||
1842 | return -ENODEV; | 1845 | return -ENODEV; |
1843 | 1846 | ||
1844 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); | 1847 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); |
1845 | return driver_register(&sl811h_driver); | 1848 | return platform_driver_register(&sl811h_driver); |
1846 | } | 1849 | } |
1847 | module_init(sl811h_init); | 1850 | module_init(sl811h_init); |
1848 | 1851 | ||
1849 | static void __exit sl811h_cleanup(void) | 1852 | static void __exit sl811h_cleanup(void) |
1850 | { | 1853 | { |
1851 | driver_unregister(&sl811h_driver); | 1854 | platform_driver_unregister(&sl811h_driver); |
1852 | } | 1855 | } |
1853 | module_exit(sl811h_cleanup); | 1856 | module_exit(sl811h_cleanup); |