@@ -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 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;
}
@@ -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 */
@@ -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;
};
@@ -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");
@@ -1207,11 +1201,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);
@@ -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;
@@ -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;
}