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 /drivers/usb/gadget/atmel_usba_udc.c | |
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>
Diffstat (limited to 'drivers/usb/gadget/atmel_usba_udc.c')
-rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 220 |
1 files changed, 161 insertions, 59 deletions
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 | ||