aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-11 16:48:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-11 16:48:01 -0400
commitdcb9cf39c533a95be7dd0b2f7dfd73e04bf17c2d (patch)
tree7377bc0f6c36e94f17dafd93a003380186021d95 /drivers/usb/dwc3
parent7135f08e47de094f8748507806efa8d7ba27a964 (diff)
parent363366cf61c544ea476f3d220f43a95cb03014f5 (diff)
Merge tag 'xceiv-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
usb: xceiv: patches for v3.7 merge window nop xceiv got its own header to avoid polluting otg.h. It has also learned to work as USB2 and USB3 phys so we can use it on USB3 controllers. Together with those two changes to nop xceiv, we're adding basic PHY support to dwc3 driver, this is to allow platforms which actually have a SW-controllable PHY talk to them through dwc3 driver. We're adding a new phy driver for the OMAP architecture. This driver is for the PHY found in OMAP4 SoCs, and a new phy driver for the marvell architecture. An extra phy driver - for Tegra SoCs - is now moving from arch/arm/mach-tegra* to drivers/usb/phy. Also here, there's the creation of <linux/usb/phy.h> which should be used from now on for PHY drivers, even those which don't support OTG.
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.c15
-rw-r--r--drivers/usb/dwc3/core.h5
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c66
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c66
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c67
5 files changed, 219 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c34452a7304..79a24fab13d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -50,6 +50,7 @@
50#include <linux/dma-mapping.h> 50#include <linux/dma-mapping.h>
51#include <linux/of.h> 51#include <linux/of.h>
52 52
53#include <linux/usb/otg.h>
53#include <linux/usb/ch9.h> 54#include <linux/usb/ch9.h>
54#include <linux/usb/gadget.h> 55#include <linux/usb/gadget.h>
55 56
@@ -136,6 +137,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
136 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; 137 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
137 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 138 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
138 139
140 usb_phy_init(dwc->usb2_phy);
141 usb_phy_init(dwc->usb3_phy);
139 mdelay(100); 142 mdelay(100);
140 143
141 /* Clear USB3 PHY reset */ 144 /* Clear USB3 PHY reset */
@@ -465,6 +468,18 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
465 return -ENOMEM; 468 return -ENOMEM;
466 } 469 }
467 470
471 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
472 if (IS_ERR_OR_NULL(dwc->usb2_phy)) {
473 dev_err(dev, "no usb2 phy configured\n");
474 return -EPROBE_DEFER;
475 }
476
477 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
478 if (IS_ERR_OR_NULL(dwc->usb3_phy)) {
479 dev_err(dev, "no usb3 phy configured\n");
480 return -EPROBE_DEFER;
481 }
482
468 spin_lock_init(&dwc->lock); 483 spin_lock_init(&dwc->lock);
469 platform_set_drvdata(pdev, dwc); 484 platform_set_drvdata(pdev, dwc);
470 485
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 151eca876df..dbc5713d84f 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -624,6 +624,8 @@ struct dwc3_scratchpad_array {
624 * @maximum_speed: maximum speed requested (mainly for testing purposes) 624 * @maximum_speed: maximum speed requested (mainly for testing purposes)
625 * @revision: revision register contents 625 * @revision: revision register contents
626 * @mode: mode of operation 626 * @mode: mode of operation
627 * @usb2_phy: pointer to USB2 PHY
628 * @usb3_phy: pointer to USB3 PHY
627 * @is_selfpowered: true when we are selfpowered 629 * @is_selfpowered: true when we are selfpowered
628 * @three_stage_setup: set if we perform a three phase setup 630 * @three_stage_setup: set if we perform a three phase setup
629 * @ep0_bounced: true when we used bounce buffer 631 * @ep0_bounced: true when we used bounce buffer
@@ -667,6 +669,9 @@ struct dwc3 {
667 struct usb_gadget gadget; 669 struct usb_gadget gadget;
668 struct usb_gadget_driver *gadget_driver; 670 struct usb_gadget_driver *gadget_driver;
669 671
672 struct usb_phy *usb2_phy;
673 struct usb_phy *usb3_phy;
674
670 void __iomem *regs; 675 void __iomem *regs;
671 size_t regs_size; 676 size_t regs_size;
672 677
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index b8f00389fa3..ca6597853f9 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -19,16 +19,74 @@
19#include <linux/platform_data/dwc3-exynos.h> 19#include <linux/platform_data/dwc3-exynos.h>
20#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/usb/otg.h>
23#include <linux/usb/nop-usb-xceiv.h>
22 24
23#include "core.h" 25#include "core.h"
24 26
25struct dwc3_exynos { 27struct dwc3_exynos {
26 struct platform_device *dwc3; 28 struct platform_device *dwc3;
29 struct platform_device *usb2_phy;
30 struct platform_device *usb3_phy;
27 struct device *dev; 31 struct device *dev;
28 32
29 struct clk *clk; 33 struct clk *clk;
30}; 34};
31 35
36static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
37{
38 struct nop_usb_xceiv_platform_data pdata;
39 struct platform_device *pdev;
40 int ret;
41
42 memset(&pdata, 0x00, sizeof(pdata));
43
44 pdev = platform_device_alloc("nop_usb_xceiv", 0);
45 if (!pdev)
46 return -ENOMEM;
47
48 exynos->usb2_phy = pdev;
49 pdata.type = USB_PHY_TYPE_USB2;
50
51 ret = platform_device_add_data(exynos->usb2_phy, &pdata, sizeof(pdata));
52 if (ret)
53 goto err1;
54
55 pdev = platform_device_alloc("nop_usb_xceiv", 1);
56 if (!pdev) {
57 ret = -ENOMEM;
58 goto err1;
59 }
60
61 exynos->usb3_phy = pdev;
62 pdata.type = USB_PHY_TYPE_USB3;
63
64 ret = platform_device_add_data(exynos->usb3_phy, &pdata, sizeof(pdata));
65 if (ret)
66 goto err2;
67
68 ret = platform_device_add(exynos->usb2_phy);
69 if (ret)
70 goto err2;
71
72 ret = platform_device_add(exynos->usb3_phy);
73 if (ret)
74 goto err3;
75
76 return 0;
77
78err3:
79 platform_device_del(exynos->usb2_phy);
80
81err2:
82 platform_device_put(exynos->usb3_phy);
83
84err1:
85 platform_device_put(exynos->usb2_phy);
86
87 return ret;
88}
89
32static int __devinit dwc3_exynos_probe(struct platform_device *pdev) 90static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
33{ 91{
34 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 92 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
@@ -51,6 +109,12 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
51 if (devid < 0) 109 if (devid < 0)
52 goto err1; 110 goto err1;
53 111
112 ret = dwc3_exynos_register_phys(exynos);
113 if (ret) {
114 dev_err(&pdev->dev, "couldn't register PHYs\n");
115 goto err1;
116 }
117
54 dwc3 = platform_device_alloc("dwc3", devid); 118 dwc3 = platform_device_alloc("dwc3", devid);
55 if (!dwc3) { 119 if (!dwc3) {
56 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); 120 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
@@ -120,6 +184,8 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
120 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 184 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
121 185
122 platform_device_unregister(exynos->dwc3); 186 platform_device_unregister(exynos->dwc3);
187 platform_device_unregister(exynos->usb2_phy);
188 platform_device_unregister(exynos->usb3_phy);
123 189
124 dwc3_put_device_id(exynos->dwc3->id); 190 dwc3_put_device_id(exynos->dwc3->id);
125 191
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 479dc047da3..ee57a10d90d 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -48,6 +48,9 @@
48#include <linux/io.h> 48#include <linux/io.h>
49#include <linux/of.h> 49#include <linux/of.h>
50 50
51#include <linux/usb/otg.h>
52#include <linux/usb/nop-usb-xceiv.h>
53
51#include "core.h" 54#include "core.h"
52 55
53/* 56/*
@@ -131,6 +134,8 @@ struct dwc3_omap {
131 spinlock_t lock; 134 spinlock_t lock;
132 135
133 struct platform_device *dwc3; 136 struct platform_device *dwc3;
137 struct platform_device *usb2_phy;
138 struct platform_device *usb3_phy;
134 struct device *dev; 139 struct device *dev;
135 140
136 int irq; 141 int irq;
@@ -152,6 +157,59 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
152 writel(value, base + offset); 157 writel(value, base + offset);
153} 158}
154 159
160static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap)
161{
162 struct nop_usb_xceiv_platform_data pdata;
163 struct platform_device *pdev;
164 int ret;
165
166 memset(&pdata, 0x00, sizeof(pdata));
167
168 pdev = platform_device_alloc("nop_usb_xceiv", 0);
169 if (!pdev)
170 return -ENOMEM;
171
172 omap->usb2_phy = pdev;
173 pdata.type = USB_PHY_TYPE_USB2;
174
175 ret = platform_device_add_data(omap->usb2_phy, &pdata, sizeof(pdata));
176 if (ret)
177 goto err1;
178
179 pdev = platform_device_alloc("nop_usb_xceiv", 1);
180 if (!pdev) {
181 ret = -ENOMEM;
182 goto err1;
183 }
184
185 omap->usb3_phy = pdev;
186 pdata.type = USB_PHY_TYPE_USB3;
187
188 ret = platform_device_add_data(omap->usb3_phy, &pdata, sizeof(pdata));
189 if (ret)
190 goto err2;
191
192 ret = platform_device_add(omap->usb2_phy);
193 if (ret)
194 goto err2;
195
196 ret = platform_device_add(omap->usb3_phy);
197 if (ret)
198 goto err3;
199
200 return 0;
201
202err3:
203 platform_device_del(omap->usb2_phy);
204
205err2:
206 platform_device_put(omap->usb3_phy);
207
208err1:
209 platform_device_put(omap->usb2_phy);
210
211 return ret;
212}
155 213
156static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) 214static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
157{ 215{
@@ -251,6 +309,12 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
251 return -ENOMEM; 309 return -ENOMEM;
252 } 310 }
253 311
312 ret = dwc3_omap_register_phys(omap);
313 if (ret) {
314 dev_err(dev, "couldn't register PHYs\n");
315 return ret;
316 }
317
254 devid = dwc3_get_device_id(); 318 devid = dwc3_get_device_id();
255 if (devid < 0) 319 if (devid < 0)
256 return -ENODEV; 320 return -ENODEV;
@@ -371,6 +435,8 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev)
371 struct dwc3_omap *omap = platform_get_drvdata(pdev); 435 struct dwc3_omap *omap = platform_get_drvdata(pdev);
372 436
373 platform_device_unregister(omap->dwc3); 437 platform_device_unregister(omap->dwc3);
438 platform_device_unregister(omap->usb2_phy);
439 platform_device_unregister(omap->usb3_phy);
374 440
375 dwc3_put_device_id(omap->dwc3->id); 441 dwc3_put_device_id(omap->dwc3->id);
376 442
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index a9ca9adba39..94f550e37f9 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -42,6 +42,9 @@
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44 44
45#include <linux/usb/otg.h>
46#include <linux/usb/nop-usb-xceiv.h>
47
45#include "core.h" 48#include "core.h"
46 49
47/* FIXME define these in <linux/pci_ids.h> */ 50/* FIXME define these in <linux/pci_ids.h> */
@@ -51,8 +54,64 @@
51struct dwc3_pci { 54struct dwc3_pci {
52 struct device *dev; 55 struct device *dev;
53 struct platform_device *dwc3; 56 struct platform_device *dwc3;
57 struct platform_device *usb2_phy;
58 struct platform_device *usb3_phy;
54}; 59};
55 60
61static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue)
62{
63 struct nop_usb_xceiv_platform_data pdata;
64 struct platform_device *pdev;
65 int ret;
66
67 memset(&pdata, 0x00, sizeof(pdata));
68
69 pdev = platform_device_alloc("nop_usb_xceiv", 0);
70 if (!pdev)
71 return -ENOMEM;
72
73 glue->usb2_phy = pdev;
74 pdata.type = USB_PHY_TYPE_USB2;
75
76 ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata));
77 if (ret)
78 goto err1;
79
80 pdev = platform_device_alloc("nop_usb_xceiv", 1);
81 if (!pdev) {
82 ret = -ENOMEM;
83 goto err1;
84 }
85
86 glue->usb3_phy = pdev;
87 pdata.type = USB_PHY_TYPE_USB3;
88
89 ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata));
90 if (ret)
91 goto err2;
92
93 ret = platform_device_add(glue->usb2_phy);
94 if (ret)
95 goto err2;
96
97 ret = platform_device_add(glue->usb3_phy);
98 if (ret)
99 goto err3;
100
101 return 0;
102
103err3:
104 platform_device_del(glue->usb2_phy);
105
106err2:
107 platform_device_put(glue->usb3_phy);
108
109err1:
110 platform_device_put(glue->usb2_phy);
111
112 return ret;
113}
114
56static int __devinit dwc3_pci_probe(struct pci_dev *pci, 115static int __devinit dwc3_pci_probe(struct pci_dev *pci,
57 const struct pci_device_id *id) 116 const struct pci_device_id *id)
58{ 117{
@@ -80,6 +139,12 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
80 pci_set_power_state(pci, PCI_D0); 139 pci_set_power_state(pci, PCI_D0);
81 pci_set_master(pci); 140 pci_set_master(pci);
82 141
142 ret = dwc3_pci_register_phys(glue);
143 if (ret) {
144 dev_err(dev, "couldn't register PHYs\n");
145 return ret;
146 }
147
83 devid = dwc3_get_device_id(); 148 devid = dwc3_get_device_id();
84 if (devid < 0) { 149 if (devid < 0) {
85 ret = -ENOMEM; 150 ret = -ENOMEM;
@@ -144,6 +209,8 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci)
144{ 209{
145 struct dwc3_pci *glue = pci_get_drvdata(pci); 210 struct dwc3_pci *glue = pci_get_drvdata(pci);
146 211
212 platform_device_unregister(glue->usb2_phy);
213 platform_device_unregister(glue->usb3_phy);
147 dwc3_put_device_id(glue->dwc3->id); 214 dwc3_put_device_id(glue->dwc3->id);
148 platform_device_unregister(glue->dwc3); 215 platform_device_unregister(glue->dwc3);
149 pci_set_drvdata(pci, NULL); 216 pci_set_drvdata(pci, NULL);