diff options
author | Roger Quadros <rogerq@ti.com> | 2013-03-12 06:44:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-15 14:51:47 -0400 |
commit | a1ae0affee119e6deb937d157aa8b43319c1d6f3 (patch) | |
tree | 217067f110ad543c5500eeec55c9781ba272406c | |
parent | 5867320dec346c2dc26f224f876d780111ca149d (diff) |
USB: ehci-omap: Add device tree support and binding information
Allows the OMAP EHCI controller to be specified via device tree.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | Documentation/devicetree/bindings/usb/ehci-omap.txt | 32 | ||||
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 37 |
2 files changed, 68 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/usb/ehci-omap.txt b/Documentation/devicetree/bindings/usb/ehci-omap.txt new file mode 100644 index 000000000000..485a9a1efa7a --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ehci-omap.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | OMAP HS USB EHCI controller | ||
2 | |||
3 | This device is usually the child of the omap-usb-host | ||
4 | Documentation/devicetree/bindings/mfd/omap-usb-host.txt | ||
5 | |||
6 | Required properties: | ||
7 | |||
8 | - compatible: should be "ti,ehci-omap" | ||
9 | - reg: should contain one register range i.e. start and length | ||
10 | - interrupts: description of the interrupt line | ||
11 | |||
12 | Optional properties: | ||
13 | |||
14 | - phys: list of phandles to PHY nodes. | ||
15 | This property is required if at least one of the ports are in | ||
16 | PHY mode i.e. OMAP_EHCI_PORT_MODE_PHY | ||
17 | |||
18 | To specify the port mode, see | ||
19 | Documentation/devicetree/bindings/mfd/omap-usb-host.txt | ||
20 | |||
21 | Example for OMAP4: | ||
22 | |||
23 | usbhsehci: ehci@4a064c00 { | ||
24 | compatible = "ti,ehci-omap", "usb-ehci"; | ||
25 | reg = <0x4a064c00 0x400>; | ||
26 | interrupts = <0 77 0x4>; | ||
27 | }; | ||
28 | |||
29 | &usbhsehci { | ||
30 | phys = <&hsusb1_phy 0 &hsusb3_phy>; | ||
31 | }; | ||
32 | |||
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 7d05cce62037..45cd01e29252 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <linux/clk.h> | 48 | #include <linux/clk.h> |
49 | #include <linux/usb.h> | 49 | #include <linux/usb.h> |
50 | #include <linux/usb/hcd.h> | 50 | #include <linux/usb/hcd.h> |
51 | #include <linux/of.h> | ||
52 | #include <linux/dma-mapping.h> | ||
51 | 53 | ||
52 | #include "ehci.h" | 54 | #include "ehci.h" |
53 | 55 | ||
@@ -121,6 +123,8 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { | |||
121 | .extra_priv_size = sizeof(struct omap_hcd), | 123 | .extra_priv_size = sizeof(struct omap_hcd), |
122 | }; | 124 | }; |
123 | 125 | ||
126 | static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32); | ||
127 | |||
124 | /** | 128 | /** |
125 | * ehci_hcd_omap_probe - initialize TI-based HCDs | 129 | * ehci_hcd_omap_probe - initialize TI-based HCDs |
126 | * | 130 | * |
@@ -148,6 +152,17 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
148 | return -ENODEV; | 152 | return -ENODEV; |
149 | } | 153 | } |
150 | 154 | ||
155 | /* For DT boot, get platform data from parent. i.e. usbhshost */ | ||
156 | if (dev->of_node) { | ||
157 | pdata = dev->parent->platform_data; | ||
158 | dev->platform_data = pdata; | ||
159 | } | ||
160 | |||
161 | if (!pdata) { | ||
162 | dev_err(dev, "Missing platform data\n"); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
151 | irq = platform_get_irq(pdev, 0); | 166 | irq = platform_get_irq(pdev, 0); |
152 | if (irq < 0) { | 167 | if (irq < 0) { |
153 | dev_err(dev, "EHCI irq failed\n"); | 168 | dev_err(dev, "EHCI irq failed\n"); |
@@ -159,6 +174,14 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
159 | if (IS_ERR(regs)) | 174 | if (IS_ERR(regs)) |
160 | return PTR_ERR(regs); | 175 | return PTR_ERR(regs); |
161 | 176 | ||
177 | /* | ||
178 | * Right now device-tree probed devices don't get dma_mask set. | ||
179 | * Since shared usb code relies on it, set it here for now. | ||
180 | * Once we have dma capability bindings this can go away. | ||
181 | */ | ||
182 | if (!pdev->dev.dma_mask) | ||
183 | pdev->dev.dma_mask = &omap_ehci_dma_mask; | ||
184 | |||
162 | hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, | 185 | hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, |
163 | dev_name(dev)); | 186 | dev_name(dev)); |
164 | if (!hcd) { | 187 | if (!hcd) { |
@@ -183,7 +206,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
183 | continue; | 206 | continue; |
184 | 207 | ||
185 | /* get the PHY device */ | 208 | /* get the PHY device */ |
186 | phy = devm_usb_get_phy_dev(dev, i); | 209 | if (dev->of_node) |
210 | phy = devm_usb_get_phy_by_phandle(dev, "phys", i); | ||
211 | else | ||
212 | phy = devm_usb_get_phy_dev(dev, i); | ||
187 | if (IS_ERR(phy) || !phy) { | 213 | if (IS_ERR(phy) || !phy) { |
188 | ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; | 214 | ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; |
189 | dev_err(dev, "Can't get PHY device for port %d: %d\n", | 215 | dev_err(dev, "Can't get PHY device for port %d: %d\n", |
@@ -273,6 +299,13 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev) | |||
273 | hcd->driver->shutdown(hcd); | 299 | hcd->driver->shutdown(hcd); |
274 | } | 300 | } |
275 | 301 | ||
302 | static const struct of_device_id omap_ehci_dt_ids[] = { | ||
303 | { .compatible = "ti,ehci-omap" }, | ||
304 | { } | ||
305 | }; | ||
306 | |||
307 | MODULE_DEVICE_TABLE(of, omap_ehci_dt_ids); | ||
308 | |||
276 | static struct platform_driver ehci_hcd_omap_driver = { | 309 | static struct platform_driver ehci_hcd_omap_driver = { |
277 | .probe = ehci_hcd_omap_probe, | 310 | .probe = ehci_hcd_omap_probe, |
278 | .remove = ehci_hcd_omap_remove, | 311 | .remove = ehci_hcd_omap_remove, |
@@ -281,6 +314,7 @@ static struct platform_driver ehci_hcd_omap_driver = { | |||
281 | /*.resume = ehci_hcd_omap_resume, */ | 314 | /*.resume = ehci_hcd_omap_resume, */ |
282 | .driver = { | 315 | .driver = { |
283 | .name = hcd_name, | 316 | .name = hcd_name, |
317 | .of_match_table = of_match_ptr(omap_ehci_dt_ids), | ||
284 | } | 318 | } |
285 | }; | 319 | }; |
286 | 320 | ||
@@ -307,6 +341,7 @@ module_exit(ehci_omap_cleanup); | |||
307 | MODULE_ALIAS("platform:ehci-omap"); | 341 | MODULE_ALIAS("platform:ehci-omap"); |
308 | MODULE_AUTHOR("Texas Instruments, Inc."); | 342 | MODULE_AUTHOR("Texas Instruments, Inc."); |
309 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); | 343 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); |
344 | MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>"); | ||
310 | 345 | ||
311 | MODULE_DESCRIPTION(DRIVER_DESC); | 346 | MODULE_DESCRIPTION(DRIVER_DESC); |
312 | MODULE_LICENSE("GPL"); | 347 | MODULE_LICENSE("GPL"); |