.. | .. |
---|
18 | 18 | #include <linux/platform_device.h> |
---|
19 | 19 | #include <linux/regmap.h> |
---|
20 | 20 | #include <linux/ctype.h> |
---|
| 21 | +#include <linux/usb.h> |
---|
21 | 22 | #include <linux/usb/ch9.h> |
---|
22 | 23 | #include <linux/usb/gadget.h> |
---|
23 | 24 | #include <linux/delay.h> |
---|
.. | .. |
---|
88 | 89 | size_t len, remaining, actual = 0; |
---|
89 | 90 | char tmpbuf[38]; |
---|
90 | 91 | |
---|
91 | | - if (!access_ok(VERIFY_WRITE, buf, nbytes)) |
---|
| 92 | + if (!access_ok(buf, nbytes)) |
---|
92 | 93 | return -EFAULT; |
---|
93 | 94 | |
---|
94 | 95 | inode_lock(file_inode(file)); |
---|
.. | .. |
---|
184 | 185 | return 0; |
---|
185 | 186 | } |
---|
186 | 187 | |
---|
187 | | -const struct file_operations queue_dbg_fops = { |
---|
| 188 | +static const struct file_operations queue_dbg_fops = { |
---|
188 | 189 | .owner = THIS_MODULE, |
---|
189 | 190 | .open = queue_dbg_open, |
---|
190 | 191 | .llseek = no_llseek, |
---|
.. | .. |
---|
192 | 193 | .release = queue_dbg_release, |
---|
193 | 194 | }; |
---|
194 | 195 | |
---|
195 | | -const struct file_operations regs_dbg_fops = { |
---|
| 196 | +static const struct file_operations regs_dbg_fops = { |
---|
196 | 197 | .owner = THIS_MODULE, |
---|
197 | 198 | .open = regs_dbg_open, |
---|
198 | 199 | .llseek = generic_file_llseek, |
---|
.. | .. |
---|
226 | 227 | struct dentry *root; |
---|
227 | 228 | struct resource *regs_resource; |
---|
228 | 229 | |
---|
229 | | - root = debugfs_create_dir(udc->gadget.name, NULL); |
---|
| 230 | + root = debugfs_create_dir(udc->gadget.name, usb_debug_root); |
---|
230 | 231 | udc->debugfs_root = root; |
---|
231 | 232 | |
---|
232 | 233 | regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM, |
---|
.. | .. |
---|
327 | 328 | switch (fifo_mode) { |
---|
328 | 329 | default: |
---|
329 | 330 | fifo_mode = 0; |
---|
| 331 | + fallthrough; |
---|
330 | 332 | case 0: |
---|
331 | 333 | udc->fifo_cfg = NULL; |
---|
332 | 334 | n = 0; |
---|
.. | .. |
---|
358 | 360 | return udc->int_enb_cache; |
---|
359 | 361 | } |
---|
360 | 362 | |
---|
361 | | -static inline void usba_int_enb_set(struct usba_udc *udc, u32 val) |
---|
| 363 | +static inline void usba_int_enb_set(struct usba_udc *udc, u32 mask) |
---|
362 | 364 | { |
---|
| 365 | + u32 val; |
---|
| 366 | + |
---|
| 367 | + val = udc->int_enb_cache | mask; |
---|
| 368 | + usba_writel(udc, INT_ENB, val); |
---|
| 369 | + udc->int_enb_cache = val; |
---|
| 370 | +} |
---|
| 371 | + |
---|
| 372 | +static inline void usba_int_enb_clear(struct usba_udc *udc, u32 mask) |
---|
| 373 | +{ |
---|
| 374 | + u32 val; |
---|
| 375 | + |
---|
| 376 | + val = udc->int_enb_cache & ~mask; |
---|
363 | 377 | usba_writel(udc, INT_ENB, val); |
---|
364 | 378 | udc->int_enb_cache = val; |
---|
365 | 379 | } |
---|
.. | .. |
---|
631 | 645 | if (ep->can_dma) { |
---|
632 | 646 | u32 ctrl; |
---|
633 | 647 | |
---|
634 | | - usba_int_enb_set(udc, usba_int_enb_get(udc) | |
---|
635 | | - USBA_BF(EPT_INT, 1 << ep->index) | |
---|
| 648 | + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1 << ep->index) | |
---|
636 | 649 | USBA_BF(DMA_INT, 1 << ep->index)); |
---|
637 | 650 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; |
---|
638 | 651 | usba_ep_writel(ep, CTL_ENB, ctrl); |
---|
639 | 652 | } else { |
---|
640 | | - usba_int_enb_set(udc, usba_int_enb_get(udc) | |
---|
641 | | - USBA_BF(EPT_INT, 1 << ep->index)); |
---|
| 653 | + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1 << ep->index)); |
---|
642 | 654 | } |
---|
643 | 655 | |
---|
644 | 656 | spin_unlock_irqrestore(&udc->lock, flags); |
---|
.. | .. |
---|
664 | 676 | |
---|
665 | 677 | if (!ep->ep.desc) { |
---|
666 | 678 | spin_unlock_irqrestore(&udc->lock, flags); |
---|
667 | | - /* REVISIT because this driver disables endpoints in |
---|
668 | | - * reset_all_endpoints() before calling disconnect(), |
---|
669 | | - * most gadget drivers would trigger this non-error ... |
---|
670 | | - */ |
---|
671 | | - if (udc->gadget.speed != USB_SPEED_UNKNOWN) |
---|
672 | | - DBG(DBG_ERR, "ep_disable: %s not enabled\n", |
---|
673 | | - ep->ep.name); |
---|
| 679 | + DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); |
---|
674 | 680 | return -EINVAL; |
---|
675 | 681 | } |
---|
676 | 682 | ep->ep.desc = NULL; |
---|
.. | .. |
---|
682 | 688 | usba_dma_readl(ep, STATUS); |
---|
683 | 689 | } |
---|
684 | 690 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); |
---|
685 | | - usba_int_enb_set(udc, usba_int_enb_get(udc) & |
---|
686 | | - ~USBA_BF(EPT_INT, 1 << ep->index)); |
---|
| 691 | + usba_int_enb_clear(udc, USBA_BF(EPT_INT, 1 << ep->index)); |
---|
687 | 692 | |
---|
688 | 693 | request_complete_list(ep, &req_list, -ESHUTDOWN); |
---|
689 | 694 | |
---|
.. | .. |
---|
1023 | 1028 | return 0; |
---|
1024 | 1029 | } |
---|
1025 | 1030 | |
---|
| 1031 | +static int atmel_usba_pullup(struct usb_gadget *gadget, int is_on); |
---|
1026 | 1032 | static int atmel_usba_start(struct usb_gadget *gadget, |
---|
1027 | 1033 | struct usb_gadget_driver *driver); |
---|
1028 | 1034 | static int atmel_usba_stop(struct usb_gadget *gadget); |
---|
.. | .. |
---|
1050 | 1056 | |
---|
1051 | 1057 | switch (usb_endpoint_type(desc)) { |
---|
1052 | 1058 | case USB_ENDPOINT_XFER_CONTROL: |
---|
| 1059 | + ep->nr_banks = 1; |
---|
1053 | 1060 | break; |
---|
1054 | 1061 | |
---|
1055 | 1062 | case USB_ENDPOINT_XFER_ISOC: |
---|
1056 | 1063 | ep->fifo_size = 1024; |
---|
1057 | | - ep->nr_banks = 2; |
---|
| 1064 | + if (ep->udc->ep_prealloc) |
---|
| 1065 | + ep->nr_banks = 2; |
---|
1058 | 1066 | break; |
---|
1059 | 1067 | |
---|
1060 | 1068 | case USB_ENDPOINT_XFER_BULK: |
---|
1061 | 1069 | ep->fifo_size = 512; |
---|
1062 | | - ep->nr_banks = 1; |
---|
| 1070 | + if (ep->udc->ep_prealloc) |
---|
| 1071 | + ep->nr_banks = 1; |
---|
1063 | 1072 | break; |
---|
1064 | 1073 | |
---|
1065 | 1074 | case USB_ENDPOINT_XFER_INT: |
---|
.. | .. |
---|
1069 | 1078 | else |
---|
1070 | 1079 | ep->fifo_size = |
---|
1071 | 1080 | roundup_pow_of_two(le16_to_cpu(desc->wMaxPacketSize)); |
---|
1072 | | - ep->nr_banks = 1; |
---|
| 1081 | + if (ep->udc->ep_prealloc) |
---|
| 1082 | + ep->nr_banks = 1; |
---|
1073 | 1083 | break; |
---|
1074 | 1084 | } |
---|
1075 | 1085 | |
---|
.. | .. |
---|
1085 | 1095 | USBA_BF(EPT_SIZE, fls(ep->fifo_size - 1) - 3); |
---|
1086 | 1096 | |
---|
1087 | 1097 | ep->ept_cfg |= USBA_BF(BK_NUMBER, ep->nr_banks); |
---|
1088 | | - |
---|
1089 | | - ep->udc->configured_ep++; |
---|
1090 | 1098 | } |
---|
1091 | 1099 | |
---|
1092 | 1100 | return _ep; |
---|
.. | .. |
---|
1096 | 1104 | .get_frame = usba_udc_get_frame, |
---|
1097 | 1105 | .wakeup = usba_udc_wakeup, |
---|
1098 | 1106 | .set_selfpowered = usba_udc_set_selfpowered, |
---|
| 1107 | + .pullup = atmel_usba_pullup, |
---|
1099 | 1108 | .udc_start = atmel_usba_start, |
---|
1100 | 1109 | .udc_stop = atmel_usba_stop, |
---|
1101 | 1110 | .match_ep = atmel_usba_match_ep, |
---|
.. | .. |
---|
1111 | 1120 | .bInterval = 1, |
---|
1112 | 1121 | }; |
---|
1113 | 1122 | |
---|
1114 | | -static struct usb_gadget usba_gadget_template = { |
---|
| 1123 | +static const struct usb_gadget usba_gadget_template = { |
---|
1115 | 1124 | .ops = &usba_udc_ops, |
---|
1116 | 1125 | .max_speed = USB_SPEED_HIGH, |
---|
1117 | 1126 | .name = "atmel_usba_udc", |
---|
.. | .. |
---|
1696 | 1705 | } |
---|
1697 | 1706 | } |
---|
1698 | 1707 | |
---|
| 1708 | +static int start_clock(struct usba_udc *udc); |
---|
| 1709 | +static void stop_clock(struct usba_udc *udc); |
---|
| 1710 | + |
---|
1699 | 1711 | static irqreturn_t usba_udc_irq(int irq, void *devid) |
---|
1700 | 1712 | { |
---|
1701 | 1713 | struct usba_udc *udc = devid; |
---|
.. | .. |
---|
1710 | 1722 | DBG(DBG_INT, "irq, status=%#08x\n", status); |
---|
1711 | 1723 | |
---|
1712 | 1724 | if (status & USBA_DET_SUSPEND) { |
---|
| 1725 | + usba_writel(udc, INT_CLR, USBA_DET_SUSPEND|USBA_WAKE_UP); |
---|
| 1726 | + usba_int_enb_set(udc, USBA_WAKE_UP); |
---|
| 1727 | + usba_int_enb_clear(udc, USBA_DET_SUSPEND); |
---|
| 1728 | + udc->suspended = true; |
---|
1713 | 1729 | toggle_bias(udc, 0); |
---|
1714 | | - usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); |
---|
1715 | | - usba_int_enb_set(udc, int_enb | USBA_WAKE_UP); |
---|
1716 | 1730 | udc->bias_pulse_needed = true; |
---|
| 1731 | + stop_clock(udc); |
---|
1717 | 1732 | DBG(DBG_BUS, "Suspend detected\n"); |
---|
1718 | 1733 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
---|
1719 | 1734 | && udc->driver && udc->driver->suspend) { |
---|
.. | .. |
---|
1724 | 1739 | } |
---|
1725 | 1740 | |
---|
1726 | 1741 | if (status & USBA_WAKE_UP) { |
---|
| 1742 | + start_clock(udc); |
---|
1727 | 1743 | toggle_bias(udc, 1); |
---|
1728 | 1744 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); |
---|
1729 | | - usba_int_enb_set(udc, int_enb & ~USBA_WAKE_UP); |
---|
1730 | 1745 | DBG(DBG_BUS, "Wake Up CPU detected\n"); |
---|
1731 | 1746 | } |
---|
1732 | 1747 | |
---|
1733 | 1748 | if (status & USBA_END_OF_RESUME) { |
---|
| 1749 | + udc->suspended = false; |
---|
1734 | 1750 | usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); |
---|
| 1751 | + usba_int_enb_clear(udc, USBA_WAKE_UP); |
---|
| 1752 | + usba_int_enb_set(udc, USBA_DET_SUSPEND); |
---|
1735 | 1753 | generate_bias_pulse(udc); |
---|
1736 | 1754 | DBG(DBG_BUS, "Resume detected\n"); |
---|
1737 | 1755 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
---|
.. | .. |
---|
1746 | 1764 | if (dma_status) { |
---|
1747 | 1765 | int i; |
---|
1748 | 1766 | |
---|
| 1767 | + usba_int_enb_set(udc, USBA_DET_SUSPEND); |
---|
| 1768 | + |
---|
1749 | 1769 | for (i = 1; i <= USBA_NR_DMAS; i++) |
---|
1750 | 1770 | if (dma_status & (1 << i)) |
---|
1751 | 1771 | usba_dma_irq(udc, &udc->usba_ep[i]); |
---|
.. | .. |
---|
1754 | 1774 | ep_status = USBA_BFEXT(EPT_INT, status); |
---|
1755 | 1775 | if (ep_status) { |
---|
1756 | 1776 | int i; |
---|
| 1777 | + |
---|
| 1778 | + usba_int_enb_set(udc, USBA_DET_SUSPEND); |
---|
1757 | 1779 | |
---|
1758 | 1780 | for (i = 0; i < udc->num_ep; i++) |
---|
1759 | 1781 | if (ep_status & (1 << i)) { |
---|
.. | .. |
---|
1766 | 1788 | |
---|
1767 | 1789 | if (status & USBA_END_OF_RESET) { |
---|
1768 | 1790 | struct usba_ep *ep0, *ep; |
---|
1769 | | - int i, n; |
---|
| 1791 | + int i; |
---|
1770 | 1792 | |
---|
1771 | | - usba_writel(udc, INT_CLR, USBA_END_OF_RESET); |
---|
| 1793 | + usba_writel(udc, INT_CLR, |
---|
| 1794 | + USBA_END_OF_RESET|USBA_END_OF_RESUME |
---|
| 1795 | + |USBA_DET_SUSPEND|USBA_WAKE_UP); |
---|
1772 | 1796 | generate_bias_pulse(udc); |
---|
1773 | 1797 | reset_all_endpoints(udc); |
---|
1774 | 1798 | |
---|
.. | .. |
---|
1795 | 1819 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); |
---|
1796 | 1820 | usba_ep_writel(ep0, CTL_ENB, |
---|
1797 | 1821 | USBA_EPT_ENABLE | USBA_RX_SETUP); |
---|
1798 | | - usba_int_enb_set(udc, int_enb | USBA_BF(EPT_INT, 1) | |
---|
| 1822 | + |
---|
| 1823 | + /* If we get reset while suspended... */ |
---|
| 1824 | + udc->suspended = false; |
---|
| 1825 | + usba_int_enb_clear(udc, USBA_WAKE_UP); |
---|
| 1826 | + |
---|
| 1827 | + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1) | |
---|
1799 | 1828 | USBA_DET_SUSPEND | USBA_END_OF_RESUME); |
---|
1800 | 1829 | |
---|
1801 | 1830 | /* |
---|
.. | .. |
---|
1807 | 1836 | "ODD: EP0 configuration is invalid!\n"); |
---|
1808 | 1837 | |
---|
1809 | 1838 | /* Preallocate other endpoints */ |
---|
1810 | | - n = fifo_mode ? udc->num_ep : udc->configured_ep; |
---|
1811 | | - for (i = 1; i < n; i++) { |
---|
| 1839 | + for (i = 1; i < udc->num_ep; i++) { |
---|
1812 | 1840 | ep = &udc->usba_ep[i]; |
---|
1813 | | - usba_ep_writel(ep, CFG, ep->ept_cfg); |
---|
1814 | | - if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) |
---|
1815 | | - dev_err(&udc->pdev->dev, |
---|
1816 | | - "ODD: EP%d configuration is invalid!\n", i); |
---|
| 1841 | + if (ep->ep.claimed) { |
---|
| 1842 | + usba_ep_writel(ep, CFG, ep->ept_cfg); |
---|
| 1843 | + if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) |
---|
| 1844 | + dev_err(&udc->pdev->dev, |
---|
| 1845 | + "ODD: EP%d configuration is invalid!\n", i); |
---|
| 1846 | + } |
---|
1817 | 1847 | } |
---|
1818 | 1848 | } |
---|
1819 | 1849 | |
---|
.. | .. |
---|
1828 | 1858 | |
---|
1829 | 1859 | if (udc->clocked) |
---|
1830 | 1860 | return 0; |
---|
| 1861 | + |
---|
| 1862 | + pm_stay_awake(&udc->pdev->dev); |
---|
1831 | 1863 | |
---|
1832 | 1864 | ret = clk_prepare_enable(udc->pclk); |
---|
1833 | 1865 | if (ret) |
---|
.. | .. |
---|
1851 | 1883 | clk_disable_unprepare(udc->pclk); |
---|
1852 | 1884 | |
---|
1853 | 1885 | udc->clocked = false; |
---|
| 1886 | + |
---|
| 1887 | + pm_relax(&udc->pdev->dev); |
---|
1854 | 1888 | } |
---|
1855 | 1889 | |
---|
1856 | 1890 | static int usba_start(struct usba_udc *udc) |
---|
.. | .. |
---|
1862 | 1896 | if (ret) |
---|
1863 | 1897 | return ret; |
---|
1864 | 1898 | |
---|
| 1899 | + if (udc->suspended) |
---|
| 1900 | + return 0; |
---|
| 1901 | + |
---|
1865 | 1902 | spin_lock_irqsave(&udc->lock, flags); |
---|
1866 | 1903 | toggle_bias(udc, 1); |
---|
1867 | 1904 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); |
---|
| 1905 | + /* Clear all requested and pending interrupts... */ |
---|
| 1906 | + usba_writel(udc, INT_ENB, 0); |
---|
| 1907 | + udc->int_enb_cache = 0; |
---|
| 1908 | + usba_writel(udc, INT_CLR, |
---|
| 1909 | + USBA_END_OF_RESET|USBA_END_OF_RESUME |
---|
| 1910 | + |USBA_DET_SUSPEND|USBA_WAKE_UP); |
---|
| 1911 | + /* ...and enable just 'reset' IRQ to get us started */ |
---|
1868 | 1912 | usba_int_enb_set(udc, USBA_END_OF_RESET); |
---|
1869 | 1913 | spin_unlock_irqrestore(&udc->lock, flags); |
---|
1870 | 1914 | |
---|
.. | .. |
---|
1874 | 1918 | static void usba_stop(struct usba_udc *udc) |
---|
1875 | 1919 | { |
---|
1876 | 1920 | unsigned long flags; |
---|
| 1921 | + |
---|
| 1922 | + if (udc->suspended) |
---|
| 1923 | + return; |
---|
1877 | 1924 | |
---|
1878 | 1925 | spin_lock_irqsave(&udc->lock, flags); |
---|
1879 | 1926 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
---|
.. | .. |
---|
1902 | 1949 | if (vbus) { |
---|
1903 | 1950 | usba_start(udc); |
---|
1904 | 1951 | } else { |
---|
1905 | | - usba_stop(udc); |
---|
1906 | | - |
---|
| 1952 | + udc->suspended = false; |
---|
1907 | 1953 | if (udc->driver->disconnect) |
---|
1908 | 1954 | udc->driver->disconnect(&udc->gadget); |
---|
| 1955 | + |
---|
| 1956 | + usba_stop(udc); |
---|
1909 | 1957 | } |
---|
1910 | 1958 | udc->vbus_prev = vbus; |
---|
1911 | 1959 | } |
---|
1912 | 1960 | |
---|
1913 | 1961 | mutex_unlock(&udc->vbus_mutex); |
---|
1914 | 1962 | return IRQ_HANDLED; |
---|
| 1963 | +} |
---|
| 1964 | + |
---|
| 1965 | +static int atmel_usba_pullup(struct usb_gadget *gadget, int is_on) |
---|
| 1966 | +{ |
---|
| 1967 | + struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); |
---|
| 1968 | + unsigned long flags; |
---|
| 1969 | + u32 ctrl; |
---|
| 1970 | + |
---|
| 1971 | + spin_lock_irqsave(&udc->lock, flags); |
---|
| 1972 | + ctrl = usba_readl(udc, CTRL); |
---|
| 1973 | + if (is_on) |
---|
| 1974 | + ctrl &= ~USBA_DETACH; |
---|
| 1975 | + else |
---|
| 1976 | + ctrl |= USBA_DETACH; |
---|
| 1977 | + usba_writel(udc, CTRL, ctrl); |
---|
| 1978 | + spin_unlock_irqrestore(&udc->lock, flags); |
---|
| 1979 | + |
---|
| 1980 | + return 0; |
---|
1915 | 1981 | } |
---|
1916 | 1982 | |
---|
1917 | 1983 | static int atmel_usba_start(struct usb_gadget *gadget, |
---|
.. | .. |
---|
1962 | 2028 | if (udc->vbus_pin) |
---|
1963 | 2029 | disable_irq(gpiod_to_irq(udc->vbus_pin)); |
---|
1964 | 2030 | |
---|
1965 | | - if (fifo_mode == 0) |
---|
1966 | | - udc->configured_ep = 1; |
---|
1967 | | - |
---|
| 2031 | + udc->suspended = false; |
---|
1968 | 2032 | usba_stop(udc); |
---|
1969 | 2033 | |
---|
1970 | 2034 | udc->driver = NULL; |
---|
.. | .. |
---|
1993 | 2057 | .pulse_bias = at91sam9g45_pulse_bias, |
---|
1994 | 2058 | }; |
---|
1995 | 2059 | |
---|
| 2060 | +static const struct usba_ep_config ep_config_sam9[] __initconst = { |
---|
| 2061 | + { .nr_banks = 1 }, /* ep 0 */ |
---|
| 2062 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 1 */ |
---|
| 2063 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 2 */ |
---|
| 2064 | + { .nr_banks = 3, .can_dma = 1 }, /* ep 3 */ |
---|
| 2065 | + { .nr_banks = 3, .can_dma = 1 }, /* ep 4 */ |
---|
| 2066 | + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 5 */ |
---|
| 2067 | + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 6 */ |
---|
| 2068 | +}; |
---|
| 2069 | + |
---|
| 2070 | +static const struct usba_ep_config ep_config_sama5[] __initconst = { |
---|
| 2071 | + { .nr_banks = 1 }, /* ep 0 */ |
---|
| 2072 | + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 1 */ |
---|
| 2073 | + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 2 */ |
---|
| 2074 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 3 */ |
---|
| 2075 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 4 */ |
---|
| 2076 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 5 */ |
---|
| 2077 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 6 */ |
---|
| 2078 | + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 7 */ |
---|
| 2079 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 8 */ |
---|
| 2080 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 9 */ |
---|
| 2081 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 10 */ |
---|
| 2082 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 11 */ |
---|
| 2083 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 12 */ |
---|
| 2084 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 13 */ |
---|
| 2085 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 14 */ |
---|
| 2086 | + { .nr_banks = 2, .can_isoc = 1 }, /* ep 15 */ |
---|
| 2087 | +}; |
---|
| 2088 | + |
---|
| 2089 | +static const struct usba_udc_config udc_at91sam9rl_cfg = { |
---|
| 2090 | + .errata = &at91sam9rl_errata, |
---|
| 2091 | + .config = ep_config_sam9, |
---|
| 2092 | + .num_ep = ARRAY_SIZE(ep_config_sam9), |
---|
| 2093 | + .ep_prealloc = true, |
---|
| 2094 | +}; |
---|
| 2095 | + |
---|
| 2096 | +static const struct usba_udc_config udc_at91sam9g45_cfg = { |
---|
| 2097 | + .errata = &at91sam9g45_errata, |
---|
| 2098 | + .config = ep_config_sam9, |
---|
| 2099 | + .num_ep = ARRAY_SIZE(ep_config_sam9), |
---|
| 2100 | + .ep_prealloc = true, |
---|
| 2101 | +}; |
---|
| 2102 | + |
---|
| 2103 | +static const struct usba_udc_config udc_sama5d3_cfg = { |
---|
| 2104 | + .config = ep_config_sama5, |
---|
| 2105 | + .num_ep = ARRAY_SIZE(ep_config_sama5), |
---|
| 2106 | + .ep_prealloc = true, |
---|
| 2107 | +}; |
---|
| 2108 | + |
---|
| 2109 | +static const struct usba_udc_config udc_sam9x60_cfg = { |
---|
| 2110 | + .num_ep = ARRAY_SIZE(ep_config_sam9), |
---|
| 2111 | + .config = ep_config_sam9, |
---|
| 2112 | + .ep_prealloc = false, |
---|
| 2113 | +}; |
---|
| 2114 | + |
---|
1996 | 2115 | static const struct of_device_id atmel_udc_dt_ids[] = { |
---|
1997 | | - { .compatible = "atmel,at91sam9rl-udc", .data = &at91sam9rl_errata }, |
---|
1998 | | - { .compatible = "atmel,at91sam9g45-udc", .data = &at91sam9g45_errata }, |
---|
1999 | | - { .compatible = "atmel,sama5d3-udc" }, |
---|
| 2116 | + { .compatible = "atmel,at91sam9rl-udc", .data = &udc_at91sam9rl_cfg }, |
---|
| 2117 | + { .compatible = "atmel,at91sam9g45-udc", .data = &udc_at91sam9g45_cfg }, |
---|
| 2118 | + { .compatible = "atmel,sama5d3-udc", .data = &udc_sama5d3_cfg }, |
---|
| 2119 | + { .compatible = "microchip,sam9x60-udc", .data = &udc_sam9x60_cfg }, |
---|
2000 | 2120 | { /* sentinel */ } |
---|
2001 | 2121 | }; |
---|
2002 | 2122 | |
---|
2003 | 2123 | MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids); |
---|
2004 | 2124 | |
---|
| 2125 | +static const struct of_device_id atmel_pmc_dt_ids[] = { |
---|
| 2126 | + { .compatible = "atmel,at91sam9g45-pmc" }, |
---|
| 2127 | + { .compatible = "atmel,at91sam9rl-pmc" }, |
---|
| 2128 | + { .compatible = "atmel,at91sam9x5-pmc" }, |
---|
| 2129 | + { /* sentinel */ } |
---|
| 2130 | +}; |
---|
| 2131 | + |
---|
2005 | 2132 | static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, |
---|
2006 | 2133 | struct usba_udc *udc) |
---|
2007 | 2134 | { |
---|
2008 | | - u32 val; |
---|
2009 | | - const char *name; |
---|
2010 | 2135 | struct device_node *np = pdev->dev.of_node; |
---|
2011 | 2136 | const struct of_device_id *match; |
---|
2012 | 2137 | struct device_node *pp; |
---|
2013 | 2138 | int i, ret; |
---|
2014 | 2139 | struct usba_ep *eps, *ep; |
---|
| 2140 | + const struct usba_udc_config *udc_config; |
---|
2015 | 2141 | |
---|
2016 | 2142 | match = of_match_node(atmel_udc_dt_ids, np); |
---|
2017 | 2143 | if (!match) |
---|
2018 | 2144 | return ERR_PTR(-EINVAL); |
---|
2019 | 2145 | |
---|
2020 | | - udc->errata = match->data; |
---|
2021 | | - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc"); |
---|
2022 | | - if (IS_ERR(udc->pmc)) |
---|
2023 | | - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9rl-pmc"); |
---|
2024 | | - if (IS_ERR(udc->pmc)) |
---|
2025 | | - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9x5-pmc"); |
---|
2026 | | - if (udc->errata && IS_ERR(udc->pmc)) |
---|
2027 | | - return ERR_CAST(udc->pmc); |
---|
| 2146 | + udc_config = match->data; |
---|
| 2147 | + udc->ep_prealloc = udc_config->ep_prealloc; |
---|
| 2148 | + udc->errata = udc_config->errata; |
---|
| 2149 | + if (udc->errata) { |
---|
| 2150 | + pp = of_find_matching_node_and_match(NULL, atmel_pmc_dt_ids, |
---|
| 2151 | + NULL); |
---|
| 2152 | + if (!pp) |
---|
| 2153 | + return ERR_PTR(-ENODEV); |
---|
| 2154 | + |
---|
| 2155 | + udc->pmc = syscon_node_to_regmap(pp); |
---|
| 2156 | + of_node_put(pp); |
---|
| 2157 | + if (IS_ERR(udc->pmc)) |
---|
| 2158 | + return ERR_CAST(udc->pmc); |
---|
| 2159 | + } |
---|
2028 | 2160 | |
---|
2029 | 2161 | udc->num_ep = 0; |
---|
2030 | 2162 | |
---|
.. | .. |
---|
2032 | 2164 | GPIOD_IN); |
---|
2033 | 2165 | |
---|
2034 | 2166 | if (fifo_mode == 0) { |
---|
2035 | | - pp = NULL; |
---|
2036 | | - while ((pp = of_get_next_child(np, pp))) |
---|
2037 | | - udc->num_ep++; |
---|
2038 | | - udc->configured_ep = 1; |
---|
| 2167 | + udc->num_ep = udc_config->num_ep; |
---|
2039 | 2168 | } else { |
---|
2040 | 2169 | udc->num_ep = usba_config_fifo_table(udc); |
---|
2041 | 2170 | } |
---|
.. | .. |
---|
2049 | 2178 | |
---|
2050 | 2179 | INIT_LIST_HEAD(&eps[0].ep.ep_list); |
---|
2051 | 2180 | |
---|
2052 | | - pp = NULL; |
---|
2053 | 2181 | i = 0; |
---|
2054 | | - while ((pp = of_get_next_child(np, pp)) && i < udc->num_ep) { |
---|
| 2182 | + while (i < udc->num_ep) { |
---|
| 2183 | + const struct usba_ep_config *ep_cfg = &udc_config->config[i]; |
---|
| 2184 | + |
---|
2055 | 2185 | ep = &eps[i]; |
---|
2056 | 2186 | |
---|
2057 | | - ret = of_property_read_u32(pp, "reg", &val); |
---|
2058 | | - if (ret) { |
---|
2059 | | - dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret); |
---|
2060 | | - goto err; |
---|
2061 | | - } |
---|
2062 | | - ep->index = fifo_mode ? udc->fifo_cfg[i].hw_ep_num : val; |
---|
| 2187 | + ep->index = fifo_mode ? udc->fifo_cfg[i].hw_ep_num : i; |
---|
2063 | 2188 | |
---|
2064 | | - ret = of_property_read_u32(pp, "atmel,fifo-size", &val); |
---|
2065 | | - if (ret) { |
---|
2066 | | - dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret); |
---|
2067 | | - goto err; |
---|
2068 | | - } |
---|
| 2189 | + /* Only the first EP is 64 bytes */ |
---|
| 2190 | + if (ep->index == 0) |
---|
| 2191 | + ep->fifo_size = 64; |
---|
| 2192 | + else |
---|
| 2193 | + ep->fifo_size = 1024; |
---|
| 2194 | + |
---|
2069 | 2195 | if (fifo_mode) { |
---|
2070 | | - if (val < udc->fifo_cfg[i].fifo_size) { |
---|
| 2196 | + if (ep->fifo_size < udc->fifo_cfg[i].fifo_size) |
---|
2071 | 2197 | dev_warn(&pdev->dev, |
---|
2072 | | - "Using max fifo-size value from DT\n"); |
---|
2073 | | - ep->fifo_size = val; |
---|
2074 | | - } else { |
---|
| 2198 | + "Using default max fifo-size value\n"); |
---|
| 2199 | + else |
---|
2075 | 2200 | ep->fifo_size = udc->fifo_cfg[i].fifo_size; |
---|
2076 | | - } |
---|
2077 | | - } else { |
---|
2078 | | - ep->fifo_size = val; |
---|
2079 | 2201 | } |
---|
2080 | 2202 | |
---|
2081 | | - ret = of_property_read_u32(pp, "atmel,nb-banks", &val); |
---|
2082 | | - if (ret) { |
---|
2083 | | - dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret); |
---|
2084 | | - goto err; |
---|
2085 | | - } |
---|
| 2203 | + ep->nr_banks = ep_cfg->nr_banks; |
---|
2086 | 2204 | if (fifo_mode) { |
---|
2087 | | - if (val < udc->fifo_cfg[i].nr_banks) { |
---|
| 2205 | + if (ep->nr_banks < udc->fifo_cfg[i].nr_banks) |
---|
2088 | 2206 | dev_warn(&pdev->dev, |
---|
2089 | | - "Using max nb-banks value from DT\n"); |
---|
2090 | | - ep->nr_banks = val; |
---|
2091 | | - } else { |
---|
| 2207 | + "Using default max nb-banks value\n"); |
---|
| 2208 | + else |
---|
2092 | 2209 | ep->nr_banks = udc->fifo_cfg[i].nr_banks; |
---|
2093 | | - } |
---|
2094 | | - } else { |
---|
2095 | | - ep->nr_banks = val; |
---|
2096 | 2210 | } |
---|
2097 | 2211 | |
---|
2098 | | - ep->can_dma = of_property_read_bool(pp, "atmel,can-dma"); |
---|
2099 | | - ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc"); |
---|
| 2212 | + ep->can_dma = ep_cfg->can_dma; |
---|
| 2213 | + ep->can_isoc = ep_cfg->can_isoc; |
---|
2100 | 2214 | |
---|
2101 | | - ret = of_property_read_string(pp, "name", &name); |
---|
2102 | | - if (ret) { |
---|
2103 | | - dev_err(&pdev->dev, "of_probe: name error(%d)\n", ret); |
---|
2104 | | - goto err; |
---|
2105 | | - } |
---|
2106 | 2215 | sprintf(ep->name, "ep%d", ep->index); |
---|
2107 | 2216 | ep->ep.name = ep->name; |
---|
2108 | 2217 | |
---|
.. | .. |
---|
2284 | 2393 | mutex_lock(&udc->vbus_mutex); |
---|
2285 | 2394 | |
---|
2286 | 2395 | if (!device_may_wakeup(dev)) { |
---|
| 2396 | + udc->suspended = false; |
---|
2287 | 2397 | usba_stop(udc); |
---|
2288 | 2398 | goto out; |
---|
2289 | 2399 | } |
---|
.. | .. |
---|
2293 | 2403 | * to request vbus irq, assuming always on. |
---|
2294 | 2404 | */ |
---|
2295 | 2405 | if (udc->vbus_pin) { |
---|
| 2406 | + /* FIXME: right to stop here...??? */ |
---|
2296 | 2407 | usba_stop(udc); |
---|
2297 | 2408 | enable_irq_wake(gpiod_to_irq(udc->vbus_pin)); |
---|
2298 | 2409 | } |
---|
| 2410 | + |
---|
| 2411 | + enable_irq_wake(udc->irq); |
---|
2299 | 2412 | |
---|
2300 | 2413 | out: |
---|
2301 | 2414 | mutex_unlock(&udc->vbus_mutex); |
---|
.. | .. |
---|
2310 | 2423 | if (!udc->driver) |
---|
2311 | 2424 | return 0; |
---|
2312 | 2425 | |
---|
2313 | | - if (device_may_wakeup(dev) && udc->vbus_pin) |
---|
2314 | | - disable_irq_wake(gpiod_to_irq(udc->vbus_pin)); |
---|
| 2426 | + if (device_may_wakeup(dev)) { |
---|
| 2427 | + if (udc->vbus_pin) |
---|
| 2428 | + disable_irq_wake(gpiod_to_irq(udc->vbus_pin)); |
---|
| 2429 | + |
---|
| 2430 | + disable_irq_wake(udc->irq); |
---|
| 2431 | + } |
---|
2315 | 2432 | |
---|
2316 | 2433 | /* If Vbus is present, enable the controller and wait for reset */ |
---|
2317 | 2434 | mutex_lock(&udc->vbus_mutex); |
---|