blob: 16520763ff8c6e8236775789c45987eb42b6fc18 [file] [log] [blame]
From 4abdbaec4f9833feb302cdea5c0c98cc9ab2a983 Mon Sep 17 00:00:00 2001
From: David Wang <davidwang@quantatw.com>
Date: Mon, 6 Nov 2023 11:00:40 +0800
Subject: [PATCH 09/16] drivers: usb: host: sync npcm ehci/ohci
---
drivers/usb/host/Kconfig | 16 ++-
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ehci-npcm7xx.c | 50 ---------
drivers/usb/host/ohci-npcm7xx.c | 181 ++++++++++++++++++++++++++++++++
4 files changed, 194 insertions(+), 54 deletions(-)
create mode 100644 drivers/usb/host/ohci-npcm7xx.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index c4736d1d020c..028864f27b74 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -205,12 +205,12 @@ config USB_EHCI_FSL
Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_HCD_NPCM7XX
- tristate "Support for Nuvoton NPCM7XX on-chip EHCI USB controller"
- depends on (USB_EHCI_HCD && ARCH_NPCM7XX) || COMPILE_TEST
- default y if (USB_EHCI_HCD && ARCH_NPCM7XX)
+ tristate "Support for Nuvoton NPCM on-chip EHCI USB controller"
+ depends on (USB_EHCI_HCD && ARCH_NPCM) || COMPILE_TEST
+ default y if (USB_EHCI_HCD && ARCH_NPCM)
help
Enables support for the on-chip EHCI controller on
- Nuvoton NPCM7XX chips.
+ Nuvoton NPCM chips.
config USB_EHCI_HCD_OMAP
tristate "EHCI support for OMAP3 and later chips"
@@ -418,6 +418,14 @@ config USB_OHCI_HCD
if USB_OHCI_HCD
+config USB_OHCI_HCD_NPCM7XX
+ tristate "Support for Nuvoton NPCM7XX on-chip OHCI USB controller"
+ depends on (USB_OHCI_HCD && ARCH_NPCM) || COMPILE_TEST
+ default y if (USB_OHCI_HCD && ARCH_NPCM)
+ help
+ Enables support for the on-chip OHCI controller on
+ Nuvoton NPCM chips.
+
config USB_OHCI_HCD_OMAP1
tristate "OHCI support for OMAP1/2 chips"
depends on ARCH_OMAP1
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 171de4df50bd..3f4f4604d229 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3C2410) += ohci-s3c2410.o
obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o
obj-$(CONFIG_USB_OHCI_HCD_PXA27X) += ohci-pxa27x.o
obj-$(CONFIG_USB_OHCI_HCD_DAVINCI) += ohci-da8xx.o
+obj-$(CONFIG_USB_OHCI_HCD_NPCM7XX) += ohci-npcm7xx.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
diff --git a/drivers/usb/host/ehci-npcm7xx.c b/drivers/usb/host/ehci-npcm7xx.c
index 6b5a7a873e01..1d2e2c3c0bf0 100644
--- a/drivers/usb/host/ehci-npcm7xx.c
+++ b/drivers/usb/host/ehci-npcm7xx.c
@@ -22,19 +22,9 @@
#include "ehci.h"
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-
#define DRIVER_DESC "EHCI npcm7xx driver"
static const char hcd_name[] = "npcm7xx-ehci";
-
-#define USB2PHYCTL_OFFSET 0x144
-
-#define IPSRST2_OFFSET 0x24
-#define IPSRST3_OFFSET 0x34
-
-
static struct hc_driver __read_mostly ehci_npcm7xx_hc_driver;
static int __maybe_unused ehci_npcm7xx_drv_suspend(struct device *dev)
@@ -60,52 +50,12 @@ static int npcm7xx_ehci_hcd_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct resource *res;
- struct regmap *gcr_regmap;
- struct regmap *rst_regmap;
const struct hc_driver *driver = &ehci_npcm7xx_hc_driver;
int irq;
int retval;
dev_dbg(&pdev->dev, "initializing npcm7xx ehci USB Controller\n");
- gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
- if (IS_ERR(gcr_regmap)) {
- dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-gcr\n",
- __func__);
- return PTR_ERR(gcr_regmap);
- }
-
- rst_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst");
- if (IS_ERR(rst_regmap)) {
- dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-rst\n",
- __func__);
- return PTR_ERR(rst_regmap);
- }
-
- /********* phy init ******/
- // reset usb host
- regmap_update_bits(rst_regmap, IPSRST2_OFFSET,
- (0x1 << 26), (0x1 << 26));
- regmap_update_bits(rst_regmap, IPSRST3_OFFSET,
- (0x1 << 25), (0x1 << 25));
- regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET,
- (0x1 << 28), 0);
-
- udelay(1);
-
- // enable phy
- regmap_update_bits(rst_regmap, IPSRST3_OFFSET,
- (0x1 << 25), 0);
-
- udelay(50); // enable phy
-
- regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET,
- (0x1 << 28), (0x1 << 28));
-
- // enable host
- regmap_update_bits(rst_regmap, IPSRST2_OFFSET,
- (0x1 << 26), 0);
-
if (usb_disabled())
return -ENODEV;
diff --git a/drivers/usb/host/ohci-npcm7xx.c b/drivers/usb/host/ohci-npcm7xx.c
new file mode 100644
index 000000000000..815d2e084c85
--- /dev/null
+++ b/drivers/usb/host/ohci-npcm7xx.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nuvoton NPCM7xx driver for OHCI HCD
+ *
+ * Copyright (C) 2019 Nuvoton Technologies,
+ * Tomer Maimon <tomer.maimon@nuvoton.com> <tmaimon77@gmail.com>
+ * Joseph Liu <kwliun@nuvoton.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI NPCM7XX driver"
+
+static const char hcd_name[] = "ohci-npcm7xx";
+static struct hc_driver __read_mostly ohci_npcm7xx_driver;
+
+static int ohci_hcd_npcm7xx_probe(struct platform_device *pdev)
+{
+ struct resource *res = NULL;
+ struct usb_hcd *hcd = NULL;
+ int irq;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ pr_err("platform_get_resource error.");
+ return -ENODEV;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ pr_err("platform_get_irq error.");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_OF
+ /*
+ * Right now device-tree probed devices don't get dma_mask set.
+ * Since shared usb code relies on it, set it here for now.
+ * Once we have dma capability bindings this can go away.
+ */
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return -ENODEV;
+#endif
+
+ /* initialize hcd */
+ hcd = usb_create_hcd(&ohci_npcm7xx_driver, &pdev->dev, (char *)hcd_name);
+ if (!hcd) {
+ pr_err("Failed to create hcd");
+ return -ENOMEM;
+ }
+
+ hcd->regs = (void __iomem *)res->start;
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_dbg(&pdev->dev, "controller already in use\n");
+ ret = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (hcd->regs == NULL) {
+ dev_dbg(&pdev->dev, "error mapping memory\n");
+ ret = -EFAULT;
+ goto err_release_region;
+ }
+
+ ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (ret != 0) {
+ pr_err("Failed to add hcd");
+ usb_put_hcd(hcd);
+ return ret;
+ }
+
+ return ret;
+
+ err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ err_put_hcd:
+ usb_put_hcd(hcd);
+ return ret;
+
+}
+
+static int ohci_hcd_npcm7xx_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ohci_npcm7xx_suspend(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ bool do_wakeup = device_may_wakeup(dev);
+ int rc = ohci_suspend(hcd, do_wakeup);
+
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int ohci_npcm7xx_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+ ohci_resume(hcd, false);
+
+ return 0;
+}
+#else
+#define ohci_npcm7xx_suspend NULL
+#define ohci_npcm7xx_resume NULL
+#endif
+
+
+#ifdef CONFIG_OF
+static const struct of_device_id npcm750_ohci_match[] = {
+ { .compatible = "nuvoton,npcm750-ohci" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, npcm750_ohci_match);
+#endif
+
+static const struct dev_pm_ops npcm7xx_ohci_pm_ops = {
+ .suspend = ohci_npcm7xx_suspend,
+ .resume = ohci_npcm7xx_resume,
+};
+
+static struct platform_driver ohci_hcd_npcm7xx_driver = {
+ .probe = ohci_hcd_npcm7xx_probe,
+ .remove = ohci_hcd_npcm7xx_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "npcm7xx-ohci",
+ .pm = &npcm7xx_ohci_pm_ops,
+ .of_match_table = of_match_ptr(npcm750_ohci_match),
+ },
+};
+
+static int __init ohci_npcm7xx_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+ ohci_init_driver(&ohci_npcm7xx_driver, NULL);
+ return platform_driver_register(&ohci_hcd_npcm7xx_driver);
+}
+module_init(ohci_npcm7xx_init);
+
+static void __exit ohci_npcm7xx_cleanup(void)
+{
+ platform_driver_unregister(&ohci_hcd_npcm7xx_driver);
+}
+module_exit(ohci_npcm7xx_cleanup);
+
+MODULE_ALIAS("platform:npcm7xx_ohci");
+MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
+MODULE_AUTHOR("Joseph Liu<kwliun@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
--
2.25.1