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>
246 lines
6.9 KiB
Diff
246 lines
6.9 KiB
Diff
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;
|
|
}
|