diff options
| author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-05-03 08:22:57 -0400 |
|---|---|---|
| committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-05-23 19:14:45 -0400 |
| commit | 4a3ae9324ebeb9715369d2bca799bfd7dcff6dd7 (patch) | |
| tree | 9c704f18b2b581f5bc0e04abc6c60861c7b05a60 | |
| parent | e8f2ea39327a1f76aa9f0c606812eb0b154b8e45 (diff) | |
USB: gadget: atmel_usba: add DT support
Allow to compile the driver all the time if AT91 enabled.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Tested-by: Bo Shen <voice.shen@atmel.com>
| -rw-r--r-- | Documentation/devicetree/bindings/usb/atmel-usb.txt | 82 | ||||
| -rw-r--r-- | drivers/usb/gadget/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 220 | ||||
| -rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.h | 1 |
4 files changed, 245 insertions, 60 deletions
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt index 60bd2150a3e6..55f51af08bc7 100644 --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt | |||
| @@ -47,3 +47,85 @@ usb1: gadget@fffa4000 { | |||
| 47 | interrupts = <10 4>; | 47 | interrupts = <10 4>; |
| 48 | atmel,vbus-gpio = <&pioC 5 0>; | 48 | atmel,vbus-gpio = <&pioC 5 0>; |
| 49 | }; | 49 | }; |
| 50 | |||
| 51 | Atmel High-Speed USB device controller | ||
| 52 | |||
| 53 | Required properties: | ||
| 54 | - compatible: Should be "atmel,at91sam9rl-udc" | ||
| 55 | - reg: Address and length of the register set for the device | ||
| 56 | - interrupts: Should contain usba interrupt | ||
| 57 | - ep childnode: To specify the number of endpoints and their properties. | ||
| 58 | |||
| 59 | Optional properties: | ||
| 60 | - atmel,vbus-gpio: If present, specifies a gpio that needs to be | ||
| 61 | activated for the bus to be powered. | ||
| 62 | |||
| 63 | Required child node properties: | ||
| 64 | - name: Name of the endpoint. | ||
| 65 | - reg: Num of the endpoint. | ||
| 66 | - atmel,fifo-size: Size of the fifo. | ||
| 67 | - atmel,nb-banks: Number of banks. | ||
| 68 | - atmel,can-dma: Boolean to specify if the endpoint support DMA. | ||
| 69 | - atmel,can-isoc: Boolean to specify if the endpoint support ISOC. | ||
| 70 | |||
| 71 | usb2: gadget@fff78000 { | ||
| 72 | #address-cells = <1>; | ||
| 73 | #size-cells = <0>; | ||
| 74 | compatible = "atmel,at91sam9rl-udc"; | ||
| 75 | reg = <0x00600000 0x80000 | ||
| 76 | 0xfff78000 0x400>; | ||
| 77 | interrupts = <27 4 0>; | ||
| 78 | atmel,vbus-gpio = <&pioB 19 0>; | ||
| 79 | |||
| 80 | ep0 { | ||
| 81 | reg = <0>; | ||
| 82 | atmel,fifo-size = <64>; | ||
| 83 | atmel,nb-banks = <1>; | ||
| 84 | }; | ||
| 85 | |||
| 86 | ep1 { | ||
| 87 | reg = <1>; | ||
| 88 | atmel,fifo-size = <1024>; | ||
| 89 | atmel,nb-banks = <2>; | ||
| 90 | atmel,can-dma; | ||
| 91 | atmel,can-isoc; | ||
| 92 | }; | ||
| 93 | |||
| 94 | ep2 { | ||
| 95 | reg = <2>; | ||
| 96 | atmel,fifo-size = <1024>; | ||
| 97 | atmel,nb-banks = <2>; | ||
| 98 | atmel,can-dma; | ||
| 99 | atmel,can-isoc; | ||
| 100 | }; | ||
| 101 | |||
| 102 | ep3 { | ||
| 103 | reg = <3>; | ||
| 104 | atmel,fifo-size = <1024>; | ||
| 105 | atmel,nb-banks = <3>; | ||
| 106 | atmel,can-dma; | ||
| 107 | }; | ||
| 108 | |||
| 109 | ep4 { | ||
| 110 | reg = <4>; | ||
| 111 | atmel,fifo-size = <1024>; | ||
| 112 | atmel,nb-banks = <3>; | ||
| 113 | atmel,can-dma; | ||
| 114 | }; | ||
| 115 | |||
| 116 | ep5 { | ||
| 117 | reg = <5>; | ||
| 118 | atmel,fifo-size = <1024>; | ||
| 119 | atmel,nb-banks = <3>; | ||
| 120 | atmel,can-dma; | ||
| 121 | atmel,can-isoc; | ||
| 122 | }; | ||
| 123 | |||
| 124 | ep6 { | ||
| 125 | reg = <6>; | ||
| 126 | atmel,fifo-size = <1024>; | ||
| 127 | atmel,nb-banks = <3>; | ||
| 128 | atmel,can-dma; | ||
| 129 | atmel,can-isoc; | ||
| 130 | }; | ||
| 131 | }; | ||
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 83300d94a893..5e47d50f01ca 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -156,7 +156,7 @@ config USB_LPC32XX | |||
| 156 | 156 | ||
| 157 | config USB_ATMEL_USBA | 157 | config USB_ATMEL_USBA |
| 158 | tristate "Atmel USBA" | 158 | tristate "Atmel USBA" |
| 159 | depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 | 159 | depends on AVR32 || ARCH_AT91 |
| 160 | help | 160 | help |
| 161 | USBA is the integrated high-speed USB Device controller on | 161 | USBA is the integrated high-speed USB Device controller on |
| 162 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | 162 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index eea57a3ca778..f89ce5eb2704 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include <linux/usb/atmel_usba_udc.h> | 22 | #include <linux/usb/atmel_usba_udc.h> |
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | #include <linux/platform_data/atmel.h> | 24 | #include <linux/platform_data/atmel.h> |
| 25 | #include <linux/of.h> | ||
| 26 | #include <linux/of_gpio.h> | ||
| 25 | 27 | ||
| 26 | #include <asm/gpio.h> | 28 | #include <asm/gpio.h> |
| 27 | 29 | ||
| @@ -1828,13 +1830,146 @@ static int atmel_usba_stop(struct usb_gadget *gadget, | |||
| 1828 | return 0; | 1830 | return 0; |
| 1829 | } | 1831 | } |
| 1830 | 1832 | ||
| 1831 | static int __init usba_udc_probe(struct platform_device *pdev) | 1833 | #ifdef CONFIG_OF |
| 1834 | static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | ||
| 1835 | struct usba_udc *udc) | ||
| 1836 | { | ||
| 1837 | u32 val; | ||
| 1838 | const char *name; | ||
| 1839 | enum of_gpio_flags flags; | ||
| 1840 | struct device_node *np = pdev->dev.of_node; | ||
| 1841 | struct device_node *pp; | ||
| 1842 | int i, ret; | ||
| 1843 | struct usba_ep *eps, *ep; | ||
| 1844 | |||
| 1845 | udc->num_ep = 0; | ||
| 1846 | |||
| 1847 | udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0, | ||
| 1848 | &flags); | ||
| 1849 | udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; | ||
| 1850 | |||
| 1851 | pp = NULL; | ||
| 1852 | while ((pp = of_get_next_child(np, pp))) | ||
| 1853 | udc->num_ep++; | ||
| 1854 | |||
| 1855 | eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep, | ||
| 1856 | GFP_KERNEL); | ||
| 1857 | if (!eps) | ||
| 1858 | return ERR_PTR(-ENOMEM); | ||
| 1859 | |||
| 1860 | udc->gadget.ep0 = &eps[0].ep; | ||
| 1861 | |||
| 1862 | INIT_LIST_HEAD(&eps[0].ep.ep_list); | ||
| 1863 | |||
| 1864 | pp = NULL; | ||
| 1865 | i = 0; | ||
| 1866 | while ((pp = of_get_next_child(np, pp))) { | ||
| 1867 | ep = &eps[i]; | ||
| 1868 | |||
| 1869 | ret = of_property_read_u32(pp, "reg", &val); | ||
| 1870 | if (ret) { | ||
| 1871 | dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret); | ||
| 1872 | goto err; | ||
| 1873 | } | ||
| 1874 | ep->index = val; | ||
| 1875 | |||
| 1876 | ret = of_property_read_u32(pp, "atmel,fifo-size", &val); | ||
| 1877 | if (ret) { | ||
| 1878 | dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret); | ||
| 1879 | goto err; | ||
| 1880 | } | ||
| 1881 | ep->fifo_size = val; | ||
| 1882 | |||
| 1883 | ret = of_property_read_u32(pp, "atmel,nb-banks", &val); | ||
| 1884 | if (ret) { | ||
| 1885 | dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret); | ||
| 1886 | goto err; | ||
| 1887 | } | ||
| 1888 | ep->nr_banks = val; | ||
| 1889 | |||
| 1890 | ep->can_dma = of_property_read_bool(pp, "atmel,can-dma"); | ||
| 1891 | ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc"); | ||
| 1892 | |||
| 1893 | ret = of_property_read_string(pp, "name", &name); | ||
| 1894 | ep->ep.name = name; | ||
| 1895 | |||
| 1896 | ep->ep_regs = udc->regs + USBA_EPT_BASE(i); | ||
| 1897 | ep->dma_regs = udc->regs + USBA_DMA_BASE(i); | ||
| 1898 | ep->fifo = udc->fifo + USBA_FIFO_BASE(i); | ||
| 1899 | ep->ep.ops = &usba_ep_ops; | ||
| 1900 | ep->ep.maxpacket = ep->fifo_size; | ||
| 1901 | ep->udc = udc; | ||
| 1902 | INIT_LIST_HEAD(&ep->queue); | ||
| 1903 | |||
| 1904 | if (i) | ||
| 1905 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
| 1906 | |||
| 1907 | i++; | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | return eps; | ||
| 1911 | err: | ||
| 1912 | return ERR_PTR(ret); | ||
| 1913 | } | ||
| 1914 | #else | ||
| 1915 | static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | ||
| 1916 | struct usba_udc *udc) | ||
| 1917 | { | ||
| 1918 | return ERR_PTR(-ENOSYS); | ||
| 1919 | } | ||
| 1920 | #endif | ||
| 1921 | |||
| 1922 | static struct usba_ep * usba_udc_pdata(struct platform_device *pdev, | ||
| 1923 | struct usba_udc *udc) | ||
| 1832 | { | 1924 | { |
| 1833 | struct usba_platform_data *pdata = pdev->dev.platform_data; | 1925 | struct usba_platform_data *pdata = pdev->dev.platform_data; |
| 1926 | struct usba_ep *eps; | ||
| 1927 | int i; | ||
| 1928 | |||
| 1929 | if (!pdata) | ||
| 1930 | return ERR_PTR(-ENXIO); | ||
| 1931 | |||
| 1932 | eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep, | ||
| 1933 | GFP_KERNEL); | ||
| 1934 | if (!eps) | ||
| 1935 | return ERR_PTR(-ENOMEM); | ||
| 1936 | |||
| 1937 | udc->gadget.ep0 = &eps[0].ep; | ||
| 1938 | |||
| 1939 | udc->vbus_pin = pdata->vbus_pin; | ||
| 1940 | udc->vbus_pin_inverted = pdata->vbus_pin_inverted; | ||
| 1941 | udc->num_ep = pdata->num_ep; | ||
| 1942 | |||
| 1943 | INIT_LIST_HEAD(&eps[0].ep.ep_list); | ||
| 1944 | |||
| 1945 | for (i = 0; i < pdata->num_ep; i++) { | ||
| 1946 | struct usba_ep *ep = &eps[i]; | ||
| 1947 | |||
| 1948 | ep->ep_regs = udc->regs + USBA_EPT_BASE(i); | ||
| 1949 | ep->dma_regs = udc->regs + USBA_DMA_BASE(i); | ||
| 1950 | ep->fifo = udc->fifo + USBA_FIFO_BASE(i); | ||
| 1951 | ep->ep.ops = &usba_ep_ops; | ||
| 1952 | ep->ep.name = pdata->ep[i].name; | ||
| 1953 | ep->fifo_size = ep->ep.maxpacket = pdata->ep[i].fifo_size; | ||
| 1954 | ep->udc = udc; | ||
| 1955 | INIT_LIST_HEAD(&ep->queue); | ||
| 1956 | ep->nr_banks = pdata->ep[i].nr_banks; | ||
| 1957 | ep->index = pdata->ep[i].index; | ||
| 1958 | ep->can_dma = pdata->ep[i].can_dma; | ||
| 1959 | ep->can_isoc = pdata->ep[i].can_isoc; | ||
| 1960 | |||
| 1961 | if (i) | ||
| 1962 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
| 1963 | } | ||
| 1964 | |||
| 1965 | return eps; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | static int __init usba_udc_probe(struct platform_device *pdev) | ||
| 1969 | { | ||
| 1834 | struct resource *regs, *fifo; | 1970 | struct resource *regs, *fifo; |
| 1835 | struct clk *pclk, *hclk; | 1971 | struct clk *pclk, *hclk; |
| 1836 | struct usba_udc *udc; | 1972 | struct usba_udc *udc; |
| 1837 | static struct usba_ep *usba_ep; | ||
| 1838 | int irq, ret, i; | 1973 | int irq, ret, i; |
| 1839 | 1974 | ||
| 1840 | udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); | 1975 | udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); |
| @@ -1846,7 +1981,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
| 1846 | 1981 | ||
| 1847 | regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); | 1982 | regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); |
| 1848 | fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); | 1983 | fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); |
| 1849 | if (!regs || !fifo || !pdata) | 1984 | if (!regs || !fifo) |
| 1850 | return -ENXIO; | 1985 | return -ENXIO; |
| 1851 | 1986 | ||
| 1852 | irq = platform_get_irq(pdev, 0); | 1987 | irq = platform_get_irq(pdev, 0); |
| @@ -1892,47 +2027,14 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
| 1892 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 2027 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
| 1893 | clk_disable(pclk); | 2028 | clk_disable(pclk); |
| 1894 | 2029 | ||
| 1895 | usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep, | 2030 | if (pdev->dev.of_node) |
| 1896 | GFP_KERNEL); | 2031 | udc->usba_ep = atmel_udc_of_init(pdev, udc); |
| 1897 | if (!usba_ep) | 2032 | else |
| 1898 | goto err_alloc_ep; | 2033 | udc->usba_ep = usba_udc_pdata(pdev, udc); |
| 1899 | |||
| 1900 | udc->usba_ep = usba_ep; | ||
| 1901 | udc->gadget.ep0 = &usba_ep[0].ep; | ||
| 1902 | |||
| 1903 | INIT_LIST_HEAD(&usba_ep[0].ep.ep_list); | ||
| 1904 | usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0); | ||
| 1905 | usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0); | ||
| 1906 | usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0); | ||
| 1907 | usba_ep[0].ep.ops = &usba_ep_ops; | ||
| 1908 | usba_ep[0].ep.name = pdata->ep[0].name; | ||
| 1909 | usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size; | ||
| 1910 | usba_ep[0].udc = udc; | ||
| 1911 | INIT_LIST_HEAD(&usba_ep[0].queue); | ||
| 1912 | usba_ep[0].fifo_size = pdata->ep[0].fifo_size; | ||
| 1913 | usba_ep[0].nr_banks = pdata->ep[0].nr_banks; | ||
| 1914 | usba_ep[0].index = pdata->ep[0].index; | ||
| 1915 | usba_ep[0].can_dma = pdata->ep[0].can_dma; | ||
| 1916 | usba_ep[0].can_isoc = pdata->ep[0].can_isoc; | ||
| 1917 | |||
| 1918 | for (i = 1; i < pdata->num_ep; i++) { | ||
| 1919 | struct usba_ep *ep = &usba_ep[i]; | ||
| 1920 | |||
| 1921 | ep->ep_regs = udc->regs + USBA_EPT_BASE(i); | ||
| 1922 | ep->dma_regs = udc->regs + USBA_DMA_BASE(i); | ||
| 1923 | ep->fifo = udc->fifo + USBA_FIFO_BASE(i); | ||
| 1924 | ep->ep.ops = &usba_ep_ops; | ||
| 1925 | ep->ep.name = pdata->ep[i].name; | ||
| 1926 | ep->ep.maxpacket = pdata->ep[i].fifo_size; | ||
| 1927 | ep->udc = udc; | ||
| 1928 | INIT_LIST_HEAD(&ep->queue); | ||
| 1929 | ep->fifo_size = pdata->ep[i].fifo_size; | ||
| 1930 | ep->nr_banks = pdata->ep[i].nr_banks; | ||
| 1931 | ep->index = pdata->ep[i].index; | ||
| 1932 | ep->can_dma = pdata->ep[i].can_dma; | ||
| 1933 | ep->can_isoc = pdata->ep[i].can_isoc; | ||
| 1934 | 2034 | ||
| 1935 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | 2035 | if (IS_ERR(udc->usba_ep)) { |
| 2036 | ret = PTR_ERR(udc->usba_ep); | ||
| 2037 | goto err_alloc_ep; | ||
| 1936 | } | 2038 | } |
| 1937 | 2039 | ||
| 1938 | ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc); | 2040 | ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc); |
| @@ -1943,16 +2045,12 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
| 1943 | } | 2045 | } |
| 1944 | udc->irq = irq; | 2046 | udc->irq = irq; |
| 1945 | 2047 | ||
| 1946 | if (gpio_is_valid(pdata->vbus_pin)) { | 2048 | if (gpio_is_valid(udc->vbus_pin)) { |
| 1947 | if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { | 2049 | if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) { |
| 1948 | udc->vbus_pin = pdata->vbus_pin; | ||
| 1949 | udc->vbus_pin_inverted = pdata->vbus_pin_inverted; | ||
| 1950 | |||
| 1951 | ret = request_irq(gpio_to_irq(udc->vbus_pin), | 2050 | ret = request_irq(gpio_to_irq(udc->vbus_pin), |
| 1952 | usba_vbus_irq, 0, | 2051 | usba_vbus_irq, 0, |
| 1953 | "atmel_usba_udc", udc); | 2052 | "atmel_usba_udc", udc); |
| 1954 | if (ret) { | 2053 | if (ret) { |
| 1955 | gpio_free(udc->vbus_pin); | ||
| 1956 | udc->vbus_pin = -ENODEV; | 2054 | udc->vbus_pin = -ENODEV; |
| 1957 | dev_warn(&udc->pdev->dev, | 2055 | dev_warn(&udc->pdev->dev, |
| 1958 | "failed to request vbus irq; " | 2056 | "failed to request vbus irq; " |
| @@ -1971,20 +2069,17 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
| 1971 | goto err_add_udc; | 2069 | goto err_add_udc; |
| 1972 | 2070 | ||
| 1973 | usba_init_debugfs(udc); | 2071 | usba_init_debugfs(udc); |
| 1974 | for (i = 1; i < pdata->num_ep; i++) | 2072 | for (i = 1; i < udc->num_ep; i++) |
| 1975 | usba_ep_init_debugfs(udc, &usba_ep[i]); | 2073 | usba_ep_init_debugfs(udc, &udc->usba_ep[i]); |
| 1976 | 2074 | ||
| 1977 | return 0; | 2075 | return 0; |
| 1978 | 2076 | ||
| 1979 | err_add_udc: | 2077 | err_add_udc: |
| 1980 | if (gpio_is_valid(pdata->vbus_pin)) { | 2078 | if (gpio_is_valid(udc->vbus_pin)) |
| 1981 | free_irq(gpio_to_irq(udc->vbus_pin), udc); | 2079 | free_irq(gpio_to_irq(udc->vbus_pin), udc); |
| 1982 | gpio_free(udc->vbus_pin); | ||
| 1983 | } | ||
| 1984 | 2080 | ||
| 1985 | free_irq(irq, udc); | 2081 | free_irq(irq, udc); |
| 1986 | err_request_irq: | 2082 | err_request_irq: |
| 1987 | kfree(usba_ep); | ||
| 1988 | err_alloc_ep: | 2083 | err_alloc_ep: |
| 1989 | iounmap(udc->fifo); | 2084 | iounmap(udc->fifo); |
| 1990 | err_map_fifo: | 2085 | err_map_fifo: |
| @@ -2003,23 +2098,20 @@ static int __exit usba_udc_remove(struct platform_device *pdev) | |||
| 2003 | { | 2098 | { |
| 2004 | struct usba_udc *udc; | 2099 | struct usba_udc *udc; |
| 2005 | int i; | 2100 | int i; |
| 2006 | struct usba_platform_data *pdata = pdev->dev.platform_data; | ||
| 2007 | 2101 | ||
| 2008 | udc = platform_get_drvdata(pdev); | 2102 | udc = platform_get_drvdata(pdev); |
| 2009 | 2103 | ||
| 2010 | usb_del_gadget_udc(&udc->gadget); | 2104 | usb_del_gadget_udc(&udc->gadget); |
| 2011 | 2105 | ||
| 2012 | for (i = 1; i < pdata->num_ep; i++) | 2106 | for (i = 1; i < udc->num_ep; i++) |
| 2013 | usba_ep_cleanup_debugfs(&udc->usba_ep[i]); | 2107 | usba_ep_cleanup_debugfs(&udc->usba_ep[i]); |
| 2014 | usba_cleanup_debugfs(udc); | 2108 | usba_cleanup_debugfs(udc); |
| 2015 | 2109 | ||
| 2016 | if (gpio_is_valid(udc->vbus_pin)) { | 2110 | if (gpio_is_valid(udc->vbus_pin)) { |
| 2017 | free_irq(gpio_to_irq(udc->vbus_pin), udc); | 2111 | free_irq(gpio_to_irq(udc->vbus_pin), udc); |
| 2018 | gpio_free(udc->vbus_pin); | ||
| 2019 | } | 2112 | } |
| 2020 | 2113 | ||
| 2021 | free_irq(udc->irq, udc); | 2114 | free_irq(udc->irq, udc); |
| 2022 | kfree(usba_ep); | ||
| 2023 | iounmap(udc->fifo); | 2115 | iounmap(udc->fifo); |
| 2024 | iounmap(udc->regs); | 2116 | iounmap(udc->regs); |
| 2025 | clk_put(udc->hclk); | 2117 | clk_put(udc->hclk); |
| @@ -2028,11 +2120,21 @@ static int __exit usba_udc_remove(struct platform_device *pdev) | |||
| 2028 | return 0; | 2120 | return 0; |
| 2029 | } | 2121 | } |
| 2030 | 2122 | ||
| 2123 | #if defined(CONFIG_OF) | ||
| 2124 | static const struct of_device_id atmel_udc_dt_ids[] = { | ||
| 2125 | { .compatible = "atmel,at91sam9rl-udc" }, | ||
| 2126 | { /* sentinel */ } | ||
| 2127 | }; | ||
| 2128 | |||
| 2129 | MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids); | ||
| 2130 | #endif | ||
| 2131 | |||
| 2031 | static struct platform_driver udc_driver = { | 2132 | static struct platform_driver udc_driver = { |
| 2032 | .remove = __exit_p(usba_udc_remove), | 2133 | .remove = __exit_p(usba_udc_remove), |
| 2033 | .driver = { | 2134 | .driver = { |
| 2034 | .name = "atmel_usba_udc", | 2135 | .name = "atmel_usba_udc", |
| 2035 | .owner = THIS_MODULE, | 2136 | .owner = THIS_MODULE, |
| 2137 | .of_match_table = of_match_ptr(atmel_udc_dt_ids), | ||
| 2036 | }, | 2138 | }, |
| 2037 | }; | 2139 | }; |
| 2038 | 2140 | ||
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index 08419867013f..2922db50befe 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
| @@ -317,6 +317,7 @@ struct usba_udc { | |||
| 317 | int irq; | 317 | int irq; |
| 318 | int vbus_pin; | 318 | int vbus_pin; |
| 319 | int vbus_pin_inverted; | 319 | int vbus_pin_inverted; |
| 320 | int num_ep; | ||
| 320 | struct clk *pclk; | 321 | struct clk *pclk; |
| 321 | struct clk *hclk; | 322 | struct clk *hclk; |
| 322 | struct usba_ep *usba_ep; | 323 | struct usba_ep *usba_ep; |
