gemini: Add kernel v6.1 patches
[openwrt/openwrt.git] / target / linux / gemini / patches-6.1 / 0017-usb-fotg210-Acquire-memory-resource-in-core.patch
diff --git a/target/linux/gemini/patches-6.1/0017-usb-fotg210-Acquire-memory-resource-in-core.patch b/target/linux/gemini/patches-6.1/0017-usb-fotg210-Acquire-memory-resource-in-core.patch
new file mode 100644 (file)
index 0000000..7dbd511
--- /dev/null
@@ -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;
+ }