diff options
author | Pawel Laszczak <pawell@cadence.com> | 2020-12-07 13:32:19 +0300 |
---|---|---|
committer | Peter Chen <peter.chen@nxp.com> | 2020-12-29 07:36:13 +0300 |
commit | f738957277bad824b422399a214b630d7832f884 (patch) | |
tree | 11744810ab909b1aace22c47097847abd0ccdad9 /drivers/usb/cdns3/core.c | |
parent | db8892bb1bb64b6e3d1381ac342a2ee31e1b76b6 (diff) | |
download | linux-f738957277bad824b422399a214b630d7832f884.tar.xz |
usb: cdns3: Split core.c into cdns3-plat and core.c file
Patch splits file core.c into core.c containing the common reusable code
and cnd3-plat.c containing device platform specific code. These changes
are required to make possible reuse DRD part of CDNS3 driver in CDNSP
driver.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Tested-by: Aswath Govindraju <a-govindraju@ti.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Diffstat (limited to 'drivers/usb/cdns3/core.c')
-rw-r--r-- | drivers/usb/cdns3/core.c | 284 |
1 files changed, 24 insertions, 260 deletions
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 04990812181d..7b67a7c74586 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -385,26 +385,6 @@ pm_put: return ret; } -static int set_phy_power_on(struct cdns3 *cdns) -{ - int ret; - - ret = phy_power_on(cdns->usb2_phy); - if (ret) - return ret; - - ret = phy_power_on(cdns->usb3_phy); - if (ret) - phy_power_off(cdns->usb2_phy); - - return ret; -} - -static void set_phy_power_off(struct cdns3 *cdns) -{ - phy_power_off(cdns->usb3_phy); - phy_power_off(cdns->usb2_phy); -} /** * cdns3_wakeup_irq - interrupt handler for wakeup events @@ -431,16 +411,13 @@ static irqreturn_t cdns3_wakeup_irq(int irq, void *data) /** * cdns3_probe - probe for cdns3 core device - * @pdev: Pointer to cdns3 core platform device + * @cdns: Pointer to cdnsp structure. * * Returns 0 on success otherwise negative errno */ -static int cdns3_probe(struct platform_device *pdev) +int cdns3_init(struct cdns3 *cdns) { - struct device *dev = &pdev->dev; - struct resource *res; - struct cdns3 *cdns; - void __iomem *regs; + struct device *dev = cdns->dev; int ret; ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); @@ -449,87 +426,8 @@ static int cdns3_probe(struct platform_device *pdev) return ret; } - cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL); - if (!cdns) - return -ENOMEM; - - cdns->dev = dev; - cdns->pdata = dev_get_platdata(dev); - - platform_set_drvdata(pdev, cdns); - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "host"); - if (!res) { - dev_err(dev, "missing host IRQ\n"); - return -ENODEV; - } - - cdns->xhci_res[0] = *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xhci"); - if (!res) { - dev_err(dev, "couldn't get xhci resource\n"); - return -ENXIO; - } - - cdns->xhci_res[1] = *res; - - cdns->dev_irq = platform_get_irq_byname(pdev, "peripheral"); - if (cdns->dev_irq < 0) - return cdns->dev_irq; - - regs = devm_platform_ioremap_resource_byname(pdev, "dev"); - if (IS_ERR(regs)) - return PTR_ERR(regs); - cdns->dev_regs = regs; - - cdns->otg_irq = platform_get_irq_byname(pdev, "otg"); - if (cdns->otg_irq < 0) - return cdns->otg_irq; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otg"); - if (!res) { - dev_err(dev, "couldn't get otg resource\n"); - return -ENXIO; - } - - cdns->phyrst_a_enable = device_property_read_bool(dev, "cdns,phyrst-a-enable"); - - cdns->otg_res = *res; - - cdns->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup"); - if (cdns->wakeup_irq == -EPROBE_DEFER) - return cdns->wakeup_irq; - else if (cdns->wakeup_irq == 0) - return -EINVAL; - - if (cdns->wakeup_irq < 0) { - dev_dbg(dev, "couldn't get wakeup irq\n"); - cdns->wakeup_irq = 0x0; - } - mutex_init(&cdns->mutex); - cdns->usb2_phy = devm_phy_optional_get(dev, "cdns3,usb2-phy"); - if (IS_ERR(cdns->usb2_phy)) - return PTR_ERR(cdns->usb2_phy); - - ret = phy_init(cdns->usb2_phy); - if (ret) - return ret; - - cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy"); - if (IS_ERR(cdns->usb3_phy)) - return PTR_ERR(cdns->usb3_phy); - - ret = phy_init(cdns->usb3_phy); - if (ret) - goto err1; - - ret = set_phy_power_on(cdns); - if (ret) - goto err2; - if (device_property_read_bool(dev, "usb-role-switch")) { struct usb_role_switch_desc sw_desc = { }; @@ -541,9 +439,8 @@ static int cdns3_probe(struct platform_device *pdev) cdns->role_sw = usb_role_switch_register(dev, &sw_desc); if (IS_ERR(cdns->role_sw)) { - ret = PTR_ERR(cdns->role_sw); dev_warn(dev, "Unable to register Role Switch\n"); - goto err3; + return PTR_ERR(cdns->role_sw); } } @@ -555,153 +452,50 @@ static int cdns3_probe(struct platform_device *pdev) if (ret) { dev_err(cdns->dev, "couldn't register wakeup irq handler\n"); - goto err4; + goto role_switch_unregister; } } ret = cdns3_drd_init(cdns); if (ret) - goto err4; + goto init_failed; ret = cdns3_core_init_role(cdns); if (ret) - goto err4; + goto init_failed; spin_lock_init(&cdns->lock); - device_set_wakeup_capable(dev, true); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW))) - pm_runtime_forbid(dev); - /* - * The controller needs less time between bus and controller suspend, - * and we also needs a small delay to avoid frequently entering low - * power mode. - */ - pm_runtime_set_autosuspend_delay(dev, 20); - pm_runtime_mark_last_busy(dev); - pm_runtime_use_autosuspend(dev); dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); return 0; -err4: +init_failed: cdns3_drd_exit(cdns); +role_switch_unregister: if (cdns->role_sw) usb_role_switch_unregister(cdns->role_sw); -err3: - set_phy_power_off(cdns); -err2: - phy_exit(cdns->usb3_phy); -err1: - phy_exit(cdns->usb2_phy); return ret; } /** * cdns3_remove - unbind drd driver and clean up - * @pdev: Pointer to Linux platform device + * @cdns: Pointer to cdnsp structure. * * Returns 0 on success otherwise negative errno */ -static int cdns3_remove(struct platform_device *pdev) +int cdns3_remove(struct cdns3 *cdns) { - struct cdns3 *cdns = platform_get_drvdata(pdev); - - pm_runtime_get_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); cdns3_exit_roles(cdns); usb_role_switch_unregister(cdns->role_sw); - set_phy_power_off(cdns); - phy_exit(cdns->usb2_phy); - phy_exit(cdns->usb3_phy); - return 0; -} - -#ifdef CONFIG_PM - -static int cdns3_set_platform_suspend(struct device *dev, - bool suspend, bool wakeup) -{ - struct cdns3 *cdns = dev_get_drvdata(dev); - int ret = 0; - - if (cdns->pdata && cdns->pdata->platform_suspend) - ret = cdns->pdata->platform_suspend(dev, suspend, wakeup); - - return ret; -} - -static int cdns3_controller_suspend(struct device *dev, pm_message_t msg) -{ - struct cdns3 *cdns = dev_get_drvdata(dev); - bool wakeup; - unsigned long flags; - - if (cdns->in_lpm) - return 0; - - if (PMSG_IS_AUTO(msg)) - wakeup = true; - else - wakeup = device_may_wakeup(dev); - - cdns3_set_platform_suspend(cdns->dev, true, wakeup); - set_phy_power_off(cdns); - spin_lock_irqsave(&cdns->lock, flags); - cdns->in_lpm = true; - spin_unlock_irqrestore(&cdns->lock, flags); - dev_dbg(cdns->dev, "%s ends\n", __func__); return 0; } -static int cdns3_controller_resume(struct device *dev, pm_message_t msg) -{ - struct cdns3 *cdns = dev_get_drvdata(dev); - int ret; - unsigned long flags; - - if (!cdns->in_lpm) - return 0; - - ret = set_phy_power_on(cdns); - if (ret) - return ret; - - cdns3_set_platform_suspend(cdns->dev, false, false); - - spin_lock_irqsave(&cdns->lock, flags); - if (cdns->roles[cdns->role]->resume && !PMSG_IS_AUTO(msg)) - cdns->roles[cdns->role]->resume(cdns, false); - - cdns->in_lpm = false; - spin_unlock_irqrestore(&cdns->lock, flags); - if (cdns->wakeup_pending) { - cdns->wakeup_pending = false; - enable_irq(cdns->wakeup_irq); - } - dev_dbg(cdns->dev, "%s ends\n", __func__); - - return ret; -} - -static int cdns3_runtime_suspend(struct device *dev) -{ - return cdns3_controller_suspend(dev, PMSG_AUTO_SUSPEND); -} - -static int cdns3_runtime_resume(struct device *dev) -{ - return cdns3_controller_resume(dev, PMSG_AUTO_RESUME); -} #ifdef CONFIG_PM_SLEEP - -static int cdns3_suspend(struct device *dev) +int cdns3_suspend(struct cdns3 *cdns) { - struct cdns3 *cdns = dev_get_drvdata(dev); + struct device *dev = cdns->dev; unsigned long flags; if (pm_runtime_status_suspended(dev)) @@ -713,52 +507,22 @@ static int cdns3_suspend(struct device *dev) spin_unlock_irqrestore(&cdns->lock, flags); } - return cdns3_controller_suspend(dev, PMSG_SUSPEND); + return 0; } -static int cdns3_resume(struct device *dev) +int cdns3_resume(struct cdns3 *cdns, u8 set_active) { - int ret; + struct device *dev = cdns->dev; - ret = cdns3_controller_resume(dev, PMSG_RESUME); - if (ret) - return ret; + if (cdns->roles[cdns->role]->resume) + cdns->roles[cdns->role]->resume(cdns, false); - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); + if (set_active) { + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + } - return ret; + return 0; } #endif /* CONFIG_PM_SLEEP */ -#endif /* CONFIG_PM */ - -static const struct dev_pm_ops cdns3_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cdns3_suspend, cdns3_resume) - SET_RUNTIME_PM_OPS(cdns3_runtime_suspend, cdns3_runtime_resume, NULL) -}; - -#ifdef CONFIG_OF -static const struct of_device_id of_cdns3_match[] = { - { .compatible = "cdns,usb3" }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_cdns3_match); -#endif - -static struct platform_driver cdns3_driver = { - .probe = cdns3_probe, - .remove = cdns3_remove, - .driver = { - .name = "cdns-usb3", - .of_match_table = of_match_ptr(of_cdns3_match), - .pm = &cdns3_pm_ops, - }, -}; - -module_platform_driver(cdns3_driver); - -MODULE_ALIAS("platform:cdns3"); -MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver"); |