hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/usb/host/xhci-plat.c
....@@ -2,7 +2,7 @@
22 /*
33 * xhci-plat.c - xHCI host controller driver platform Bus Glue.
44 *
5
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
66 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
77 *
88 * A lot of code borrowed from the Linux xHCI driver.
....@@ -18,6 +18,7 @@
1818 #include <linux/usb/phy.h>
1919 #include <linux/slab.h>
2020 #include <linux/acpi.h>
21
+#include <linux/usb/of.h>
2122
2223 #include "xhci.h"
2324 #include "xhci-plat.h"
....@@ -43,6 +44,16 @@
4344 priv->plat_start(hcd);
4445 }
4546
47
+static int xhci_priv_plat_setup(struct usb_hcd *hcd)
48
+{
49
+ struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
50
+
51
+ if (!priv->plat_setup)
52
+ return 0;
53
+
54
+ return priv->plat_setup(hcd);
55
+}
56
+
4657 static int xhci_priv_init_quirk(struct usb_hcd *hcd)
4758 {
4859 struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
....@@ -51,6 +62,16 @@
5162 return 0;
5263
5364 return priv->init_quirk(hcd);
65
+}
66
+
67
+static int xhci_priv_suspend_quirk(struct usb_hcd *hcd)
68
+{
69
+ struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
70
+
71
+ if (!priv->suspend_quirk)
72
+ return 0;
73
+
74
+ return priv->suspend_quirk(hcd);
5475 }
5576
5677 static int xhci_priv_resume_quirk(struct usb_hcd *hcd)
....@@ -65,12 +86,14 @@
6586
6687 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
6788 {
89
+ struct xhci_plat_priv *priv = xhci_to_priv(xhci);
90
+
6891 /*
6992 * As of now platform drivers don't provide MSI support so we ensure
7093 * here that the generic code does not try to make a pci_dev from our
7194 * dev struct in order to setup MSI
7295 */
73
- xhci->quirks |= XHCI_PLAT;
96
+ xhci->quirks |= XHCI_PLAT | priv->quirks;
7497 }
7598
7699 /* called during probe() after chip reset completes */
....@@ -97,18 +120,21 @@
97120 .init_quirk = xhci_mvebu_mbus_init_quirk,
98121 };
99122
123
+static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
124
+ .plat_setup = xhci_mvebu_a3700_plat_setup,
125
+ .init_quirk = xhci_mvebu_a3700_init_quirk,
126
+};
127
+
100128 static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
101
- .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1,
102
- .init_quirk = xhci_rcar_init_quirk,
103
- .plat_start = xhci_rcar_start,
104
- .resume_quirk = xhci_rcar_resume_quirk,
129
+ SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V1)
105130 };
106131
107132 static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
108
- .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3,
109
- .init_quirk = xhci_rcar_init_quirk,
110
- .plat_start = xhci_rcar_start,
111
- .resume_quirk = xhci_rcar_resume_quirk,
133
+ SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3)
134
+};
135
+
136
+static const struct xhci_plat_priv xhci_plat_brcm = {
137
+ .quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS,
112138 };
113139
114140 static const struct of_device_id usb_xhci_of_match[] = {
....@@ -116,12 +142,16 @@
116142 .compatible = "generic-xhci",
117143 }, {
118144 .compatible = "xhci-platform",
145
+#ifndef CONFIG_ARCH_ROCKCHIP
119146 }, {
120147 .compatible = "marvell,armada-375-xhci",
121148 .data = &xhci_plat_marvell_armada,
122149 }, {
123150 .compatible = "marvell,armada-380-xhci",
124151 .data = &xhci_plat_marvell_armada,
152
+ }, {
153
+ .compatible = "marvell,armada3700-xhci",
154
+ .data = &xhci_plat_marvell_armada3700,
125155 }, {
126156 .compatible = "renesas,xhci-r8a7790",
127157 .data = &xhci_plat_renesas_rcar_gen2,
....@@ -143,11 +173,53 @@
143173 }, {
144174 .compatible = "renesas,rcar-gen3-xhci",
145175 .data = &xhci_plat_renesas_rcar_gen3,
176
+ }, {
177
+ .compatible = "brcm,xhci-brcm-v2",
178
+ .data = &xhci_plat_brcm,
179
+ }, {
180
+ .compatible = "brcm,bcm7445-xhci",
181
+ .data = &xhci_plat_brcm,
182
+#endif
146183 },
147184 {},
148185 };
149186 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
150187 #endif
188
+
189
+static struct xhci_plat_priv_overwrite xhci_plat_vendor_overwrite;
190
+
191
+int xhci_plat_register_vendor_ops(struct xhci_vendor_ops *vendor_ops)
192
+{
193
+ if (vendor_ops == NULL)
194
+ return -EINVAL;
195
+
196
+ xhci_plat_vendor_overwrite.vendor_ops = vendor_ops;
197
+
198
+ return 0;
199
+}
200
+EXPORT_SYMBOL_GPL(xhci_plat_register_vendor_ops);
201
+
202
+static int xhci_vendor_init(struct xhci_hcd *xhci)
203
+{
204
+ struct xhci_vendor_ops *ops = NULL;
205
+
206
+ if (xhci_plat_vendor_overwrite.vendor_ops)
207
+ ops = xhci->vendor_ops = xhci_plat_vendor_overwrite.vendor_ops;
208
+
209
+ if (ops && ops->vendor_init)
210
+ return ops->vendor_init(xhci);
211
+ return 0;
212
+}
213
+
214
+static void xhci_vendor_cleanup(struct xhci_hcd *xhci)
215
+{
216
+ struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci);
217
+
218
+ if (ops && ops->vendor_cleanup)
219
+ ops->vendor_cleanup(xhci);
220
+
221
+ xhci->vendor_ops = NULL;
222
+}
151223
152224 static int xhci_plat_probe(struct platform_device *pdev)
153225 {
....@@ -157,10 +229,10 @@
157229 struct xhci_hcd *xhci;
158230 struct resource *res;
159231 struct usb_hcd *hcd;
160
- struct clk *clk;
161
- struct clk *reg_clk;
162232 int ret;
163233 int irq;
234
+ struct xhci_plat_priv *priv = NULL;
235
+
164236
165237 if (usb_disabled())
166238 return -ENODEV;
....@@ -217,8 +289,7 @@
217289 goto disable_runtime;
218290 }
219291
220
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
221
- hcd->regs = devm_ioremap_resource(&pdev->dev, res);
292
+ hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
222293 if (IS_ERR(hcd->regs)) {
223294 ret = PTR_ERR(hcd->regs);
224295 goto put_hcd;
....@@ -227,44 +298,45 @@
227298 hcd->rsrc_start = res->start;
228299 hcd->rsrc_len = resource_size(res);
229300
301
+ xhci = hcd_to_xhci(hcd);
302
+
230303 /*
231304 * Not all platforms have clks so it is not an error if the
232305 * clock do not exist.
233306 */
234
- reg_clk = devm_clk_get(&pdev->dev, "reg");
235
- if (!IS_ERR(reg_clk)) {
236
- ret = clk_prepare_enable(reg_clk);
237
- if (ret)
238
- goto put_hcd;
239
- } else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
240
- ret = -EPROBE_DEFER;
307
+ xhci->reg_clk = devm_clk_get_optional(&pdev->dev, "reg");
308
+ if (IS_ERR(xhci->reg_clk)) {
309
+ ret = PTR_ERR(xhci->reg_clk);
241310 goto put_hcd;
242311 }
243312
244
- clk = devm_clk_get(&pdev->dev, NULL);
245
- if (!IS_ERR(clk)) {
246
- ret = clk_prepare_enable(clk);
247
- if (ret)
248
- goto disable_reg_clk;
249
- } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
250
- ret = -EPROBE_DEFER;
313
+ ret = clk_prepare_enable(xhci->reg_clk);
314
+ if (ret)
315
+ goto put_hcd;
316
+
317
+ xhci->clk = devm_clk_get_optional(&pdev->dev, NULL);
318
+ if (IS_ERR(xhci->clk)) {
319
+ ret = PTR_ERR(xhci->clk);
251320 goto disable_reg_clk;
252321 }
253322
254
- xhci = hcd_to_xhci(hcd);
255
- priv_match = of_device_get_match_data(&pdev->dev);
256
- if (priv_match) {
257
- struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
323
+ ret = clk_prepare_enable(xhci->clk);
324
+ if (ret)
325
+ goto disable_reg_clk;
258326
327
+ if (pdev->dev.of_node)
328
+ priv_match = of_device_get_match_data(&pdev->dev);
329
+ else
330
+ priv_match = dev_get_platdata(&pdev->dev);
331
+
332
+ if (priv_match) {
333
+ priv = hcd_to_xhci_priv(hcd);
259334 /* Just copy data for now */
260
- if (priv_match)
261
- *priv = *priv_match;
335
+ *priv = *priv_match;
262336 }
263337
264
- device_wakeup_enable(hcd->self.controller);
338
+ device_set_wakeup_capable(&pdev->dev, true);
265339
266
- xhci->clk = clk;
267
- xhci->reg_clk = reg_clk;
268340 xhci->main_hcd = hcd;
269341 xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
270342 dev_name(&pdev->dev), hcd);
....@@ -288,25 +360,12 @@
288360 if (device_property_read_bool(tmpdev, "quirk-broken-port-ped"))
289361 xhci->quirks |= XHCI_BROKEN_PORT_PED;
290362
291
- if (device_property_read_bool(tmpdev, "xhci-slow-suspend"))
292
- xhci->quirks |= XHCI_SLOW_SUSPEND;
293
-
294
- if (device_property_read_bool(tmpdev, "xhci-trb-ent-quirk"))
295
- xhci->quirks |= XHCI_TRB_ENT_QUIRK;
296
-
297
- if (device_property_read_bool(tmpdev, "usb3-dis-autosuspend"))
298
- xhci->quirks |= XHCI_DIS_AUTOSUSPEND;
299
-
300
- if (device_property_read_bool(tmpdev,
301
- "xhci-warm-reset-on-suspend"))
302
- xhci->quirks |= XHCI_WARM_RESET_ON_SUSPEND;
363
+ if (device_property_read_bool(tmpdev, "quirk-skip-phy-init"))
364
+ xhci->quirks |= XHCI_SKIP_PHY_INIT;
303365
304366 if (device_property_read_bool(tmpdev,
305367 "xhci-u2-broken-suspend"))
306368 xhci->quirks |= XHCI_U2_BROKEN_SUSPEND;
307
-
308
- if (device_property_read_bool(tmpdev, "quirk-skip-phy-init"))
309
- xhci->quirks |= XHCI_SKIP_PHY_INIT;
310369
311370 device_property_read_u32(tmpdev, "imod-interval-ns",
312371 &xhci->imod_interval);
....@@ -324,17 +383,24 @@
324383 goto put_usb3_hcd;
325384 }
326385
327
- xhci->shared_hcd->usb_phy = devm_usb_get_phy(sysdev,
328
- USB_PHY_TYPE_USB3);
329
- if (IS_ERR(xhci->shared_hcd->usb_phy)) {
330
- ret = PTR_ERR(xhci->shared_hcd->usb_phy);
331
- if (ret == -EPROBE_DEFER)
332
- goto put_usb3_hcd;
333
- xhci->shared_hcd->usb_phy = NULL;
386
+ ret = xhci_vendor_init(xhci);
387
+ if (ret)
388
+ goto disable_usb_phy;
389
+
390
+ hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
391
+ xhci->shared_hcd->tpl_support = hcd->tpl_support;
392
+
393
+ if (priv) {
394
+ ret = xhci_priv_plat_setup(hcd);
395
+ if (ret)
396
+ goto disable_usb_phy;
334397 }
335398
336
- if (xhci->quirks & XHCI_SKIP_PHY_INIT)
399
+ if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)))
337400 hcd->skip_phy_initialization = 1;
401
+
402
+ if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
403
+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
338404
339405 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
340406 if (ret)
....@@ -369,10 +435,10 @@
369435 usb_put_hcd(xhci->shared_hcd);
370436
371437 disable_clk:
372
- clk_disable_unprepare(clk);
438
+ clk_disable_unprepare(xhci->clk);
373439
374440 disable_reg_clk:
375
- clk_disable_unprepare(reg_clk);
441
+ clk_disable_unprepare(xhci->reg_clk);
376442
377443 put_hcd:
378444 usb_put_hcd(hcd);
....@@ -400,8 +466,10 @@
400466 usb_phy_shutdown(hcd->usb_phy);
401467
402468 usb_remove_hcd(hcd);
403
- usb_put_hcd(shared_hcd);
404469
470
+ xhci_vendor_cleanup(xhci);
471
+
472
+ usb_put_hcd(shared_hcd);
405473 clk_disable_unprepare(clk);
406474 clk_disable_unprepare(reg_clk);
407475 usb_put_hcd(hcd);
....@@ -417,16 +485,28 @@
417485 {
418486 struct usb_hcd *hcd = dev_get_drvdata(dev);
419487 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
488
+ int ret;
420489
490
+ if (pm_runtime_suspended(dev))
491
+ pm_runtime_resume(dev);
492
+
493
+ ret = xhci_priv_suspend_quirk(hcd);
494
+ if (ret)
495
+ return ret;
421496 /*
422497 * xhci_suspend() needs `do_wakeup` to know whether host is allowed
423
- * to do wakeup during suspend. Since xhci_plat_suspend is currently
424
- * only designed for system suspend, device_may_wakeup() is enough
425
- * to dertermine whether host is allowed to do wakeup. Need to
426
- * reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
427
- * also applies to runtime suspend.
498
+ * to do wakeup during suspend.
428499 */
429
- return xhci_suspend(xhci, device_may_wakeup(dev));
500
+ ret = xhci_suspend(xhci, device_may_wakeup(dev));
501
+ if (ret)
502
+ return ret;
503
+
504
+ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
505
+ clk_disable_unprepare(xhci->clk);
506
+ clk_disable_unprepare(xhci->reg_clk);
507
+ }
508
+
509
+ return 0;
430510 }
431511
432512 static int __maybe_unused xhci_plat_resume(struct device *dev)
....@@ -435,17 +515,35 @@
435515 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
436516 int ret;
437517
518
+ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
519
+ clk_prepare_enable(xhci->clk);
520
+ clk_prepare_enable(xhci->reg_clk);
521
+ }
522
+
438523 ret = xhci_priv_resume_quirk(hcd);
439524 if (ret)
440525 return ret;
441526
442
- return xhci_resume(xhci, 0);
527
+ ret = xhci_resume(xhci, 0);
528
+ if (ret)
529
+ return ret;
530
+
531
+ pm_runtime_disable(dev);
532
+ pm_runtime_set_active(dev);
533
+ pm_runtime_enable(dev);
534
+
535
+ return 0;
443536 }
444537
445538 static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
446539 {
447540 struct usb_hcd *hcd = dev_get_drvdata(dev);
448541 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
542
+ int ret;
543
+
544
+ ret = xhci_priv_suspend_quirk(hcd);
545
+ if (ret)
546
+ return ret;
449547
450548 return xhci_suspend(xhci, true);
451549 }
....@@ -466,12 +564,14 @@
466564 NULL)
467565 };
468566
567
+#ifdef CONFIG_ACPI
469568 static const struct acpi_device_id usb_xhci_acpi_match[] = {
470569 /* XHCI-compliant USB Controller */
471570 { "PNP0D10", },
472571 { }
473572 };
474573 MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
574
+#endif
475575
476576 static struct platform_driver usb_xhci_driver = {
477577 .probe = xhci_plat_probe,