Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: gadget: at91_udc: Rework for multi-platform kernel support

cpu_is_at91xxx are a set of macros defined in mach/cpu.h and are here used
to detect the SoC we are booting on.
Use compatible string + a caps structure to replace those cpu_is_xxx tests.

Remove all mach and asm headers (which are now unused).

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>

authored by

Boris Brezillon and committed by
Nicolas Ferre
f0bceab4 422cde25

+218 -77
+211 -77
drivers/usb/gadget/udc/at91_udc.c
··· 31 31 #include <linux/of.h> 32 32 #include <linux/of_gpio.h> 33 33 #include <linux/platform_data/atmel.h> 34 - 35 - #include <asm/byteorder.h> 36 - #include <mach/hardware.h> 37 - #include <asm/io.h> 38 - #include <asm/irq.h> 39 - #include <asm/gpio.h> 40 - 41 - #include <mach/cpu.h> 42 - #include <mach/at91sam9261_matrix.h> 43 - #include <mach/at91_matrix.h> 34 + #include <linux/regmap.h> 35 + #include <linux/mfd/syscon.h> 36 + #include <linux/mfd/syscon/atmel-matrix.h> 44 37 45 38 #include "at91_udc.h" 46 39 ··· 908 915 */ 909 916 static void pullup(struct at91_udc *udc, int is_on) 910 917 { 911 - int active = !udc->board.pullup_active_low; 912 - 913 918 if (!udc->enabled || !udc->vbus) 914 919 is_on = 0; 915 920 DBG("%sactive\n", is_on ? "" : "in"); ··· 916 925 clk_on(udc); 917 926 at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); 918 927 at91_udp_write(udc, AT91_UDP_TXVC, 0); 919 - if (cpu_is_at91rm9200()) 920 - gpio_set_value(udc->board.pullup_pin, active); 921 - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { 922 - u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); 923 - 924 - txvc |= AT91_UDP_TXVC_PUON; 925 - at91_udp_write(udc, AT91_UDP_TXVC, txvc); 926 - } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { 927 - u32 usbpucr; 928 - 929 - usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR); 930 - usbpucr |= AT91_MATRIX_USBPUCR_PUON; 931 - at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr); 932 - } 933 928 } else { 934 929 stop_activity(udc); 935 930 at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); 936 931 at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); 937 - if (cpu_is_at91rm9200()) 938 - gpio_set_value(udc->board.pullup_pin, !active); 939 - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { 940 - u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); 941 - 942 - txvc &= ~AT91_UDP_TXVC_PUON; 943 - at91_udp_write(udc, AT91_UDP_TXVC, txvc); 944 - } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { 945 - u32 usbpucr; 946 - 947 - usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR); 948 - usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; 949 - at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr); 950 - } 951 932 clk_off(udc); 952 933 } 934 + 935 + if (udc->caps && udc->caps->pullup) 936 + udc->caps->pullup(udc, is_on); 953 937 } 954 938 955 939 /* vbus is here! turn everything on that's ready */ ··· 1649 1683 spin_unlock_irqrestore(&udc->lock, flags); 1650 1684 } 1651 1685 1652 - static void at91udc_of_init(struct at91_udc *udc, 1653 - struct device_node *np) 1686 + static int at91rm9200_udc_init(struct at91_udc *udc) 1687 + { 1688 + struct at91_ep *ep; 1689 + int ret; 1690 + int i; 1691 + 1692 + for (i = 0; i < NUM_ENDPOINTS; i++) { 1693 + ep = &udc->ep[i]; 1694 + 1695 + switch (i) { 1696 + case 0: 1697 + case 3: 1698 + ep->maxpacket = 8; 1699 + break; 1700 + case 1 ... 2: 1701 + ep->maxpacket = 64; 1702 + break; 1703 + case 4 ... 5: 1704 + ep->maxpacket = 256; 1705 + break; 1706 + } 1707 + } 1708 + 1709 + if (!gpio_is_valid(udc->board.pullup_pin)) { 1710 + DBG("no D+ pullup?\n"); 1711 + return -ENODEV; 1712 + } 1713 + 1714 + ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin, 1715 + "udc_pullup"); 1716 + if (ret) { 1717 + DBG("D+ pullup is busy\n"); 1718 + return ret; 1719 + } 1720 + 1721 + gpio_direction_output(udc->board.pullup_pin, 1722 + udc->board.pullup_active_low); 1723 + 1724 + return 0; 1725 + } 1726 + 1727 + static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on) 1728 + { 1729 + int active = !udc->board.pullup_active_low; 1730 + 1731 + if (is_on) 1732 + gpio_set_value(udc->board.pullup_pin, active); 1733 + else 1734 + gpio_set_value(udc->board.pullup_pin, !active); 1735 + } 1736 + 1737 + static const struct at91_udc_caps at91rm9200_udc_caps = { 1738 + .init = at91rm9200_udc_init, 1739 + .pullup = at91rm9200_udc_pullup, 1740 + }; 1741 + 1742 + static int at91sam9260_udc_init(struct at91_udc *udc) 1743 + { 1744 + struct at91_ep *ep; 1745 + int i; 1746 + 1747 + for (i = 0; i < NUM_ENDPOINTS; i++) { 1748 + ep = &udc->ep[i]; 1749 + 1750 + switch (i) { 1751 + case 0 ... 3: 1752 + ep->maxpacket = 64; 1753 + break; 1754 + case 4 ... 5: 1755 + ep->maxpacket = 512; 1756 + break; 1757 + } 1758 + } 1759 + 1760 + return 0; 1761 + } 1762 + 1763 + static void at91sam9260_udc_pullup(struct at91_udc *udc, int is_on) 1764 + { 1765 + u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); 1766 + 1767 + if (is_on) 1768 + txvc |= AT91_UDP_TXVC_PUON; 1769 + else 1770 + txvc &= ~AT91_UDP_TXVC_PUON; 1771 + 1772 + at91_udp_write(udc, AT91_UDP_TXVC, txvc); 1773 + } 1774 + 1775 + static const struct at91_udc_caps at91sam9260_udc_caps = { 1776 + .init = at91sam9260_udc_init, 1777 + .pullup = at91sam9260_udc_pullup, 1778 + }; 1779 + 1780 + static int at91sam9261_udc_init(struct at91_udc *udc) 1781 + { 1782 + struct at91_ep *ep; 1783 + int i; 1784 + 1785 + for (i = 0; i < NUM_ENDPOINTS; i++) { 1786 + ep = &udc->ep[i]; 1787 + 1788 + switch (i) { 1789 + case 0: 1790 + ep->maxpacket = 8; 1791 + break; 1792 + case 1 ... 3: 1793 + ep->maxpacket = 64; 1794 + break; 1795 + case 4 ... 5: 1796 + ep->maxpacket = 256; 1797 + break; 1798 + } 1799 + } 1800 + 1801 + udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node, 1802 + "atmel,matrix"); 1803 + if (IS_ERR(udc->matrix)) 1804 + return PTR_ERR(udc->matrix); 1805 + 1806 + return 0; 1807 + } 1808 + 1809 + static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on) 1810 + { 1811 + u32 usbpucr = 0; 1812 + 1813 + if (is_on) 1814 + usbpucr = AT91_MATRIX_USBPUCR_PUON; 1815 + 1816 + regmap_update_bits(udc->matrix, AT91SAM9261_MATRIX_USBPUCR, 1817 + AT91_MATRIX_USBPUCR_PUON, usbpucr); 1818 + } 1819 + 1820 + static const struct at91_udc_caps at91sam9261_udc_caps = { 1821 + .init = at91sam9261_udc_init, 1822 + .pullup = at91sam9261_udc_pullup, 1823 + }; 1824 + 1825 + static int at91sam9263_udc_init(struct at91_udc *udc) 1826 + { 1827 + struct at91_ep *ep; 1828 + int i; 1829 + 1830 + for (i = 0; i < NUM_ENDPOINTS; i++) { 1831 + ep = &udc->ep[i]; 1832 + 1833 + switch (i) { 1834 + case 0: 1835 + case 1: 1836 + case 2: 1837 + case 3: 1838 + ep->maxpacket = 64; 1839 + break; 1840 + case 4: 1841 + case 5: 1842 + ep->maxpacket = 256; 1843 + break; 1844 + } 1845 + } 1846 + 1847 + return 0; 1848 + } 1849 + 1850 + static const struct at91_udc_caps at91sam9263_udc_caps = { 1851 + .init = at91sam9263_udc_init, 1852 + .pullup = at91sam9260_udc_pullup, 1853 + }; 1854 + 1855 + static const struct of_device_id at91_udc_dt_ids[] = { 1856 + { 1857 + .compatible = "atmel,at91rm9200-udc", 1858 + .data = &at91rm9200_udc_caps, 1859 + }, 1860 + { 1861 + .compatible = "atmel,at91sam9260-udc", 1862 + .data = &at91sam9260_udc_caps, 1863 + }, 1864 + { 1865 + .compatible = "atmel,at91sam9261-udc", 1866 + .data = &at91sam9261_udc_caps, 1867 + }, 1868 + { 1869 + .compatible = "atmel,at91sam9263-udc", 1870 + .data = &at91sam9263_udc_caps, 1871 + }, 1872 + { /* sentinel */ } 1873 + }; 1874 + MODULE_DEVICE_TABLE(of, at91_udc_dt_ids); 1875 + 1876 + static void at91udc_of_init(struct at91_udc *udc, struct device_node *np) 1654 1877 { 1655 1878 struct at91_udc_data *board = &udc->board; 1656 - u32 val; 1879 + const struct of_device_id *match; 1657 1880 enum of_gpio_flags flags; 1881 + u32 val; 1658 1882 1659 1883 if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0) 1660 1884 board->vbus_polled = 1; ··· 1857 1701 &flags); 1858 1702 1859 1703 board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; 1704 + 1705 + match = of_match_node(at91_udc_dt_ids, np); 1706 + if (match) 1707 + udc->caps = match->data; 1860 1708 } 1861 1709 1862 1710 static int at91udc_probe(struct platform_device *pdev) ··· 1869 1709 struct at91_udc *udc; 1870 1710 int retval; 1871 1711 struct resource *res; 1712 + struct at91_ep *ep; 1713 + int i; 1872 1714 1873 1715 /* init software state */ 1874 1716 udc = &controller; ··· 1880 1718 udc->enabled = 0; 1881 1719 spin_lock_init(&udc->lock); 1882 1720 1883 - /* rm9200 needs manual D+ pullup; off by default */ 1884 - if (cpu_is_at91rm9200()) { 1885 - if (!gpio_is_valid(udc->board.pullup_pin)) { 1886 - DBG("no D+ pullup?\n"); 1887 - return -ENODEV; 1888 - } 1889 - retval = devm_gpio_request(dev, udc->board.pullup_pin, 1890 - "udc_pullup"); 1891 - if (retval) { 1892 - DBG("D+ pullup is busy\n"); 1893 - return retval; 1894 - } 1895 - gpio_direction_output(udc->board.pullup_pin, 1896 - udc->board.pullup_active_low); 1897 - } 1898 1721 1899 - /* newer chips have more FIFO memory than rm9200 */ 1900 - if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) { 1901 - udc->ep[0].maxpacket = 64; 1902 - udc->ep[3].maxpacket = 64; 1903 - udc->ep[4].maxpacket = 512; 1904 - udc->ep[5].maxpacket = 512; 1905 - } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { 1906 - udc->ep[3].maxpacket = 64; 1907 - } else if (cpu_is_at91sam9263()) { 1908 - udc->ep[0].maxpacket = 64; 1909 - udc->ep[3].maxpacket = 64; 1910 - } 1911 1722 1912 1723 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1913 1724 udc->udp_baseaddr = devm_ioremap_resource(dev, res); 1914 1725 if (IS_ERR(udc->udp_baseaddr)) 1915 1726 return PTR_ERR(udc->udp_baseaddr); 1727 + 1728 + if (udc->caps && udc->caps->init) { 1729 + retval = udc->caps->init(udc); 1730 + if (retval) 1731 + return retval; 1732 + } 1916 1733 1917 1734 udc_reinit(udc); 1918 1735 ··· 2060 1919 #define at91udc_suspend NULL 2061 1920 #define at91udc_resume NULL 2062 1921 #endif 2063 - 2064 - static const struct of_device_id at91_udc_dt_ids[] = { 2065 - { .compatible = "atmel,at91rm9200-udc" }, 2066 - { /* sentinel */ } 2067 - }; 2068 - 2069 - MODULE_DEVICE_TABLE(of, at91_udc_dt_ids); 2070 1922 2071 1923 static struct platform_driver at91_udc_driver = { 2072 1924 .remove = __exit_p(at91udc_remove),
+7
drivers/usb/gadget/udc/at91_udc.h
··· 107 107 unsigned fifo_bank:1; 108 108 }; 109 109 110 + struct at91_udc_caps { 111 + int (*init)(struct at91_udc *udc); 112 + void (*pullup)(struct at91_udc *udc, int is_on); 113 + }; 114 + 110 115 /* 111 116 * driver is non-SMP, and just blocks IRQs whenever it needs 112 117 * access protection for chip registers or driver state ··· 120 115 struct usb_gadget gadget; 121 116 struct at91_ep ep[NUM_ENDPOINTS]; 122 117 struct usb_gadget_driver *driver; 118 + const struct at91_udc_caps *caps; 123 119 unsigned vbus:1; 124 120 unsigned enabled:1; 125 121 unsigned clocked:1; ··· 140 134 spinlock_t lock; 141 135 struct timer_list vbus_timer; 142 136 struct work_struct vbus_timer_work; 137 + struct regmap *matrix; 143 138 }; 144 139 145 140 static inline struct at91_udc *to_udc(struct usb_gadget *g)