--- /dev/null
+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;
+ }