hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/usb/host/fotg210-hcd.c
....@@ -10,6 +10,7 @@
1010 * Most of code borrowed from the Linux-3.7 EHCI driver
1111 */
1212 #include <linux/module.h>
13
+#include <linux/of.h>
1314 #include <linux/device.h>
1415 #include <linux/dmapool.h>
1516 #include <linux/kernel.h>
....@@ -31,6 +32,8 @@
3132 #include <linux/uaccess.h>
3233 #include <linux/platform_device.h>
3334 #include <linux/io.h>
35
+#include <linux/iopoll.h>
36
+#include <linux/clk.h>
3437
3538 #include <asm/byteorder.h>
3639 #include <asm/irq.h>
....@@ -881,18 +884,15 @@
881884 u32 mask, u32 done, int usec)
882885 {
883886 u32 result;
887
+ int ret;
884888
885
- do {
886
- result = fotg210_readl(fotg210, ptr);
887
- if (result == ~(u32)0) /* card removed */
888
- return -ENODEV;
889
- result &= mask;
890
- if (result == done)
891
- return 0;
892
- udelay(1);
893
- usec--;
894
- } while (usec > 0);
895
- return -ETIMEDOUT;
889
+ ret = readl_poll_timeout_atomic(ptr, result,
890
+ ((result & mask) == done ||
891
+ result == U32_MAX), 1, usec);
892
+ if (result == U32_MAX) /* card removed */
893
+ return -ENODEV;
894
+
895
+ return ret;
896896 }
897897
898898 /* Force HC to halt state from unknown (EHCI spec section 2.3).
....@@ -1285,7 +1285,7 @@
12851285 */
12861286 status = fotg210_readl(fotg210, &fotg210->regs->status);
12871287 if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
1288
- COUNT(fotg210->stats.lost_iaa);
1288
+ INCR(fotg210->stats.lost_iaa);
12891289 fotg210_writel(fotg210, STS_IAA,
12901290 &fotg210->regs->status);
12911291 }
....@@ -2208,12 +2208,12 @@
22082208 }
22092209
22102210 if (unlikely(urb->unlinked)) {
2211
- COUNT(fotg210->stats.unlink);
2211
+ INCR(fotg210->stats.unlink);
22122212 } else {
22132213 /* report non-error and short read status as zero */
22142214 if (status == -EINPROGRESS || status == -EREMOTEIO)
22152215 status = 0;
2216
- COUNT(fotg210->stats.complete);
2216
+ INCR(fotg210->stats.complete);
22172217 }
22182218
22192219 #ifdef FOTG210_URB_TRACE
....@@ -2802,7 +2802,7 @@
28022802 switch (urb->dev->speed) {
28032803 case USB_SPEED_LOW:
28042804 info1 |= QH_LOW_SPEED;
2805
- /* FALL THROUGH */
2805
+ fallthrough;
28062806
28072807 case USB_SPEED_FULL:
28082808 /* EPS 0 means "full" */
....@@ -4629,7 +4629,7 @@
46294629 default:
46304630 fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
46314631 type, frame, q.ptr);
4632
- /* FALL THROUGH */
4632
+ fallthrough;
46334633 case Q_TYPE_QH:
46344634 case Q_TYPE_FSTN:
46354635 /* End of the iTDs and siTDs */
....@@ -4995,7 +4995,7 @@
49954995 fotg210->command = temp;
49964996
49974997 /* Accept arbitrarily long scatter-gather lists */
4998
- if (!(hcd->driver->flags & HCD_LOCAL_MEM))
4998
+ if (!hcd->localmem_pool)
49994999 hcd->self.sg_tablesize = ~0;
50005000 return 0;
50015001 }
....@@ -5005,7 +5005,6 @@
50055005 {
50065006 struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
50075007 u32 temp;
5008
- u32 hcc_params;
50095008
50105009 hcd->uses_new_polling = 1;
50115010
....@@ -5028,7 +5027,7 @@
50285027 * Scsi_Host.highmem_io, and so forth. It's readonly to all
50295028 * host side drivers though.
50305029 */
5031
- hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
5030
+ fotg210_readl(fotg210, &fotg210->caps->hcc_params);
50325031
50335032 /*
50345033 * Philips, Intel, and maybe others need CMD_RUN before the
....@@ -5154,9 +5153,9 @@
51545153 /* normal [4.15.1.2] or error [4.15.1.1] completion */
51555154 if (likely((status & (STS_INT|STS_ERR)) != 0)) {
51565155 if (likely((status & STS_ERR) == 0))
5157
- COUNT(fotg210->stats.normal);
5156
+ INCR(fotg210->stats.normal);
51585157 else
5159
- COUNT(fotg210->stats.error);
5158
+ INCR(fotg210->stats.error);
51605159 bh = 1;
51615160 }
51625161
....@@ -5181,7 +5180,7 @@
51815180 if (cmd & CMD_IAAD)
51825181 fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
51835182 if (fotg210->async_iaa) {
5184
- COUNT(fotg210->stats.iaa);
5183
+ INCR(fotg210->stats.iaa);
51855184 end_unlink_async(fotg210);
51865185 } else
51875186 fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
....@@ -5407,7 +5406,7 @@
54075406 */
54085407 if (tmp)
54095408 start_unlink_async(fotg210, qh);
5410
- /* FALL THROUGH */
5409
+ fallthrough;
54115410 case QH_STATE_UNLINK: /* wait for hw to finish? */
54125411 case QH_STATE_UNLINK_WAIT:
54135412 idle_timeout:
....@@ -5421,7 +5420,7 @@
54215420 qh_destroy(fotg210, qh);
54225421 break;
54235422 }
5424
- /* fall through */
5423
+ fallthrough;
54255424 default:
54265425 /* caller was supposed to have unlinked any requests;
54275426 * that's not our job. just leak this memory.
....@@ -5503,7 +5502,7 @@
55035502 * generic hardware linkage
55045503 */
55055504 .irq = fotg210_irq,
5506
- .flags = HCD_MEMORY | HCD_USB2,
5505
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
55075506
55085507 /*
55095508 * basic lifecycle operations
....@@ -5553,7 +5552,7 @@
55535552 iowrite32(value, &fotg210->regs->otgcsr);
55545553 }
55555554
5556
-/**
5555
+/*
55575556 * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
55585557 *
55595558 * Allocates basic resources for this USB host controller, and
....@@ -5597,7 +5596,7 @@
55975596 hcd->regs = devm_ioremap_resource(&pdev->dev, res);
55985597 if (IS_ERR(hcd->regs)) {
55995598 retval = PTR_ERR(hcd->regs);
5600
- goto failed;
5599
+ goto failed_put_hcd;
56015600 }
56025601
56035602 hcd->rsrc_start = res->start;
....@@ -5607,40 +5606,65 @@
56075606
56085607 fotg210->caps = hcd->regs;
56095608
5609
+ /* It's OK not to supply this clock */
5610
+ fotg210->pclk = clk_get(dev, "PCLK");
5611
+ if (!IS_ERR(fotg210->pclk)) {
5612
+ retval = clk_prepare_enable(fotg210->pclk);
5613
+ if (retval) {
5614
+ dev_err(dev, "failed to enable PCLK\n");
5615
+ goto failed_put_hcd;
5616
+ }
5617
+ } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
5618
+ /*
5619
+ * Percolate deferrals, for anything else,
5620
+ * just live without the clocking.
5621
+ */
5622
+ retval = PTR_ERR(fotg210->pclk);
5623
+ goto failed_dis_clk;
5624
+ }
5625
+
56105626 retval = fotg210_setup(hcd);
56115627 if (retval)
5612
- goto failed;
5628
+ goto failed_dis_clk;
56135629
56145630 fotg210_init(fotg210);
56155631
56165632 retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
56175633 if (retval) {
56185634 dev_err(dev, "failed to add hcd with err %d\n", retval);
5619
- goto failed;
5635
+ goto failed_dis_clk;
56205636 }
56215637 device_wakeup_enable(hcd->self.controller);
5638
+ platform_set_drvdata(pdev, hcd);
56225639
56235640 return retval;
56245641
5625
-failed:
5642
+failed_dis_clk:
5643
+ if (!IS_ERR(fotg210->pclk)) {
5644
+ clk_disable_unprepare(fotg210->pclk);
5645
+ clk_put(fotg210->pclk);
5646
+ }
5647
+failed_put_hcd:
56265648 usb_put_hcd(hcd);
56275649 fail_create_hcd:
56285650 dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
56295651 return retval;
56305652 }
56315653
5632
-/**
5654
+/*
56335655 * fotg210_hcd_remove - shutdown processing for EHCI HCDs
56345656 * @dev: USB Host Controller being removed
56355657 *
56365658 */
56375659 static int fotg210_hcd_remove(struct platform_device *pdev)
56385660 {
5639
- struct device *dev = &pdev->dev;
5640
- struct usb_hcd *hcd = dev_get_drvdata(dev);
5661
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
5662
+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
56415663
5642
- if (!hcd)
5643
- return 0;
5664
+ if (!IS_ERR(fotg210->pclk)) {
5665
+ clk_disable_unprepare(fotg210->pclk);
5666
+ clk_put(fotg210->pclk);
5667
+ }
56445668
56455669 usb_remove_hcd(hcd);
56465670 usb_put_hcd(hcd);
....@@ -5648,9 +5672,18 @@
56485672 return 0;
56495673 }
56505674
5675
+#ifdef CONFIG_OF
5676
+static const struct of_device_id fotg210_of_match[] = {
5677
+ { .compatible = "faraday,fotg210" },
5678
+ {},
5679
+};
5680
+MODULE_DEVICE_TABLE(of, fotg210_of_match);
5681
+#endif
5682
+
56515683 static struct platform_driver fotg210_hcd_driver = {
56525684 .driver = {
56535685 .name = "fotg210-hcd",
5686
+ .of_match_table = of_match_ptr(fotg210_of_match),
56545687 },
56555688 .probe = fotg210_hcd_probe,
56565689 .remove = fotg210_hcd_remove,