gemini: Add kernel v6.1 patches
This adds a bunch of patches for the v6.1 Gemini kernel. For v5.15 this was down to a single upstream patch, but for kernel v6.2 I reworked the USB code for FOTG210, so instead of carrying over the half-baked and incomplete patch from v5.15 I just backported all the v6.2 patches, 31 in total, as it creates full device USB mode for e.g. D-Link DNS-313. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
This commit is contained in:
parent
33abdc07fb
commit
58acb1dd2c
@ -0,0 +1,67 @@
|
|||||||
|
From d5a026cc8306ccd3e99e1455c87e38f8e6fa18df Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 7 Nov 2022 00:05:06 +0100
|
||||||
|
Subject: [PATCH 01/29] usb: phy: phy-gpio-vbus-usb: Add device tree probing
|
||||||
|
|
||||||
|
Make it possible to probe the GPIO VBUS detection driver
|
||||||
|
from the device tree compatible for GPIO USB B connectors.
|
||||||
|
|
||||||
|
Since this driver is using the "gpio-usb-b-connector"
|
||||||
|
compatible, it is important to discern it from the role
|
||||||
|
switch connector driver (which does not provide a phy),
|
||||||
|
so we add some Kconfig text and depend on !USB_CONN_GPIO.
|
||||||
|
|
||||||
|
Cc: Rob Herring <robh@kernel.org>
|
||||||
|
Cc: Prashant Malani <pmalani@chromium.org>
|
||||||
|
Cc: Felipe Balbi <balbi@kernel.org>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221106230506.1646101-1-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/phy/Kconfig
|
||||||
|
+++ b/drivers/usb/phy/Kconfig
|
||||||
|
@@ -93,12 +93,16 @@ config USB_GPIO_VBUS
|
||||||
|
tristate "GPIO based peripheral-only VBUS sensing 'transceiver'"
|
||||||
|
depends on GPIOLIB || COMPILE_TEST
|
||||||
|
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
|
||||||
|
+ depends on !USB_CONN_GPIO
|
||||||
|
select USB_PHY
|
||||||
|
help
|
||||||
|
Provides simple GPIO VBUS sensing for controllers with an
|
||||||
|
internal transceiver via the usb_phy interface, and
|
||||||
|
optionally control of a D+ pullup GPIO as well as a VBUS
|
||||||
|
- current limit regulator.
|
||||||
|
+ current limit regulator. This driver is for devices that do
|
||||||
|
+ NOT support role switch. OTG devices that can do role switch
|
||||||
|
+ (master/peripheral) shall use the USB based connection
|
||||||
|
+ detection driver USB_CONN_GPIO.
|
||||||
|
|
||||||
|
config OMAP_OTG
|
||||||
|
tristate "OMAP USB OTG controller driver"
|
||||||
|
--- a/drivers/usb/phy/phy-gpio-vbus-usb.c
|
||||||
|
+++ b/drivers/usb/phy/phy-gpio-vbus-usb.c
|
||||||
|
@@ -366,12 +366,24 @@ static const struct dev_pm_ops gpio_vbus
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:gpio-vbus");
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * NOTE: this driver matches against "gpio-usb-b-connector" for
|
||||||
|
+ * devices that do NOT support role switch.
|
||||||
|
+ */
|
||||||
|
+static const struct of_device_id gpio_vbus_of_match[] = {
|
||||||
|
+ {
|
||||||
|
+ .compatible = "gpio-usb-b-connector",
|
||||||
|
+ },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static struct platform_driver gpio_vbus_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "gpio-vbus",
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.pm = &gpio_vbus_dev_pm_ops,
|
||||||
|
#endif
|
||||||
|
+ .of_match_table = gpio_vbus_of_match,
|
||||||
|
},
|
||||||
|
.probe = gpio_vbus_probe,
|
||||||
|
.remove = gpio_vbus_remove,
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,332 @@
|
|||||||
|
From 0dbc77a99267a5efef0603a4b49ac02ece6a3f23 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Sun, 23 Oct 2022 16:47:07 +0200
|
||||||
|
Subject: [PATCH 03/29] usb: fotg210: Compile into one module
|
||||||
|
|
||||||
|
It is since ages perfectly possible to compile both of these
|
||||||
|
modules into the same kernel, which makes no sense since it
|
||||||
|
is one piece of hardware.
|
||||||
|
|
||||||
|
Compile one module named "fotg210.ko" for both HCD and UDC
|
||||||
|
drivers by collecting the init calls into a fotg210-core.c
|
||||||
|
file and start to centralize things handling one and the same
|
||||||
|
piece of hardware.
|
||||||
|
|
||||||
|
Stub out the initcalls if one or the other part of the driver
|
||||||
|
was not selected.
|
||||||
|
|
||||||
|
Tested by compiling one or the other or both of the drivers
|
||||||
|
into the kernel and as modules.
|
||||||
|
|
||||||
|
Cc: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
|
||||||
|
Cc: Felipe Balbi <balbi@kernel.org>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221023144708.3596563-2-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/Kconfig
|
||||||
|
+++ b/drivers/usb/fotg210/Kconfig
|
||||||
|
@@ -12,7 +12,7 @@ config USB_FOTG210
|
||||||
|
if USB_FOTG210
|
||||||
|
|
||||||
|
config USB_FOTG210_HCD
|
||||||
|
- tristate "Faraday FOTG210 USB Host Controller support"
|
||||||
|
+ bool "Faraday FOTG210 USB Host Controller support"
|
||||||
|
depends on USB
|
||||||
|
help
|
||||||
|
Faraday FOTG210 is an OTG controller which can be configured as
|
||||||
|
@@ -24,7 +24,7 @@ config USB_FOTG210_HCD
|
||||||
|
|
||||||
|
config USB_FOTG210_UDC
|
||||||
|
depends on USB_GADGET
|
||||||
|
- tristate "Faraday FOTG210 USB Peripheral Controller support"
|
||||||
|
+ bool "Faraday FOTG210 USB Peripheral Controller support"
|
||||||
|
help
|
||||||
|
Faraday USB2.0 OTG controller which can be configured as
|
||||||
|
high speed or full speed USB device. This driver suppports
|
||||||
|
--- a/drivers/usb/fotg210/Makefile
|
||||||
|
+++ b/drivers/usb/fotg210/Makefile
|
||||||
|
@@ -1,3 +1,10 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
-obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
|
||||||
|
-obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
|
||||||
|
+
|
||||||
|
+# This setup links the different object files into one single
|
||||||
|
+# module so we don't have to EXPORT() a lot of internal symbols
|
||||||
|
+# or create unnecessary submodules.
|
||||||
|
+fotg210-objs-y += fotg210-core.o
|
||||||
|
+fotg210-objs-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
|
||||||
|
+fotg210-objs-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
|
||||||
|
+fotg210-objs := $(fotg210-objs-y)
|
||||||
|
+obj-$(CONFIG_USB_FOTG210) += fotg210.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -0,0 +1,79 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
+/*
|
||||||
|
+ * Central probing code for the FOTG210 dual role driver
|
||||||
|
+ * We register one driver for the hardware and then we decide
|
||||||
|
+ * whether to proceed with probing the host or the peripheral
|
||||||
|
+ * driver.
|
||||||
|
+ */
|
||||||
|
+#include <linux/device.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/usb.h>
|
||||||
|
+
|
||||||
|
+#include "fotg210.h"
|
||||||
|
+
|
||||||
|
+static int fotg210_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) {
|
||||||
|
+ ret = fotg210_hcd_probe(pdev);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
|
||||||
|
+ ret = fotg210_udc_probe(pdev);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int fotg210_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
|
||||||
|
+ fotg210_hcd_remove(pdev);
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
|
||||||
|
+ fotg210_udc_remove(pdev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_OF
|
||||||
|
+static const struct of_device_id fotg210_of_match[] = {
|
||||||
|
+ { .compatible = "faraday,fotg210" },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, fotg210_of_match);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static struct platform_driver fotg210_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "fotg210",
|
||||||
|
+ .of_match_table = of_match_ptr(fotg210_of_match),
|
||||||
|
+ },
|
||||||
|
+ .probe = fotg210_probe,
|
||||||
|
+ .remove = fotg210_remove,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init fotg210_init(void)
|
||||||
|
+{
|
||||||
|
+ if (usb_disabled())
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
|
||||||
|
+ fotg210_hcd_init();
|
||||||
|
+ return platform_driver_register(&fotg210_driver);
|
||||||
|
+}
|
||||||
|
+module_init(fotg210_init);
|
||||||
|
+
|
||||||
|
+static void __exit fotg210_cleanup(void)
|
||||||
|
+{
|
||||||
|
+ platform_driver_unregister(&fotg210_driver);
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
|
||||||
|
+ fotg210_hcd_cleanup();
|
||||||
|
+}
|
||||||
|
+module_exit(fotg210_cleanup);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+MODULE_DESCRIPTION("FOTG210 Dual Role Controller Driver");
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
@@ -39,8 +39,8 @@
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
-#define DRIVER_AUTHOR "Yuan-Hsin Chen"
|
||||||
|
-#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
|
||||||
|
+#include "fotg210.h"
|
||||||
|
+
|
||||||
|
static const char hcd_name[] = "fotg210_hcd";
|
||||||
|
|
||||||
|
#undef FOTG210_URB_TRACE
|
||||||
|
@@ -5490,9 +5490,6 @@ static int fotg210_get_frame(struct usb_
|
||||||
|
* functions and in order to facilitate role switching we cannot
|
||||||
|
* give the fotg210 driver exclusive access to those.
|
||||||
|
*/
|
||||||
|
-MODULE_DESCRIPTION(DRIVER_DESC);
|
||||||
|
-MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||||
|
-MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
static const struct hc_driver fotg210_fotg210_hc_driver = {
|
||||||
|
.description = hcd_name,
|
||||||
|
@@ -5560,7 +5557,7 @@ static void fotg210_init(struct fotg210_
|
||||||
|
* then invokes the start() method for the HCD associated with it
|
||||||
|
* through the hotplug entry's driver_data.
|
||||||
|
*/
|
||||||
|
-static int fotg210_hcd_probe(struct platform_device *pdev)
|
||||||
|
+int fotg210_hcd_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct usb_hcd *hcd;
|
||||||
|
@@ -5652,7 +5649,7 @@ fail_create_hcd:
|
||||||
|
* @dev: USB Host Controller being removed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
-static int fotg210_hcd_remove(struct platform_device *pdev)
|
||||||
|
+int fotg210_hcd_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
|
||||||
|
@@ -5668,27 +5665,8 @@ static int fotg210_hcd_remove(struct pla
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef CONFIG_OF
|
||||||
|
-static const struct of_device_id fotg210_of_match[] = {
|
||||||
|
- { .compatible = "faraday,fotg210" },
|
||||||
|
- {},
|
||||||
|
-};
|
||||||
|
-MODULE_DEVICE_TABLE(of, fotg210_of_match);
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-static struct platform_driver fotg210_hcd_driver = {
|
||||||
|
- .driver = {
|
||||||
|
- .name = "fotg210-hcd",
|
||||||
|
- .of_match_table = of_match_ptr(fotg210_of_match),
|
||||||
|
- },
|
||||||
|
- .probe = fotg210_hcd_probe,
|
||||||
|
- .remove = fotg210_hcd_remove,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static int __init fotg210_hcd_init(void)
|
||||||
|
+int __init fotg210_hcd_init(void)
|
||||||
|
{
|
||||||
|
- int retval = 0;
|
||||||
|
-
|
||||||
|
if (usb_disabled())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
@@ -5704,24 +5682,11 @@ static int __init fotg210_hcd_init(void)
|
||||||
|
|
||||||
|
fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
|
||||||
|
|
||||||
|
- retval = platform_driver_register(&fotg210_hcd_driver);
|
||||||
|
- if (retval < 0)
|
||||||
|
- goto clean;
|
||||||
|
- return retval;
|
||||||
|
-
|
||||||
|
-clean:
|
||||||
|
- debugfs_remove(fotg210_debug_root);
|
||||||
|
- fotg210_debug_root = NULL;
|
||||||
|
-
|
||||||
|
- clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
|
||||||
|
- return retval;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
-module_init(fotg210_hcd_init);
|
||||||
|
|
||||||
|
-static void __exit fotg210_hcd_cleanup(void)
|
||||||
|
+void __exit fotg210_hcd_cleanup(void)
|
||||||
|
{
|
||||||
|
- platform_driver_unregister(&fotg210_hcd_driver);
|
||||||
|
debugfs_remove(fotg210_debug_root);
|
||||||
|
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
|
||||||
|
}
|
||||||
|
-module_exit(fotg210_hcd_cleanup);
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <linux/usb/gadget.h>
|
||||||
|
|
||||||
|
+#include "fotg210.h"
|
||||||
|
#include "fotg210-udc.h"
|
||||||
|
|
||||||
|
#define DRIVER_DESC "FOTG210 USB Device Controller Driver"
|
||||||
|
@@ -1081,7 +1082,7 @@ static const struct usb_gadget_ops fotg2
|
||||||
|
.udc_stop = fotg210_udc_stop,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int fotg210_udc_remove(struct platform_device *pdev)
|
||||||
|
+int fotg210_udc_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
|
||||||
|
int i;
|
||||||
|
@@ -1098,7 +1099,7 @@ static int fotg210_udc_remove(struct pla
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
+int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res, *ires;
|
||||||
|
struct fotg210_udc *fotg210 = NULL;
|
||||||
|
@@ -1223,17 +1224,3 @@ err_alloc:
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-static struct platform_driver fotg210_driver = {
|
||||||
|
- .driver = {
|
||||||
|
- .name = udc_name,
|
||||||
|
- },
|
||||||
|
- .probe = fotg210_udc_probe,
|
||||||
|
- .remove = fotg210_udc_remove,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-module_platform_driver(fotg210_driver);
|
||||||
|
-
|
||||||
|
-MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
|
||||||
|
-MODULE_LICENSE("GPL");
|
||||||
|
-MODULE_DESCRIPTION(DRIVER_DESC);
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210.h
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+#ifndef __FOTG210_H
|
||||||
|
+#define __FOTG210_H
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_USB_FOTG210_HCD
|
||||||
|
+int fotg210_hcd_probe(struct platform_device *pdev);
|
||||||
|
+int fotg210_hcd_remove(struct platform_device *pdev);
|
||||||
|
+int fotg210_hcd_init(void);
|
||||||
|
+void fotg210_hcd_cleanup(void);
|
||||||
|
+#else
|
||||||
|
+static inline int fotg210_hcd_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+static inline int fotg210_hcd_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+static inline int fotg210_hcd_init(void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+static inline void fotg210_hcd_cleanup(void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_USB_FOTG210_UDC
|
||||||
|
+int fotg210_udc_probe(struct platform_device *pdev);
|
||||||
|
+int fotg210_udc_remove(struct platform_device *pdev);
|
||||||
|
+#else
|
||||||
|
+static inline int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+static inline int fotg210_udc_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* __FOTG210_H */
|
@ -0,0 +1,68 @@
|
|||||||
|
From 7c0b661926097e935f2711857596fc2277b2304a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Sun, 23 Oct 2022 16:47:08 +0200
|
||||||
|
Subject: [PATCH 04/29] usb: fotg210: Select subdriver by mode
|
||||||
|
|
||||||
|
Check which mode the hardware is in, and selecte the peripheral
|
||||||
|
driver if the hardware is in explicit peripheral mode, otherwise
|
||||||
|
select host mode.
|
||||||
|
|
||||||
|
This should solve the immediate problem that both subdrivers
|
||||||
|
can get probed.
|
||||||
|
|
||||||
|
Cc: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
|
||||||
|
Cc: Felipe Balbi <balbi@kernel.org>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221023144708.3596563-3-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -10,30 +10,37 @@
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
+#include <linux/usb/otg.h>
|
||||||
|
|
||||||
|
#include "fotg210.h"
|
||||||
|
|
||||||
|
static int fotg210_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ enum usb_dr_mode mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) {
|
||||||
|
- ret = fotg210_hcd_probe(pdev);
|
||||||
|
- if (ret)
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
- if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
|
||||||
|
+ mode = usb_get_dr_mode(dev);
|
||||||
|
+
|
||||||
|
+ if (mode == USB_DR_MODE_PERIPHERAL)
|
||||||
|
ret = fotg210_udc_probe(pdev);
|
||||||
|
+ else
|
||||||
|
+ ret = fotg210_hcd_probe(pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fotg210_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
|
||||||
|
- fotg210_hcd_remove(pdev);
|
||||||
|
- if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ enum usb_dr_mode mode;
|
||||||
|
+
|
||||||
|
+ mode = usb_get_dr_mode(dev);
|
||||||
|
+
|
||||||
|
+ if (mode == USB_DR_MODE_PERIPHERAL)
|
||||||
|
fotg210_udc_remove(pdev);
|
||||||
|
+ else
|
||||||
|
+ fotg210_hcd_remove(pdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
From f7f6c8aca91093e2f886ec97910b1a7d9a69bf9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 9 Nov 2022 21:05:54 +0100
|
||||||
|
Subject: [PATCH 05/29] usb: fotg2: add Gemini-specific handling
|
||||||
|
|
||||||
|
The Cortina Systems Gemini has bolted on a PHY inside the
|
||||||
|
silicon that can be handled by six bits in a MISC register in
|
||||||
|
the system controller.
|
||||||
|
|
||||||
|
If we are running on Gemini, look up a syscon regmap through
|
||||||
|
a phandle and enable VBUS and optionally the Mini-B connector.
|
||||||
|
|
||||||
|
If the device is flagged as "wakeup-source" using the standard
|
||||||
|
DT bindings, we also enable this in the global controller for
|
||||||
|
respective port.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221109200554.1957185-1-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/Kconfig
|
||||||
|
+++ b/drivers/usb/fotg210/Kconfig
|
||||||
|
@@ -5,6 +5,7 @@ config USB_FOTG210
|
||||||
|
depends on USB || USB_GADGET
|
||||||
|
depends on HAS_DMA && HAS_IOMEM
|
||||||
|
default ARCH_GEMINI
|
||||||
|
+ select MFD_SYSCON
|
||||||
|
help
|
||||||
|
Faraday FOTG210 is a dual-mode USB controller that can act
|
||||||
|
in both host controller and peripheral controller mode.
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -5,15 +5,86 @@
|
||||||
|
* whether to proceed with probing the host or the peripheral
|
||||||
|
* driver.
|
||||||
|
*/
|
||||||
|
+#include <linux/bitops.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
+#include <linux/mfd/syscon.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
+#include <linux/regmap.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
#include <linux/usb/otg.h>
|
||||||
|
|
||||||
|
#include "fotg210.h"
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Gemini-specific initialization function, only executed on the
|
||||||
|
+ * Gemini SoC using the global misc control register.
|
||||||
|
+ *
|
||||||
|
+ * The gemini USB blocks are connected to either Mini-A (host mode) or
|
||||||
|
+ * Mini-B (peripheral mode) plugs. There is no role switch support on the
|
||||||
|
+ * Gemini SoC, just either-or.
|
||||||
|
+ */
|
||||||
|
+#define GEMINI_GLOBAL_MISC_CTRL 0x30
|
||||||
|
+#define GEMINI_MISC_USB0_WAKEUP BIT(14)
|
||||||
|
+#define GEMINI_MISC_USB1_WAKEUP BIT(15)
|
||||||
|
+#define GEMINI_MISC_USB0_VBUS_ON BIT(22)
|
||||||
|
+#define GEMINI_MISC_USB1_VBUS_ON BIT(23)
|
||||||
|
+#define GEMINI_MISC_USB0_MINI_B BIT(29)
|
||||||
|
+#define GEMINI_MISC_USB1_MINI_B BIT(30)
|
||||||
|
+
|
||||||
|
+static int fotg210_gemini_init(struct device *dev, struct resource *res,
|
||||||
|
+ enum usb_dr_mode mode)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = dev->of_node;
|
||||||
|
+ struct regmap *map;
|
||||||
|
+ bool wakeup;
|
||||||
|
+ u32 mask, val;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ map = syscon_regmap_lookup_by_phandle(np, "syscon");
|
||||||
|
+ if (IS_ERR(map)) {
|
||||||
|
+ dev_err(dev, "no syscon\n");
|
||||||
|
+ return PTR_ERR(map);
|
||||||
|
+ }
|
||||||
|
+ wakeup = of_property_read_bool(np, "wakeup-source");
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Figure out if this is USB0 or USB1 by simply checking the
|
||||||
|
+ * physical base address.
|
||||||
|
+ */
|
||||||
|
+ mask = 0;
|
||||||
|
+ if (res->start == 0x69000000) {
|
||||||
|
+ mask = GEMINI_MISC_USB1_VBUS_ON | GEMINI_MISC_USB1_MINI_B |
|
||||||
|
+ GEMINI_MISC_USB1_WAKEUP;
|
||||||
|
+ if (mode == USB_DR_MODE_HOST)
|
||||||
|
+ val = GEMINI_MISC_USB1_VBUS_ON;
|
||||||
|
+ else
|
||||||
|
+ val = GEMINI_MISC_USB1_MINI_B;
|
||||||
|
+ if (wakeup)
|
||||||
|
+ val |= GEMINI_MISC_USB1_WAKEUP;
|
||||||
|
+ } else {
|
||||||
|
+ mask = GEMINI_MISC_USB0_VBUS_ON | GEMINI_MISC_USB0_MINI_B |
|
||||||
|
+ GEMINI_MISC_USB0_WAKEUP;
|
||||||
|
+ if (mode == USB_DR_MODE_HOST)
|
||||||
|
+ val = GEMINI_MISC_USB0_VBUS_ON;
|
||||||
|
+ else
|
||||||
|
+ val = GEMINI_MISC_USB0_MINI_B;
|
||||||
|
+ if (wakeup)
|
||||||
|
+ val |= GEMINI_MISC_USB0_WAKEUP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
|
||||||
|
+ if (ret) {
|
||||||
|
+ dev_err(dev, "failed to initialize Gemini PHY\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(dev, "initialized Gemini PHY in %s mode\n",
|
||||||
|
+ (mode == USB_DR_MODE_HOST) ? "host" : "gadget");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int fotg210_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
@@ -22,6 +93,15 @@ static int fotg210_probe(struct platform
|
||||||
|
|
||||||
|
mode = usb_get_dr_mode(dev);
|
||||||
|
|
||||||
|
+ if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
|
||||||
|
+ struct resource *res;
|
||||||
|
+
|
||||||
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ ret = fotg210_gemini_init(dev, res, mode);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (mode == USB_DR_MODE_PERIPHERAL)
|
||||||
|
ret = fotg210_udc_probe(pdev);
|
||||||
|
else
|
@ -0,0 +1,51 @@
|
|||||||
|
From 6e002d41889bc52213a26ff91338d340505e0336 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Fri, 11 Nov 2022 15:48:21 +0100
|
||||||
|
Subject: [PATCH 06/29] usb: fotg210: Fix Kconfig for USB host modules
|
||||||
|
|
||||||
|
The kernel robot reports a link failure when activating the
|
||||||
|
FOTG210 host subdriver with =y on a system where the USB host
|
||||||
|
core is a module (CONFIG_USB=m).
|
||||||
|
|
||||||
|
This is a bit of special case, so mimic the Kconfig incantations
|
||||||
|
from DWC3: let the subdrivers for host or peripheral depend
|
||||||
|
on the host or gadget support being =y or the same as the
|
||||||
|
FOTG210 core itself.
|
||||||
|
|
||||||
|
This should ensure that either:
|
||||||
|
|
||||||
|
- The host (CONFIG_USB) or gadget (CONFIG_GADGET) is compiled
|
||||||
|
in and then the FOTG210 can be either module or compiled
|
||||||
|
in.
|
||||||
|
|
||||||
|
- The host or gadget is modular, and then the FOTG210 module
|
||||||
|
must be a module too, or we cannot resolve the symbols
|
||||||
|
at link time.
|
||||||
|
|
||||||
|
Reported-by: kernel test robot <lkp@intel.com>
|
||||||
|
Link: https://lore.kernel.org/linux-usb/202211112132.0BUPGKCd-lkp@intel.com/
|
||||||
|
Cc: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221111144821.113665-1-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/Kconfig
|
||||||
|
+++ b/drivers/usb/fotg210/Kconfig
|
||||||
|
@@ -14,7 +14,7 @@ if USB_FOTG210
|
||||||
|
|
||||||
|
config USB_FOTG210_HCD
|
||||||
|
bool "Faraday FOTG210 USB Host Controller support"
|
||||||
|
- depends on USB
|
||||||
|
+ depends on USB=y || USB=USB_FOTG210
|
||||||
|
help
|
||||||
|
Faraday FOTG210 is an OTG controller which can be configured as
|
||||||
|
an USB2.0 host. It is designed to meet USB2.0 EHCI specification
|
||||||
|
@@ -24,7 +24,7 @@ config USB_FOTG210_HCD
|
||||||
|
module will be called fotg210-hcd.
|
||||||
|
|
||||||
|
config USB_FOTG210_UDC
|
||||||
|
- depends on USB_GADGET
|
||||||
|
+ depends on USB_GADGET=y || USB_GADGET=USB_FOTG210
|
||||||
|
bool "Faraday FOTG210 USB Peripheral Controller support"
|
||||||
|
help
|
||||||
|
Faraday USB2.0 OTG controller which can be configured as
|
@ -0,0 +1,26 @@
|
|||||||
|
From 466b10510add46afd21ca19505b29d35ad853370 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||||
|
Date: Mon, 21 Nov 2022 16:22:19 +0100
|
||||||
|
Subject: [PATCH 07/29] usb: USB_FOTG210 should depend on ARCH_GEMINI
|
||||||
|
|
||||||
|
The Faraday Technology FOTG210 USB2 Dual Role Controller is only present
|
||||||
|
on Cortina Systems Gemini SoCs. Hence add a dependency on ARCH_GEMINI,
|
||||||
|
to prevent asking the user about its drivers when configuring a kernel
|
||||||
|
without Cortina Systems Gemini SoC support.
|
||||||
|
|
||||||
|
Fixes: 1dd33a9f1b95ab59 ("usb: fotg210: Collect pieces of dual mode controller")
|
||||||
|
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/a989b3b798ecaf3b45f35160e30e605636d66a77.1669044086.git.geert+renesas@glider.be
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/Kconfig
|
||||||
|
+++ b/drivers/usb/fotg210/Kconfig
|
||||||
|
@@ -4,6 +4,7 @@ config USB_FOTG210
|
||||||
|
tristate "Faraday FOTG210 USB2 Dual Role controller"
|
||||||
|
depends on USB || USB_GADGET
|
||||||
|
depends on HAS_DMA && HAS_IOMEM
|
||||||
|
+ depends on ARCH_GEMINI || COMPILE_TEST
|
||||||
|
default ARCH_GEMINI
|
||||||
|
select MFD_SYSCON
|
||||||
|
help
|
@ -0,0 +1,61 @@
|
|||||||
|
From 27cd321a365fecac857e41ad1681062994142e4a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 14 Nov 2022 12:51:58 +0100
|
||||||
|
Subject: [PATCH 08/29] fotg210-udc: Use dev pointer in probe and dev_messages
|
||||||
|
|
||||||
|
Add a local struct device *dev pointer and use dev_err()
|
||||||
|
etc to report status.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221114115201.302887-1-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1104,6 +1104,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
struct resource *res, *ires;
|
||||||
|
struct fotg210_udc *fotg210 = NULL;
|
||||||
|
struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1135,7 +1136,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
|
||||||
|
fotg210->reg = ioremap(res->start, resource_size(res));
|
||||||
|
if (fotg210->reg == NULL) {
|
||||||
|
- pr_err("ioremap error.\n");
|
||||||
|
+ dev_err(dev, "ioremap error\n");
|
||||||
|
goto err_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1146,8 +1147,8 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
fotg210->gadget.ops = &fotg210_gadget_ops;
|
||||||
|
|
||||||
|
fotg210->gadget.max_speed = USB_SPEED_HIGH;
|
||||||
|
- fotg210->gadget.dev.parent = &pdev->dev;
|
||||||
|
- fotg210->gadget.dev.dma_mask = pdev->dev.dma_mask;
|
||||||
|
+ fotg210->gadget.dev.parent = dev;
|
||||||
|
+ fotg210->gadget.dev.dma_mask = dev->dma_mask;
|
||||||
|
fotg210->gadget.name = udc_name;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&fotg210->gadget.ep_list);
|
||||||
|
@@ -1195,15 +1196,15 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
|
||||||
|
udc_name, fotg210);
|
||||||
|
if (ret < 0) {
|
||||||
|
- pr_err("request_irq error (%d)\n", ret);
|
||||||
|
+ dev_err(dev, "request_irq error (%d)\n", ret);
|
||||||
|
goto err_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
|
||||||
|
+ ret = usb_add_gadget_udc(dev, &fotg210->gadget);
|
||||||
|
if (ret)
|
||||||
|
goto err_add_udc;
|
||||||
|
|
||||||
|
- dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
|
||||||
|
+ dev_info(dev, "version %s\n", DRIVER_VERSION);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
@ -0,0 +1,158 @@
|
|||||||
|
From 03e4b585ac947e2d422bedf03179bbfec3aca3cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 14 Nov 2022 12:51:59 +0100
|
||||||
|
Subject: [PATCH 09/29] fotg210-udc: Support optional external PHY
|
||||||
|
|
||||||
|
This adds support for an optional external PHY to the FOTG210
|
||||||
|
UDC driver.
|
||||||
|
|
||||||
|
Tested with the GPIO VBUS PHY driver on the Gemini SoC.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221114115201.302887-2-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -15,6 +15,8 @@
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <linux/usb/gadget.h>
|
||||||
|
+#include <linux/usb/otg.h>
|
||||||
|
+#include <linux/usb/phy.h>
|
||||||
|
|
||||||
|
#include "fotg210.h"
|
||||||
|
#include "fotg210-udc.h"
|
||||||
|
@@ -1022,10 +1024,18 @@ static int fotg210_udc_start(struct usb_
|
||||||
|
{
|
||||||
|
struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
|
||||||
|
u32 value;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
/* hook up the driver */
|
||||||
|
fotg210->driver = driver;
|
||||||
|
|
||||||
|
+ if (!IS_ERR_OR_NULL(fotg210->phy)) {
|
||||||
|
+ ret = otg_set_peripheral(fotg210->phy->otg,
|
||||||
|
+ &fotg210->gadget);
|
||||||
|
+ if (ret)
|
||||||
|
+ dev_err(fotg210->dev, "can't bind to phy\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* enable device global interrupt */
|
||||||
|
value = ioread32(fotg210->reg + FOTG210_DMCR);
|
||||||
|
value |= DMCR_GLINT_EN;
|
||||||
|
@@ -1067,6 +1077,9 @@ static int fotg210_udc_stop(struct usb_g
|
||||||
|
struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
+ if (!IS_ERR_OR_NULL(fotg210->phy))
|
||||||
|
+ return otg_set_peripheral(fotg210->phy->otg, NULL);
|
||||||
|
+
|
||||||
|
spin_lock_irqsave(&fotg210->lock, flags);
|
||||||
|
|
||||||
|
fotg210_init(fotg210);
|
||||||
|
@@ -1082,12 +1095,50 @@ static const struct usb_gadget_ops fotg2
|
||||||
|
.udc_stop = fotg210_udc_stop,
|
||||||
|
};
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * fotg210_phy_event - Called by phy upon VBus event
|
||||||
|
+ * @nb: notifier block
|
||||||
|
+ * @action: phy action, is vbus connect or disconnect
|
||||||
|
+ * @data: the usb_gadget structure in fotg210
|
||||||
|
+ *
|
||||||
|
+ * Called by the USB Phy when a cable connect or disconnect is sensed.
|
||||||
|
+ *
|
||||||
|
+ * Returns NOTIFY_OK or NOTIFY_DONE
|
||||||
|
+ */
|
||||||
|
+static int fotg210_phy_event(struct notifier_block *nb, unsigned long action,
|
||||||
|
+ void *data)
|
||||||
|
+{
|
||||||
|
+ struct usb_gadget *gadget = data;
|
||||||
|
+
|
||||||
|
+ if (!gadget)
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
+
|
||||||
|
+ switch (action) {
|
||||||
|
+ case USB_EVENT_VBUS:
|
||||||
|
+ usb_gadget_vbus_connect(gadget);
|
||||||
|
+ return NOTIFY_OK;
|
||||||
|
+ case USB_EVENT_NONE:
|
||||||
|
+ usb_gadget_vbus_disconnect(gadget);
|
||||||
|
+ return NOTIFY_OK;
|
||||||
|
+ default:
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct notifier_block fotg210_phy_notifier = {
|
||||||
|
+ .notifier_call = fotg210_phy_event,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
int fotg210_udc_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
usb_del_gadget_udc(&fotg210->gadget);
|
||||||
|
+ if (!IS_ERR_OR_NULL(fotg210->phy)) {
|
||||||
|
+ usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
|
||||||
|
+ usb_put_phy(fotg210->phy);
|
||||||
|
+ }
|
||||||
|
iounmap(fotg210->reg);
|
||||||
|
free_irq(platform_get_irq(pdev, 0), fotg210);
|
||||||
|
|
||||||
|
@@ -1127,6 +1178,22 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
if (fotg210 == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
+ fotg210->dev = dev;
|
||||||
|
+
|
||||||
|
+ fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
|
||||||
|
+ if (IS_ERR(fotg210->phy)) {
|
||||||
|
+ ret = PTR_ERR(fotg210->phy);
|
||||||
|
+ if (ret == -EPROBE_DEFER)
|
||||||
|
+ goto err;
|
||||||
|
+ dev_info(dev, "no PHY found\n");
|
||||||
|
+ fotg210->phy = NULL;
|
||||||
|
+ } else {
|
||||||
|
+ ret = usb_phy_init(fotg210->phy);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err;
|
||||||
|
+ dev_info(dev, "found and initialized PHY\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
|
||||||
|
_ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
|
||||||
|
if (_ep[i] == NULL)
|
||||||
|
@@ -1200,6 +1267,9 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
goto err_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!IS_ERR_OR_NULL(fotg210->phy))
|
||||||
|
+ usb_register_notifier(fotg210->phy, &fotg210_phy_notifier);
|
||||||
|
+
|
||||||
|
ret = usb_add_gadget_udc(dev, &fotg210->gadget);
|
||||||
|
if (ret)
|
||||||
|
goto err_add_udc;
|
||||||
|
@@ -1209,6 +1279,8 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_add_udc:
|
||||||
|
+ if (!IS_ERR_OR_NULL(fotg210->phy))
|
||||||
|
+ usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
|
||||||
|
free_irq(ires->start, fotg210);
|
||||||
|
|
||||||
|
err_req:
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
@@ -234,6 +234,8 @@ struct fotg210_udc {
|
||||||
|
|
||||||
|
unsigned long irq_trigger;
|
||||||
|
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct usb_phy *phy;
|
||||||
|
struct usb_gadget gadget;
|
||||||
|
struct usb_gadget_driver *driver;
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
From 772ea3ec2b9363b45ef9a4768ea205f758c3debc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 14 Nov 2022 12:52:00 +0100
|
||||||
|
Subject: [PATCH 10/29] fotg210-udc: Handle PCLK
|
||||||
|
|
||||||
|
This adds optional handling of the peripheral clock PCLK.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221114115201.302887-3-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <linux/usb/gadget.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
#include <linux/usb/otg.h>
|
||||||
|
#include <linux/usb/phy.h>
|
||||||
|
|
||||||
|
@@ -1145,6 +1146,10 @@ int fotg210_udc_remove(struct platform_d
|
||||||
|
fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
|
||||||
|
kfree(fotg210->ep[i]);
|
||||||
|
+
|
||||||
|
+ if (!IS_ERR(fotg210->pclk))
|
||||||
|
+ clk_disable_unprepare(fotg210->pclk);
|
||||||
|
+
|
||||||
|
kfree(fotg210);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1180,17 +1185,34 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
|
||||||
|
fotg210->dev = dev;
|
||||||
|
|
||||||
|
+ /* It's OK not to supply this clock */
|
||||||
|
+ fotg210->pclk = devm_clk_get(dev, "PCLK");
|
||||||
|
+ if (!IS_ERR(fotg210->pclk)) {
|
||||||
|
+ ret = clk_prepare_enable(fotg210->pclk);
|
||||||
|
+ if (ret) {
|
||||||
|
+ dev_err(dev, "failed to enable PCLK\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
|
||||||
|
+ /*
|
||||||
|
+ * Percolate deferrals, for anything else,
|
||||||
|
+ * just live without the clocking.
|
||||||
|
+ */
|
||||||
|
+ ret = -EPROBE_DEFER;
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
|
||||||
|
if (IS_ERR(fotg210->phy)) {
|
||||||
|
ret = PTR_ERR(fotg210->phy);
|
||||||
|
if (ret == -EPROBE_DEFER)
|
||||||
|
- goto err;
|
||||||
|
+ goto err_pclk;
|
||||||
|
dev_info(dev, "no PHY found\n");
|
||||||
|
fotg210->phy = NULL;
|
||||||
|
} else {
|
||||||
|
ret = usb_phy_init(fotg210->phy);
|
||||||
|
if (ret)
|
||||||
|
- goto err;
|
||||||
|
+ goto err_pclk;
|
||||||
|
dev_info(dev, "found and initialized PHY\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1292,6 +1314,10 @@ err_map:
|
||||||
|
err_alloc:
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
|
||||||
|
kfree(fotg210->ep[i]);
|
||||||
|
+err_pclk:
|
||||||
|
+ if (!IS_ERR(fotg210->pclk))
|
||||||
|
+ clk_disable_unprepare(fotg210->pclk);
|
||||||
|
+
|
||||||
|
kfree(fotg210);
|
||||||
|
|
||||||
|
err:
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
@@ -231,6 +231,7 @@ struct fotg210_ep {
|
||||||
|
struct fotg210_udc {
|
||||||
|
spinlock_t lock; /* protect the struct */
|
||||||
|
void __iomem *reg;
|
||||||
|
+ struct clk *pclk;
|
||||||
|
|
||||||
|
unsigned long irq_trigger;
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From eda686d41e298a9d16708d2ec8d12d8e682dd7ca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 14 Nov 2022 12:52:01 +0100
|
||||||
|
Subject: [PATCH 11/29] fotg210-udc: Get IRQ using platform_get_irq()
|
||||||
|
|
||||||
|
The platform_get_irq() is necessary to use to get dynamic
|
||||||
|
IRQ resolution when instantiating the device from the
|
||||||
|
device tree. IRQs are not passed as resources in that
|
||||||
|
case.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221114115201.302887-4-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1157,10 +1157,11 @@ int fotg210_udc_remove(struct platform_d
|
||||||
|
|
||||||
|
int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
- struct resource *res, *ires;
|
||||||
|
+ struct resource *res;
|
||||||
|
struct fotg210_udc *fotg210 = NULL;
|
||||||
|
struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
+ int irq;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1170,9 +1171,9 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
|
- if (!ires) {
|
||||||
|
- pr_err("platform_get_resource IORESOURCE_IRQ error.\n");
|
||||||
|
+ irq = platform_get_irq(pdev, 0);
|
||||||
|
+ if (irq < 0) {
|
||||||
|
+ pr_err("could not get irq\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1202,7 +1203,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
|
||||||
|
+ fotg210->phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
|
||||||
|
if (IS_ERR(fotg210->phy)) {
|
||||||
|
ret = PTR_ERR(fotg210->phy);
|
||||||
|
if (ret == -EPROBE_DEFER)
|
||||||
|
@@ -1282,7 +1283,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
|
||||||
|
fotg210_disable_unplug(fotg210);
|
||||||
|
|
||||||
|
- ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
|
||||||
|
+ ret = request_irq(irq, fotg210_irq, IRQF_SHARED,
|
||||||
|
udc_name, fotg210);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "request_irq error (%d)\n", ret);
|
||||||
|
@@ -1303,7 +1304,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
err_add_udc:
|
||||||
|
if (!IS_ERR_OR_NULL(fotg210->phy))
|
||||||
|
usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
|
||||||
|
- free_irq(ires->start, fotg210);
|
||||||
|
+ free_irq(irq, fotg210);
|
||||||
|
|
||||||
|
err_req:
|
||||||
|
fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
|
@ -0,0 +1,39 @@
|
|||||||
|
From 7889a2f0256c55e0184dffd0001d0782f9e4cb83 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||||||
|
Date: Mon, 14 Nov 2022 21:38:04 +0100
|
||||||
|
Subject: [PATCH 12/29] usb: fotg210-udc: Remove a useless assignment
|
||||||
|
|
||||||
|
There is no need to use an intermediate array for these memory allocations,
|
||||||
|
so, axe it.
|
||||||
|
|
||||||
|
While at it, turn a '== NULL' into a shorter '!' when testing memory
|
||||||
|
allocation failure.
|
||||||
|
|
||||||
|
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/deab9696fc4000499470e7ccbca7c36fca17bd4e.1668458274.git.christophe.jaillet@wanadoo.fr
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1159,7 +1159,6 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
struct fotg210_udc *fotg210 = NULL;
|
||||||
|
- struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
int irq;
|
||||||
|
int ret = 0;
|
||||||
|
@@ -1218,10 +1217,9 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
|
||||||
|
- _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
|
||||||
|
- if (_ep[i] == NULL)
|
||||||
|
+ fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
|
||||||
|
+ if (!fotg210->ep[i])
|
||||||
|
goto err_alloc;
|
||||||
|
- fotg210->ep[i] = _ep[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
fotg210->reg = ioremap(res->start, resource_size(res));
|
@ -0,0 +1,58 @@
|
|||||||
|
From 7b95ade85ac18eec63e81ac58a482b3e88361ffd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yi Yang <yiyang13@huawei.com>
|
||||||
|
Date: Fri, 2 Dec 2022 09:21:26 +0800
|
||||||
|
Subject: [PATCH 13/29] usb: fotg210-udc: fix potential memory leak in
|
||||||
|
fotg210_udc_probe()
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
In fotg210_udc_probe(), if devm_clk_get() or clk_prepare_enable()
|
||||||
|
fails, 'fotg210' will not be freed, which will lead to a memory leak.
|
||||||
|
Fix it by moving kfree() to a proper location.
|
||||||
|
|
||||||
|
In addition,we can use "return -ENOMEM" instead of "goto err"
|
||||||
|
to simplify the code.
|
||||||
|
|
||||||
|
Fixes: 718a38d092ec ("fotg210-udc: Handle PCLK")
|
||||||
|
Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Signed-off-by: Yi Yang <yiyang13@huawei.com>
|
||||||
|
Link: https://lore.kernel.org/r/20221202012126.246953-1-yiyang13@huawei.com
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1176,12 +1176,10 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = -ENOMEM;
|
||||||
|
-
|
||||||
|
/* initialize udc */
|
||||||
|
fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
|
||||||
|
if (fotg210 == NULL)
|
||||||
|
- goto err;
|
||||||
|
+ return -ENOMEM;
|
||||||
|
|
||||||
|
fotg210->dev = dev;
|
||||||
|
|
||||||
|
@@ -1191,7 +1189,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
ret = clk_prepare_enable(fotg210->pclk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "failed to enable PCLK\n");
|
||||||
|
- return ret;
|
||||||
|
+ goto err;
|
||||||
|
}
|
||||||
|
} else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
|
||||||
|
/*
|
||||||
|
@@ -1317,8 +1315,7 @@ err_pclk:
|
||||||
|
if (!IS_ERR(fotg210->pclk))
|
||||||
|
clk_disable_unprepare(fotg210->pclk);
|
||||||
|
|
||||||
|
- kfree(fotg210);
|
||||||
|
-
|
||||||
|
err:
|
||||||
|
+ kfree(fotg210);
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
From d8eed400495029ba551704ff0fae1dad87332291 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Date: Thu, 15 Dec 2022 17:57:20 +0100
|
||||||
|
Subject: [PATCH 14/29] usb: fotg210: fix OTG-only build
|
||||||
|
|
||||||
|
The fotg210 module combines the HCD and OTG drivers, which then
|
||||||
|
fails to build when only the USB gadget support is enabled
|
||||||
|
in the kernel but host support is not:
|
||||||
|
|
||||||
|
aarch64-linux-ld: drivers/usb/fotg210/fotg210-core.o: in function `fotg210_init':
|
||||||
|
fotg210-core.c:(.init.text+0xc): undefined reference to `usb_disabled'
|
||||||
|
|
||||||
|
Move the check for usb_disabled() after the check for the HCD module,
|
||||||
|
and let the OTG driver still be probed in this configuration.
|
||||||
|
|
||||||
|
A nicer approach might be to have the common portion built as a
|
||||||
|
library module, with the two platform other files registering
|
||||||
|
their own platform_driver instances separately.
|
||||||
|
|
||||||
|
Fixes: ddacd6ef44ca ("usb: fotg210: Fix Kconfig for USB host modules")
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Link: https://lore.kernel.org/r/20221215165728.2062984-1-arnd@kernel.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -144,10 +144,7 @@ static struct platform_driver fotg210_dr
|
||||||
|
|
||||||
|
static int __init fotg210_init(void)
|
||||||
|
{
|
||||||
|
- if (usb_disabled())
|
||||||
|
- return -ENODEV;
|
||||||
|
-
|
||||||
|
- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
|
||||||
|
+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD) && !usb_disabled())
|
||||||
|
fotg210_hcd_init();
|
||||||
|
return platform_driver_register(&fotg210_driver);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
From eaaa85d907fe27852dd960b2bc5d7bcf11bc3ebd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yang Yingliang <yangyingliang@huawei.com>
|
||||||
|
Date: Fri, 30 Dec 2022 14:54:27 +0800
|
||||||
|
Subject: [PATCH 15/29] usb: fotg210-udc: fix error return code in
|
||||||
|
fotg210_udc_probe()
|
||||||
|
|
||||||
|
After commit 5f217ccd520f ("fotg210-udc: Support optional external PHY"),
|
||||||
|
the error code is re-assigned to 0 in fotg210_udc_probe(), if allocate or
|
||||||
|
map memory fails after the assignment, it can't return an error code. Set
|
||||||
|
the error code to -ENOMEM to fix this problem.
|
||||||
|
|
||||||
|
Fixes: 5f217ccd520f ("fotg210-udc: Support optional external PHY")
|
||||||
|
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20221230065427.944586-1-yangyingliang@huawei.com
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1214,6 +1214,8 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
dev_info(dev, "found and initialized PHY\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ret = -ENOMEM;
|
||||||
|
+
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
|
||||||
|
fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
|
||||||
|
if (!fotg210->ep[i])
|
@ -0,0 +1,25 @@
|
|||||||
|
From 407577548b2fcd41cc72ee05df1f05a430ed30a0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:16 +0100
|
||||||
|
Subject: [PATCH 16/29] usb: fotg210: List different variants
|
||||||
|
|
||||||
|
There are at least two variants of the FOTG: FOTG200 and
|
||||||
|
FOTG210. Handle them in this driver and let's add
|
||||||
|
more quirks as we go along.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-2-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -127,7 +127,9 @@ static int fotg210_remove(struct platfor
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id fotg210_of_match[] = {
|
||||||
|
+ { .compatible = "faraday,fotg200" },
|
||||||
|
{ .compatible = "faraday,fotg210" },
|
||||||
|
+ /* TODO: can we also handle FUSB220? */
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, fotg210_of_match);
|
@ -0,0 +1,245 @@
|
|||||||
|
From fa735ad1afeb5791d5562617b9bbed74574d3e81 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:17 +0100
|
||||||
|
Subject: [PATCH 17/29] usb: fotg210: Acquire memory resource in core
|
||||||
|
|
||||||
|
The subdrivers are obtaining and mapping the memory resource
|
||||||
|
separately. Create a common state container for the shared
|
||||||
|
resources and start populating this by acquiring the IO
|
||||||
|
memory resource and remap it and pass this to the subdrivers
|
||||||
|
for host and peripheral.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-3-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -33,9 +33,10 @@
|
||||||
|
#define GEMINI_MISC_USB0_MINI_B BIT(29)
|
||||||
|
#define GEMINI_MISC_USB1_MINI_B BIT(30)
|
||||||
|
|
||||||
|
-static int fotg210_gemini_init(struct device *dev, struct resource *res,
|
||||||
|
+static int fotg210_gemini_init(struct fotg210 *fotg, struct resource *res,
|
||||||
|
enum usb_dr_mode mode)
|
||||||
|
{
|
||||||
|
+ struct device *dev = fotg->dev;
|
||||||
|
struct device_node *np = dev->of_node;
|
||||||
|
struct regmap *map;
|
||||||
|
bool wakeup;
|
||||||
|
@@ -47,6 +48,7 @@ static int fotg210_gemini_init(struct de
|
||||||
|
dev_err(dev, "no syscon\n");
|
||||||
|
return PTR_ERR(map);
|
||||||
|
}
|
||||||
|
+ fotg->map = map;
|
||||||
|
wakeup = of_property_read_bool(np, "wakeup-source");
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -55,6 +57,7 @@ static int fotg210_gemini_init(struct de
|
||||||
|
*/
|
||||||
|
mask = 0;
|
||||||
|
if (res->start == 0x69000000) {
|
||||||
|
+ fotg->port = GEMINI_PORT_1;
|
||||||
|
mask = GEMINI_MISC_USB1_VBUS_ON | GEMINI_MISC_USB1_MINI_B |
|
||||||
|
GEMINI_MISC_USB1_WAKEUP;
|
||||||
|
if (mode == USB_DR_MODE_HOST)
|
||||||
|
@@ -64,6 +67,7 @@ static int fotg210_gemini_init(struct de
|
||||||
|
if (wakeup)
|
||||||
|
val |= GEMINI_MISC_USB1_WAKEUP;
|
||||||
|
} else {
|
||||||
|
+ fotg->port = GEMINI_PORT_0;
|
||||||
|
mask = GEMINI_MISC_USB0_VBUS_ON | GEMINI_MISC_USB0_MINI_B |
|
||||||
|
GEMINI_MISC_USB0_WAKEUP;
|
||||||
|
if (mode == USB_DR_MODE_HOST)
|
||||||
|
@@ -89,23 +93,34 @@ static int fotg210_probe(struct platform
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
enum usb_dr_mode mode;
|
||||||
|
+ struct fotg210 *fotg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
+ fotg = devm_kzalloc(dev, sizeof(*fotg), GFP_KERNEL);
|
||||||
|
+ if (!fotg)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ fotg->dev = dev;
|
||||||
|
+
|
||||||
|
+ fotg->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ if (!fotg->res)
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ fotg->base = devm_ioremap_resource(dev, fotg->res);
|
||||||
|
+ if (!fotg->base)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
mode = usb_get_dr_mode(dev);
|
||||||
|
|
||||||
|
if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
|
||||||
|
- struct resource *res;
|
||||||
|
-
|
||||||
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
- ret = fotg210_gemini_init(dev, res, mode);
|
||||||
|
+ ret = fotg210_gemini_init(fotg, fotg->res, mode);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == USB_DR_MODE_PERIPHERAL)
|
||||||
|
- ret = fotg210_udc_probe(pdev);
|
||||||
|
+ ret = fotg210_udc_probe(pdev, fotg);
|
||||||
|
else
|
||||||
|
- ret = fotg210_hcd_probe(pdev);
|
||||||
|
+ ret = fotg210_hcd_probe(pdev, fotg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
@@ -5557,11 +5557,10 @@ static void fotg210_init(struct fotg210_
|
||||||
|
* then invokes the start() method for the HCD associated with it
|
||||||
|
* through the hotplug entry's driver_data.
|
||||||
|
*/
|
||||||
|
-int fotg210_hcd_probe(struct platform_device *pdev)
|
||||||
|
+int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct usb_hcd *hcd;
|
||||||
|
- struct resource *res;
|
||||||
|
int irq;
|
||||||
|
int retval;
|
||||||
|
struct fotg210_hcd *fotg210;
|
||||||
|
@@ -5585,18 +5584,14 @@ int fotg210_hcd_probe(struct platform_de
|
||||||
|
|
||||||
|
hcd->has_tt = 1;
|
||||||
|
|
||||||
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
- hcd->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
- if (IS_ERR(hcd->regs)) {
|
||||||
|
- retval = PTR_ERR(hcd->regs);
|
||||||
|
- goto failed_put_hcd;
|
||||||
|
- }
|
||||||
|
+ hcd->regs = fotg->base;
|
||||||
|
|
||||||
|
- hcd->rsrc_start = res->start;
|
||||||
|
- hcd->rsrc_len = resource_size(res);
|
||||||
|
+ hcd->rsrc_start = fotg->res->start;
|
||||||
|
+ hcd->rsrc_len = resource_size(fotg->res);
|
||||||
|
|
||||||
|
fotg210 = hcd_to_fotg210(hcd);
|
||||||
|
|
||||||
|
+ fotg210->fotg = fotg;
|
||||||
|
fotg210->caps = hcd->regs;
|
||||||
|
|
||||||
|
/* It's OK not to supply this clock */
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-hcd.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-hcd.h
|
||||||
|
@@ -182,6 +182,7 @@ struct fotg210_hcd { /* one per contro
|
||||||
|
# define INCR(x) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ struct fotg210 *fotg; /* Overarching FOTG210 device */
|
||||||
|
/* silicon clock */
|
||||||
|
struct clk *pclk;
|
||||||
|
};
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1155,21 +1155,14 @@ int fotg210_udc_remove(struct platform_d
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
+int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg)
|
||||||
|
{
|
||||||
|
- struct resource *res;
|
||||||
|
struct fotg210_udc *fotg210 = NULL;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
int irq;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
- if (!res) {
|
||||||
|
- pr_err("platform_get_resource error.\n");
|
||||||
|
- return -ENODEV;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
irq = platform_get_irq(pdev, 0);
|
||||||
|
if (irq < 0) {
|
||||||
|
pr_err("could not get irq\n");
|
||||||
|
@@ -1182,6 +1175,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
fotg210->dev = dev;
|
||||||
|
+ fotg210->fotg = fotg;
|
||||||
|
|
||||||
|
/* It's OK not to supply this clock */
|
||||||
|
fotg210->pclk = devm_clk_get(dev, "PCLK");
|
||||||
|
@@ -1222,11 +1216,7 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
goto err_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
- fotg210->reg = ioremap(res->start, resource_size(res));
|
||||||
|
- if (fotg210->reg == NULL) {
|
||||||
|
- dev_err(dev, "ioremap error\n");
|
||||||
|
- goto err_alloc;
|
||||||
|
- }
|
||||||
|
+ fotg210->reg = fotg->base;
|
||||||
|
|
||||||
|
spin_lock_init(&fotg210->lock);
|
||||||
|
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
@@ -236,6 +236,7 @@ struct fotg210_udc {
|
||||||
|
unsigned long irq_trigger;
|
||||||
|
|
||||||
|
struct device *dev;
|
||||||
|
+ struct fotg210 *fotg;
|
||||||
|
struct usb_phy *phy;
|
||||||
|
struct usb_gadget gadget;
|
||||||
|
struct usb_gadget_driver *driver;
|
||||||
|
--- a/drivers/usb/fotg210/fotg210.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210.h
|
||||||
|
@@ -2,13 +2,28 @@
|
||||||
|
#ifndef __FOTG210_H
|
||||||
|
#define __FOTG210_H
|
||||||
|
|
||||||
|
+enum gemini_port {
|
||||||
|
+ GEMINI_PORT_NONE = 0,
|
||||||
|
+ GEMINI_PORT_0,
|
||||||
|
+ GEMINI_PORT_1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct fotg210 {
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct resource *res;
|
||||||
|
+ void __iomem *base;
|
||||||
|
+ struct regmap *map;
|
||||||
|
+ enum gemini_port port;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_USB_FOTG210_HCD
|
||||||
|
-int fotg210_hcd_probe(struct platform_device *pdev);
|
||||||
|
+int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg);
|
||||||
|
int fotg210_hcd_remove(struct platform_device *pdev);
|
||||||
|
int fotg210_hcd_init(void);
|
||||||
|
void fotg210_hcd_cleanup(void);
|
||||||
|
#else
|
||||||
|
-static inline int fotg210_hcd_probe(struct platform_device *pdev)
|
||||||
|
+static inline int fotg210_hcd_probe(struct platform_device *pdev,
|
||||||
|
+ struct fotg210 *fotg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -26,10 +41,11 @@ static inline void fotg210_hcd_cleanup(v
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_FOTG210_UDC
|
||||||
|
-int fotg210_udc_probe(struct platform_device *pdev);
|
||||||
|
+int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg);
|
||||||
|
int fotg210_udc_remove(struct platform_device *pdev);
|
||||||
|
#else
|
||||||
|
-static inline int fotg210_udc_probe(struct platform_device *pdev)
|
||||||
|
+static inline int fotg210_udc_probe(struct platform_device *pdev,
|
||||||
|
+ struct fotg210 *fotg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,196 @@
|
|||||||
|
From fb8e1e8dbc47e7aff7624b47adaa0a84d2983802 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:18 +0100
|
||||||
|
Subject: [PATCH 18/29] usb: fotg210: Move clock handling to core
|
||||||
|
|
||||||
|
Grab the optional silicon block clock, prepare and enable it in
|
||||||
|
the core before proceeding to prepare the host or peripheral
|
||||||
|
driver. This saves duplicate code and also uses the simple
|
||||||
|
devm_clk_get_optional_enabled() to do everything we really
|
||||||
|
want to do.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-4-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
* driver.
|
||||||
|
*/
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
@@ -109,6 +110,10 @@ static int fotg210_probe(struct platform
|
||||||
|
if (!fotg->base)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
+ fotg->pclk = devm_clk_get_optional_enabled(dev, "PCLK");
|
||||||
|
+ if (IS_ERR(fotg->pclk))
|
||||||
|
+ return PTR_ERR(fotg->pclk);
|
||||||
|
+
|
||||||
|
mode = usb_get_dr_mode(dev);
|
||||||
|
|
||||||
|
if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
@@ -33,7 +33,6 @@
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
-#include <linux/clk.h>
|
||||||
|
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
@@ -5594,44 +5593,22 @@ int fotg210_hcd_probe(struct platform_de
|
||||||
|
fotg210->fotg = fotg;
|
||||||
|
fotg210->caps = hcd->regs;
|
||||||
|
|
||||||
|
- /* It's OK not to supply this clock */
|
||||||
|
- fotg210->pclk = clk_get(dev, "PCLK");
|
||||||
|
- if (!IS_ERR(fotg210->pclk)) {
|
||||||
|
- retval = clk_prepare_enable(fotg210->pclk);
|
||||||
|
- if (retval) {
|
||||||
|
- dev_err(dev, "failed to enable PCLK\n");
|
||||||
|
- goto failed_put_hcd;
|
||||||
|
- }
|
||||||
|
- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
|
||||||
|
- /*
|
||||||
|
- * Percolate deferrals, for anything else,
|
||||||
|
- * just live without the clocking.
|
||||||
|
- */
|
||||||
|
- retval = PTR_ERR(fotg210->pclk);
|
||||||
|
- goto failed_dis_clk;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
retval = fotg210_setup(hcd);
|
||||||
|
if (retval)
|
||||||
|
- goto failed_dis_clk;
|
||||||
|
+ goto failed_put_hcd;
|
||||||
|
|
||||||
|
fotg210_init(fotg210);
|
||||||
|
|
||||||
|
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||||
|
if (retval) {
|
||||||
|
dev_err(dev, "failed to add hcd with err %d\n", retval);
|
||||||
|
- goto failed_dis_clk;
|
||||||
|
+ goto failed_put_hcd;
|
||||||
|
}
|
||||||
|
device_wakeup_enable(hcd->self.controller);
|
||||||
|
platform_set_drvdata(pdev, hcd);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
-failed_dis_clk:
|
||||||
|
- if (!IS_ERR(fotg210->pclk)) {
|
||||||
|
- clk_disable_unprepare(fotg210->pclk);
|
||||||
|
- clk_put(fotg210->pclk);
|
||||||
|
- }
|
||||||
|
failed_put_hcd:
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
fail_create_hcd:
|
||||||
|
@@ -5647,12 +5624,6 @@ fail_create_hcd:
|
||||||
|
int fotg210_hcd_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
|
||||||
|
-
|
||||||
|
- if (!IS_ERR(fotg210->pclk)) {
|
||||||
|
- clk_disable_unprepare(fotg210->pclk);
|
||||||
|
- clk_put(fotg210->pclk);
|
||||||
|
- }
|
||||||
|
|
||||||
|
usb_remove_hcd(hcd);
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -15,7 +15,6 @@
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <linux/usb/gadget.h>
|
||||||
|
-#include <linux/clk.h>
|
||||||
|
#include <linux/usb/otg.h>
|
||||||
|
#include <linux/usb/phy.h>
|
||||||
|
|
||||||
|
@@ -1147,9 +1146,6 @@ int fotg210_udc_remove(struct platform_d
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
|
||||||
|
kfree(fotg210->ep[i]);
|
||||||
|
|
||||||
|
- if (!IS_ERR(fotg210->pclk))
|
||||||
|
- clk_disable_unprepare(fotg210->pclk);
|
||||||
|
-
|
||||||
|
kfree(fotg210);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1177,34 +1173,17 @@ int fotg210_udc_probe(struct platform_de
|
||||||
|
fotg210->dev = dev;
|
||||||
|
fotg210->fotg = fotg;
|
||||||
|
|
||||||
|
- /* It's OK not to supply this clock */
|
||||||
|
- fotg210->pclk = devm_clk_get(dev, "PCLK");
|
||||||
|
- if (!IS_ERR(fotg210->pclk)) {
|
||||||
|
- ret = clk_prepare_enable(fotg210->pclk);
|
||||||
|
- if (ret) {
|
||||||
|
- dev_err(dev, "failed to enable PCLK\n");
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
|
||||||
|
- /*
|
||||||
|
- * Percolate deferrals, for anything else,
|
||||||
|
- * just live without the clocking.
|
||||||
|
- */
|
||||||
|
- ret = -EPROBE_DEFER;
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
fotg210->phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
|
||||||
|
if (IS_ERR(fotg210->phy)) {
|
||||||
|
ret = PTR_ERR(fotg210->phy);
|
||||||
|
if (ret == -EPROBE_DEFER)
|
||||||
|
- goto err_pclk;
|
||||||
|
+ goto err_free;
|
||||||
|
dev_info(dev, "no PHY found\n");
|
||||||
|
fotg210->phy = NULL;
|
||||||
|
} else {
|
||||||
|
ret = usb_phy_init(fotg210->phy);
|
||||||
|
if (ret)
|
||||||
|
- goto err_pclk;
|
||||||
|
+ goto err_free;
|
||||||
|
dev_info(dev, "found and initialized PHY\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1303,11 +1282,8 @@ err_map:
|
||||||
|
err_alloc:
|
||||||
|
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
|
||||||
|
kfree(fotg210->ep[i]);
|
||||||
|
-err_pclk:
|
||||||
|
- if (!IS_ERR(fotg210->pclk))
|
||||||
|
- clk_disable_unprepare(fotg210->pclk);
|
||||||
|
|
||||||
|
-err:
|
||||||
|
+err_free:
|
||||||
|
kfree(fotg210);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
@@ -231,7 +231,6 @@ struct fotg210_ep {
|
||||||
|
struct fotg210_udc {
|
||||||
|
spinlock_t lock; /* protect the struct */
|
||||||
|
void __iomem *reg;
|
||||||
|
- struct clk *pclk;
|
||||||
|
|
||||||
|
unsigned long irq_trigger;
|
||||||
|
|
||||||
|
--- a/drivers/usb/fotg210/fotg210.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210.h
|
||||||
|
@@ -12,6 +12,7 @@ struct fotg210 {
|
||||||
|
struct device *dev;
|
||||||
|
struct resource *res;
|
||||||
|
void __iomem *base;
|
||||||
|
+ struct clk *pclk;
|
||||||
|
struct regmap *map;
|
||||||
|
enum gemini_port port;
|
||||||
|
};
|
@ -0,0 +1,54 @@
|
|||||||
|
From b1b07abb598211de3ce7f52abdf8dcb24384341e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:19 +0100
|
||||||
|
Subject: [PATCH 19/29] usb: fotg210: Check role register in core
|
||||||
|
|
||||||
|
Read the role register and check that we are in host/peripheral
|
||||||
|
mode and issue warnings if we're not in the right role when
|
||||||
|
probing respective driver.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-5-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -18,6 +18,11 @@
|
||||||
|
|
||||||
|
#include "fotg210.h"
|
||||||
|
|
||||||
|
+/* Role Register 0x80 */
|
||||||
|
+#define FOTG210_RR 0x80
|
||||||
|
+#define FOTG210_RR_ID BIT(21) /* 1 = B-device, 0 = A-device */
|
||||||
|
+#define FOTG210_RR_CROLE BIT(20) /* 1 = device, 0 = host */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Gemini-specific initialization function, only executed on the
|
||||||
|
* Gemini SoC using the global misc control register.
|
||||||
|
@@ -95,6 +100,7 @@ static int fotg210_probe(struct platform
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
enum usb_dr_mode mode;
|
||||||
|
struct fotg210 *fotg;
|
||||||
|
+ u32 val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fotg = devm_kzalloc(dev, sizeof(*fotg), GFP_KERNEL);
|
||||||
|
@@ -122,10 +128,16 @@ static int fotg210_probe(struct platform
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (mode == USB_DR_MODE_PERIPHERAL)
|
||||||
|
+ val = readl(fotg->base + FOTG210_RR);
|
||||||
|
+ if (mode == USB_DR_MODE_PERIPHERAL) {
|
||||||
|
+ if (!(val & FOTG210_RR_CROLE))
|
||||||
|
+ dev_err(dev, "block not in device role\n");
|
||||||
|
ret = fotg210_udc_probe(pdev, fotg);
|
||||||
|
- else
|
||||||
|
+ } else {
|
||||||
|
+ if (val & FOTG210_RR_CROLE)
|
||||||
|
+ dev_err(dev, "block not in host role\n");
|
||||||
|
ret = fotg210_hcd_probe(pdev, fotg);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
From d7c2b0b6da75b86cf5ddbcd51a74d74e19bbf178 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:20 +0100
|
||||||
|
Subject: [PATCH 20/29] usb: fotg210-udc: Assign of_node and speed on start
|
||||||
|
|
||||||
|
Follow the example set by other drivers to assign of_node
|
||||||
|
and speed to the driver when binding, also print bound
|
||||||
|
info akin to other UDC drivers.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-6-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1028,6 +1028,10 @@ static int fotg210_udc_start(struct usb_
|
||||||
|
|
||||||
|
/* hook up the driver */
|
||||||
|
fotg210->driver = driver;
|
||||||
|
+ fotg210->gadget.dev.of_node = fotg210->dev->of_node;
|
||||||
|
+ fotg210->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
|
+
|
||||||
|
+ dev_info(fotg210->dev, "bound driver %s\n", driver->driver.name);
|
||||||
|
|
||||||
|
if (!IS_ERR_OR_NULL(fotg210->phy)) {
|
||||||
|
ret = otg_set_peripheral(fotg210->phy->otg,
|
||||||
|
@@ -1084,6 +1088,7 @@ static int fotg210_udc_stop(struct usb_g
|
||||||
|
|
||||||
|
fotg210_init(fotg210);
|
||||||
|
fotg210->driver = NULL;
|
||||||
|
+ fotg210->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fotg210->lock, flags);
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From 2fbbfb2c556944945639b17b13fcb1e05272b646 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Wed, 18 Jan 2023 08:09:21 +0100
|
||||||
|
Subject: [PATCH 21/29] usb: fotg210-udc: Implement VBUS session
|
||||||
|
|
||||||
|
Implement VBUS session handling for FOTG210. This is
|
||||||
|
mainly used by the UDC driver which needs to call down to
|
||||||
|
the FOTG210 core and enable/disable VBUS, as this needs to be
|
||||||
|
handled outside of the HCD and UDC drivers, by platform
|
||||||
|
specific glue code.
|
||||||
|
|
||||||
|
The Gemini has a special bit in a system register to turn
|
||||||
|
VBUS on and off so we implement this in the FOTG210 core.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-7-100388af9810@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-core.c
|
||||||
|
@@ -95,6 +95,35 @@ static int fotg210_gemini_init(struct fo
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * fotg210_vbus() - Called by gadget driver to enable/disable VBUS
|
||||||
|
+ * @enable: true to enable VBUS, false to disable VBUS
|
||||||
|
+ */
|
||||||
|
+void fotg210_vbus(struct fotg210 *fotg, bool enable)
|
||||||
|
+{
|
||||||
|
+ u32 mask;
|
||||||
|
+ u32 val;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ switch (fotg->port) {
|
||||||
|
+ case GEMINI_PORT_0:
|
||||||
|
+ mask = GEMINI_MISC_USB0_VBUS_ON;
|
||||||
|
+ val = enable ? GEMINI_MISC_USB0_VBUS_ON : 0;
|
||||||
|
+ break;
|
||||||
|
+ case GEMINI_PORT_1:
|
||||||
|
+ mask = GEMINI_MISC_USB1_VBUS_ON;
|
||||||
|
+ val = enable ? GEMINI_MISC_USB1_VBUS_ON : 0;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ ret = regmap_update_bits(fotg->map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
|
||||||
|
+ if (ret)
|
||||||
|
+ dev_err(fotg->dev, "failed to %s VBUS\n",
|
||||||
|
+ enable ? "enable" : "disable");
|
||||||
|
+ dev_info(fotg->dev, "%s: %s VBUS\n", __func__, enable ? "enable" : "disable");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int fotg210_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -1095,9 +1095,26 @@ static int fotg210_udc_stop(struct usb_g
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * fotg210_vbus_session - Called by external transceiver to enable/disable udc
|
||||||
|
+ * @_gadget: usb gadget
|
||||||
|
+ * @is_active: 0 if should disable UDC VBUS, 1 if should enable
|
||||||
|
+ *
|
||||||
|
+ * Returns 0
|
||||||
|
+ */
|
||||||
|
+static int fotg210_vbus_session(struct usb_gadget *g, int is_active)
|
||||||
|
+{
|
||||||
|
+ struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
|
||||||
|
+
|
||||||
|
+ /* Call down to core integration layer to drive or disable VBUS */
|
||||||
|
+ fotg210_vbus(fotg210->fotg, is_active);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct usb_gadget_ops fotg210_gadget_ops = {
|
||||||
|
.udc_start = fotg210_udc_start,
|
||||||
|
.udc_stop = fotg210_udc_stop,
|
||||||
|
+ .vbus_session = fotg210_vbus_session,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
--- a/drivers/usb/fotg210/fotg210.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210.h
|
||||||
|
@@ -17,6 +17,8 @@ struct fotg210 {
|
||||||
|
enum gemini_port port;
|
||||||
|
};
|
||||||
|
|
||||||
|
+void fotg210_vbus(struct fotg210 *fotg, bool enable);
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_USB_FOTG210_HCD
|
||||||
|
int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg);
|
||||||
|
int fotg210_hcd_remove(struct platform_device *pdev);
|
@ -0,0 +1,134 @@
|
|||||||
|
From f011d1eab23f4c063c5441c0d5a22898adf9145c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Date: Mon, 23 Jan 2023 08:35:07 +0100
|
||||||
|
Subject: [PATCH 22/29] fotg210-udc: Introduce and use a fotg210_ack_int
|
||||||
|
function
|
||||||
|
|
||||||
|
This is in preparation of support for devices where interrupts are acked
|
||||||
|
differently.
|
||||||
|
|
||||||
|
Signed-off-by: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230123073508.2350402-3-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -28,6 +28,14 @@ static const char udc_name[] = "fotg210_
|
||||||
|
static const char * const fotg210_ep_name[] = {
|
||||||
|
"ep0", "ep1", "ep2", "ep3", "ep4"};
|
||||||
|
|
||||||
|
+static void fotg210_ack_int(struct fotg210_udc *fotg210, u32 offset, u32 mask)
|
||||||
|
+{
|
||||||
|
+ u32 value = ioread32(fotg210->reg + offset);
|
||||||
|
+
|
||||||
|
+ value &= ~mask;
|
||||||
|
+ iowrite32(value, fotg210->reg + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void fotg210_disable_fifo_int(struct fotg210_ep *ep)
|
||||||
|
{
|
||||||
|
u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
|
||||||
|
@@ -303,8 +311,7 @@ static void fotg210_wait_dma_done(struct
|
||||||
|
goto dma_reset;
|
||||||
|
} while (!(value & DISGR2_DMA_CMPLT));
|
||||||
|
|
||||||
|
- value &= ~DISGR2_DMA_CMPLT;
|
||||||
|
- iowrite32(value, ep->fotg210->reg + FOTG210_DISGR2);
|
||||||
|
+ fotg210_ack_int(ep->fotg210, FOTG210_DISGR2, DISGR2_DMA_CMPLT);
|
||||||
|
return;
|
||||||
|
|
||||||
|
dma_reset:
|
||||||
|
@@ -844,14 +851,6 @@ static void fotg210_ep0in(struct fotg210
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void fotg210_clear_comabt_int(struct fotg210_udc *fotg210)
|
||||||
|
-{
|
||||||
|
- u32 value = ioread32(fotg210->reg + FOTG210_DISGR0);
|
||||||
|
-
|
||||||
|
- value &= ~DISGR0_CX_COMABT_INT;
|
||||||
|
- iowrite32(value, fotg210->reg + FOTG210_DISGR0);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void fotg210_in_fifo_handler(struct fotg210_ep *ep)
|
||||||
|
{
|
||||||
|
struct fotg210_request *req = list_entry(ep->queue.next,
|
||||||
|
@@ -893,60 +892,43 @@ static irqreturn_t fotg210_irq(int irq,
|
||||||
|
void __iomem *reg = fotg210->reg + FOTG210_DISGR2;
|
||||||
|
u32 int_grp2 = ioread32(reg);
|
||||||
|
u32 int_msk2 = ioread32(fotg210->reg + FOTG210_DMISGR2);
|
||||||
|
- u32 value;
|
||||||
|
|
||||||
|
int_grp2 &= ~int_msk2;
|
||||||
|
|
||||||
|
if (int_grp2 & DISGR2_USBRST_INT) {
|
||||||
|
usb_gadget_udc_reset(&fotg210->gadget,
|
||||||
|
fotg210->driver);
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_USBRST_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_USBRST_INT);
|
||||||
|
pr_info("fotg210 udc reset\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_SUSP_INT) {
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_SUSP_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_SUSP_INT);
|
||||||
|
pr_info("fotg210 udc suspend\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_RESM_INT) {
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_RESM_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_RESM_INT);
|
||||||
|
pr_info("fotg210 udc resume\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_ISO_SEQ_ERR_INT) {
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_ISO_SEQ_ERR_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_ISO_SEQ_ERR_INT);
|
||||||
|
pr_info("fotg210 iso sequence error\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_ISO_SEQ_ABORT_INT) {
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_ISO_SEQ_ABORT_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_ISO_SEQ_ABORT_INT);
|
||||||
|
pr_info("fotg210 iso sequence abort\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_TX0BYTE_INT) {
|
||||||
|
fotg210_clear_tx0byte(fotg210);
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_TX0BYTE_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_TX0BYTE_INT);
|
||||||
|
pr_info("fotg210 transferred 0 byte\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_RX0BYTE_INT) {
|
||||||
|
fotg210_clear_rx0byte(fotg210);
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_RX0BYTE_INT;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_RX0BYTE_INT);
|
||||||
|
pr_info("fotg210 received 0 byte\n");
|
||||||
|
}
|
||||||
|
if (int_grp2 & DISGR2_DMA_ERROR) {
|
||||||
|
- value = ioread32(reg);
|
||||||
|
- value &= ~DISGR2_DMA_ERROR;
|
||||||
|
- iowrite32(value, reg);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_DMA_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -960,7 +942,7 @@ static irqreturn_t fotg210_irq(int irq,
|
||||||
|
|
||||||
|
/* the highest priority in this source register */
|
||||||
|
if (int_grp0 & DISGR0_CX_COMABT_INT) {
|
||||||
|
- fotg210_clear_comabt_int(fotg210);
|
||||||
|
+ fotg210_ack_int(fotg210, FOTG210_DISGR0, DISGR0_CX_COMABT_INT);
|
||||||
|
pr_info("fotg210 CX command abort\n");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
From 367747c7813cecf19b46ef7134691f903ab76dc9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Date: Mon, 23 Jan 2023 08:35:08 +0100
|
||||||
|
Subject: [PATCH 23/29] fotg210-udc: Improve device initialization
|
||||||
|
|
||||||
|
Reset the device explicitly to get into a known state and also set the chip
|
||||||
|
enable bit. Additionally, mask interrupts which aren't handled.
|
||||||
|
|
||||||
|
Signed-off-by: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230123073508.2350402-4-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.c
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
* Author : Yuan-Hsin Chen <yhchen@faraday-tech.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include <linux/delay.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
@@ -1022,6 +1023,11 @@ static int fotg210_udc_start(struct usb_
|
||||||
|
dev_err(fotg210->dev, "can't bind to phy\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* chip enable */
|
||||||
|
+ value = ioread32(fotg210->reg + FOTG210_DMCR);
|
||||||
|
+ value |= DMCR_CHIP_EN;
|
||||||
|
+ iowrite32(value, fotg210->reg + FOTG210_DMCR);
|
||||||
|
+
|
||||||
|
/* enable device global interrupt */
|
||||||
|
value = ioread32(fotg210->reg + FOTG210_DMCR);
|
||||||
|
value |= DMCR_GLINT_EN;
|
||||||
|
@@ -1038,6 +1044,15 @@ static void fotg210_init(struct fotg210_
|
||||||
|
iowrite32(GMIR_MHC_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
|
||||||
|
fotg210->reg + FOTG210_GMIR);
|
||||||
|
|
||||||
|
+ /* mask interrupts for groups other than 0-2 */
|
||||||
|
+ iowrite32(~(DMIGR_MINT_G0 | DMIGR_MINT_G1 | DMIGR_MINT_G2),
|
||||||
|
+ fotg210->reg + FOTG210_DMIGR);
|
||||||
|
+
|
||||||
|
+ /* udc software reset */
|
||||||
|
+ iowrite32(DMCR_SFRST, fotg210->reg + FOTG210_DMCR);
|
||||||
|
+ /* Better wait a bit, but without a datasheet, no idea how long. */
|
||||||
|
+ usleep_range(100, 200);
|
||||||
|
+
|
||||||
|
/* disable device global interrupt */
|
||||||
|
value = ioread32(fotg210->reg + FOTG210_DMCR);
|
||||||
|
value &= ~DMCR_GLINT_EN;
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-udc.h
|
||||||
|
@@ -58,6 +58,8 @@
|
||||||
|
|
||||||
|
/* Device Mask of Interrupt Group Register (0x130) */
|
||||||
|
#define FOTG210_DMIGR 0x130
|
||||||
|
+#define DMIGR_MINT_G2 (1 << 2)
|
||||||
|
+#define DMIGR_MINT_G1 (1 << 1)
|
||||||
|
#define DMIGR_MINT_G0 (1 << 0)
|
||||||
|
|
||||||
|
/* Device Mask of Interrupt Source Group 0(0x134) */
|
@ -0,0 +1,32 @@
|
|||||||
|
From 482830a70408a5d30af264b3d6706f818c78b2b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||||
|
Date: Fri, 20 Jan 2023 17:44:33 +0200
|
||||||
|
Subject: [PATCH 24/29] usb: fotg210-hcd: use sysfs_emit() to instead of
|
||||||
|
scnprintf()
|
||||||
|
|
||||||
|
Follow the advice of the Documentation/filesystems/sysfs.rst and show()
|
||||||
|
should only use sysfs_emit() or sysfs_emit_at() when formatting the
|
||||||
|
value to be returned to user space.
|
||||||
|
|
||||||
|
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||||
|
Link: https://lore.kernel.org/r/20230120154437.22025-1-andriy.shevchenko@linux.intel.com
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
--- a/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
+++ b/drivers/usb/fotg210/fotg210-hcd.c
|
||||||
|
@@ -4686,14 +4686,11 @@ static ssize_t uframe_periodic_max_show(
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct fotg210_hcd *fotg210;
|
||||||
|
- int n;
|
||||||
|
|
||||||
|
fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
|
||||||
|
- n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
|
||||||
|
- return n;
|
||||||
|
+ return sysfs_emit(buf, "%d\n", fotg210->uframe_periodic_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
static ssize_t uframe_periodic_max_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
@ -0,0 +1,62 @@
|
|||||||
|
From 6b84aa39a063eec883d410a9893cec70fce56163 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Sun, 4 Dec 2022 20:02:28 +0100
|
||||||
|
Subject: [PATCH 25/29] ARM: dts: gemini: Push down flash address/size cells
|
||||||
|
|
||||||
|
The platforms not defining any OF partions complain like
|
||||||
|
this:
|
||||||
|
|
||||||
|
../arch/arm/boot/dts/gemini.dtsi:19.25-28.5: Warning
|
||||||
|
(avoid_unnecessary_addr_size): /soc/flash@30000000: unnecessary
|
||||||
|
#address-cells/#size-cells without "ranges" or child "reg" property
|
||||||
|
|
||||||
|
Get rid of this by only defining the address-cells and
|
||||||
|
size-cells where it is actually used by OF partitions.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/r/20221204190230.3345590-1-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
|
||||||
|
@@ -164,6 +164,8 @@
|
||||||
|
compatible = "cortina,gemini-flash", "jedec-flash";
|
||||||
|
status = "okay";
|
||||||
|
reg = <0x30000000 0x00080000>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This "RedBoot" is the Storlink derivative.
|
||||||
|
--- a/arch/arm/boot/dts/gemini-wbd111.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-wbd111.dts
|
||||||
|
@@ -86,6 +86,8 @@
|
||||||
|
status = "okay";
|
||||||
|
/* 8MB of flash */
|
||||||
|
reg = <0x30000000 0x00800000>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "RedBoot";
|
||||||
|
--- a/arch/arm/boot/dts/gemini-wbd222.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-wbd222.dts
|
||||||
|
@@ -90,6 +90,8 @@
|
||||||
|
status = "okay";
|
||||||
|
/* 8MB of flash */
|
||||||
|
reg = <0x30000000 0x00800000>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "RedBoot";
|
||||||
|
--- a/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
@@ -22,8 +22,6 @@
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pflash_default_pins>;
|
||||||
|
bank-width = <2>;
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <1>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
From 0e733f5af628210f372585e431504a7024e7b571 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Sun, 4 Dec 2022 20:02:29 +0100
|
||||||
|
Subject: [PATCH 26/29] ARM: dts: gemini: wbd111: Use RedBoot partion parser
|
||||||
|
|
||||||
|
This is clearly a RedBoot partitioned device with 0x20000
|
||||||
|
sized erase blocks.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/r/20221204190230.3345590-2-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini-wbd111.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-wbd111.dts
|
||||||
|
@@ -86,36 +86,11 @@
|
||||||
|
status = "okay";
|
||||||
|
/* 8MB of flash */
|
||||||
|
reg = <0x30000000 0x00800000>;
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <1>;
|
||||||
|
|
||||||
|
- partition@0 {
|
||||||
|
- label = "RedBoot";
|
||||||
|
- reg = <0x00000000 0x00020000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@20000 {
|
||||||
|
- label = "kernel";
|
||||||
|
- reg = <0x00020000 0x00100000>;
|
||||||
|
- };
|
||||||
|
- partition@120000 {
|
||||||
|
- label = "rootfs";
|
||||||
|
- reg = <0x00120000 0x006a0000>;
|
||||||
|
- };
|
||||||
|
- partition@7c0000 {
|
||||||
|
- label = "VCTL";
|
||||||
|
- reg = <0x007c0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@7d0000 {
|
||||||
|
- label = "cfg";
|
||||||
|
- reg = <0x007d0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@7e0000 {
|
||||||
|
- label = "FIS";
|
||||||
|
- reg = <0x007e0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
+ partitions {
|
||||||
|
+ compatible = "redboot-fis";
|
||||||
|
+ /* Eraseblock at 0x7e0000 */
|
||||||
|
+ fis-index-block = <0x3f>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
From 8558e2e1110a5daa4ac9e1c5b5c15e1651a8fb94 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Sun, 4 Dec 2022 20:02:30 +0100
|
||||||
|
Subject: [PATCH 27/29] ARM: dts: gemini: wbd222: Use RedBoot partion parser
|
||||||
|
|
||||||
|
This is clearly a RedBoot partitioned device with 0x20000
|
||||||
|
sized erase blocks.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/r/20221204190230.3345590-3-linus.walleij@linaro.org
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini-wbd222.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-wbd222.dts
|
||||||
|
@@ -90,36 +90,11 @@
|
||||||
|
status = "okay";
|
||||||
|
/* 8MB of flash */
|
||||||
|
reg = <0x30000000 0x00800000>;
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <1>;
|
||||||
|
|
||||||
|
- partition@0 {
|
||||||
|
- label = "RedBoot";
|
||||||
|
- reg = <0x00000000 0x00020000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@20000 {
|
||||||
|
- label = "kernel";
|
||||||
|
- reg = <0x00020000 0x00100000>;
|
||||||
|
- };
|
||||||
|
- partition@120000 {
|
||||||
|
- label = "rootfs";
|
||||||
|
- reg = <0x00120000 0x006a0000>;
|
||||||
|
- };
|
||||||
|
- partition@7c0000 {
|
||||||
|
- label = "VCTL";
|
||||||
|
- reg = <0x007c0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@7d0000 {
|
||||||
|
- label = "cfg";
|
||||||
|
- reg = <0x007d0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
- };
|
||||||
|
- partition@7e0000 {
|
||||||
|
- label = "FIS";
|
||||||
|
- reg = <0x007e0000 0x00010000>;
|
||||||
|
- read-only;
|
||||||
|
+ partitions {
|
||||||
|
+ compatible = "redboot-fis";
|
||||||
|
+ /* Eraseblock at 0x7e0000 */
|
||||||
|
+ fis-index-block = <0x3f>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From d5c01ce4a1016507c69682894cf6b66301abca3d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 23 Jan 2023 08:39:15 +0100
|
||||||
|
Subject: [PATCH 28/29] ARM: dts: gemini: Fix USB block version
|
||||||
|
|
||||||
|
The FOTG version in the Gemini is the FOTG200, fix this
|
||||||
|
up.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230123073916.2350839-1-linus.walleij@linaro.org
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
@@ -439,7 +439,7 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
usb0: usb@68000000 {
|
||||||
|
- compatible = "cortina,gemini-usb", "faraday,fotg210";
|
||||||
|
+ compatible = "cortina,gemini-usb", "faraday,fotg200";
|
||||||
|
reg = <0x68000000 0x1000>;
|
||||||
|
interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
resets = <&syscon GEMINI_RESET_USB0>;
|
||||||
|
@@ -460,7 +460,7 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
usb1: usb@69000000 {
|
||||||
|
- compatible = "cortina,gemini-usb", "faraday,fotg210";
|
||||||
|
+ compatible = "cortina,gemini-usb", "faraday,fotg200";
|
||||||
|
reg = <0x69000000 0x1000>;
|
||||||
|
interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
resets = <&syscon GEMINI_RESET_USB1>;
|
@ -0,0 +1,54 @@
|
|||||||
|
From 296184694ae7a4e388603c95499e98d30b21cc09 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 23 Jan 2023 08:39:16 +0100
|
||||||
|
Subject: [PATCH 29/29] ARM: dts: gemini: Enable DNS313 FOTG210 as periph
|
||||||
|
|
||||||
|
Add the GPIO-based VBUS phy, and enable the FOTG210
|
||||||
|
USB1 block for use as peripheral.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230123073916.2350839-2-linus.walleij@linaro.org
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
|
||||||
|
@@ -80,6 +80,15 @@
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * This is the type B USB connector on the device,
|
||||||
|
+ * a GPIO-controlled USB VBUS detect
|
||||||
|
+ */
|
||||||
|
+ usb1_phy: phy {
|
||||||
|
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
|
||||||
|
+ #phy-cells = <0>;
|
||||||
|
+ vbus-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
|
||||||
|
+ };
|
||||||
|
|
||||||
|
/* Global Mixed-Mode Technology G751 mounted on GPIO I2C */
|
||||||
|
i2c {
|
||||||
|
@@ -302,5 +311,13 @@
|
||||||
|
ide@63000000 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+ usb@69000000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ dr_mode = "peripheral";
|
||||||
|
+ usb-phy = <&usb1_phy>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ pinctrl-0 = <&usb_default_pins>;
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
--- a/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/gemini.dtsi
|
||||||
|
@@ -455,6 +455,8 @@
|
||||||
|
*/
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&usb_default_pins>;
|
||||||
|
+ /* Default to host mode */
|
||||||
|
+ dr_mode = "host";
|
||||||
|
syscon = <&syscon>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
@ -0,0 +1,34 @@
|
|||||||
|
From 36ee838bf83c01cff7cb47c7b07be278d2950ac0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Date: Mon, 11 Mar 2019 15:44:29 +0100
|
||||||
|
Subject: [PATCH 2/2] ARM: dts: Augment DIR-685 partition table for OpenWrt
|
||||||
|
|
||||||
|
Rename the firmware partition so that the firmware MTD
|
||||||
|
splitter will do its job, drop the rootfs arguments as
|
||||||
|
the MTD splitter will set this up automatically.
|
||||||
|
|
||||||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
---
|
||||||
|
--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
|
||||||
|
+++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
|
||||||
|
@@ -20,7 +20,7 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
- bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300";
|
||||||
|
+ bootargs = "console=ttyS0,19200n8 consoleblank=300";
|
||||||
|
stdout-path = "uart0:19200n8";
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -317,9 +317,9 @@
|
||||||
|
* this is called "upgrade" on the vendor system.
|
||||||
|
*/
|
||||||
|
partition@40000 {
|
||||||
|
- label = "upgrade";
|
||||||
|
+ compatible = "wrg";
|
||||||
|
+ label = "firmware";
|
||||||
|
reg = <0x00040000 0x01f40000>;
|
||||||
|
- read-only;
|
||||||
|
};
|
||||||
|
/* RGDB, Residental Gateway Database? */
|
||||||
|
partition@1f80000 {
|
Loading…
x
Reference in New Issue
Block a user