usb: fotg210: Acquire memory resource in core
authorLinus Walleij <linus.walleij@linaro.org>
Wed, 18 Jan 2023 07:09:17 +0000 (08:09 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jan 2023 13:10:43 +0000 (14:10 +0100)
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>
drivers/usb/fotg210/fotg210-core.c
drivers/usb/fotg210/fotg210-hcd.c
drivers/usb/fotg210/fotg210-hcd.h
drivers/usb/fotg210/fotg210-udc.c
drivers/usb/fotg210/fotg210-udc.h
drivers/usb/fotg210/fotg210.h

index da9ea5957ccff25a702ba99c82810b72fd79061c..0dd4957ad70af76da72ceadd904cec99a07077fc 100644 (file)
 #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 device *dev, struct resource *res,
                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 device *dev, struct resource *res,
         */
        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 device *dev, struct resource *res,
                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_device *pdev)
 {
        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;
 }
index 51ac93a2eb98e54509c3891521b3121f30ae7ab4..15ba5b1618e1130cabbf3ab1f88c471628426cdf 100644 (file)
@@ -5557,11 +5557,10 @@ static void fotg210_init(struct fotg210_hcd *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_device *pdev)
 
        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 */
index 0781442b7a24ab80218b2a1c9a36e70c3fab2ab0..13c9342982ee97f5f929967ad426e2468ebf62d3 100644 (file)
@@ -182,6 +182,7 @@ struct fotg210_hcd {                        /* one per controller */
 #      define INCR(x) do {} while (0)
 #endif
 
+       struct fotg210          *fotg;          /* Overarching FOTG210 device */
        /* silicon clock */
        struct clk              *pclk;
 };
index 87cca81bf4ac970fcdb902e5add8c0a68eacb0e4..a4a6f57c31905cb1f0bafda43559c387fe0713d0 100644 (file)
@@ -1142,21 +1142,14 @@ int fotg210_udc_remove(struct platform_device *pdev)
        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");
@@ -1169,6 +1162,7 @@ int fotg210_udc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        fotg210->dev = dev;
+       fotg210->fotg = fotg;
 
        /* It's OK not to supply this clock */
        fotg210->pclk = devm_clk_get(dev, "PCLK");
@@ -1209,11 +1203,7 @@ int fotg210_udc_probe(struct platform_device *pdev)
                        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);
 
index fadb57ca8d7863068d9c659f5aa6dc7e884561ea..20335a38a410d11d4a19d71474c59c22161f793a 100644 (file)
@@ -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;
index ef79d8323d89793c33fdec18480da781cf30b3b5..50436cc16538c05ef983dd8a82f609f4336ecbac 100644 (file)
@@ -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(void)
 #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;
 }