From 0349176120aa3024e96ae4fd7dc0e0181dc55f52 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 2 Dec 2010 09:57:08 +0200 Subject: usb: musb: move clock handling to glue layer musb core doesn't need to know about platform specific details. So start moving clock handling to platform glue layer and make musb core agnostic about that. Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 91 +++++++++++++++++++++++++++----------------- drivers/usb/musb/da8xx.c | 36 ++++++++++++++---- drivers/usb/musb/davinci.c | 36 +++++++++++++----- drivers/usb/musb/musb_core.c | 39 +------------------ drivers/usb/musb/musb_core.h | 2 - drivers/usb/musb/omap2430.c | 46 +++++++++++++--------- drivers/usb/musb/tusb6010.c | 15 -------- 7 files changed, 140 insertions(+), 125 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index e372c87f37e..e4e571bf9ba 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -85,6 +85,8 @@ struct am35x_glue { struct device *dev; struct platform_device *musb; + struct clk *phy_clk; + struct clk *clk; }; static inline void phy_on(void) @@ -402,34 +404,18 @@ static int am35x_musb_init(struct musb *musb) { void __iomem *reg_base = musb->ctrl_base; u32 rev, lvl_intr, sw_reset; - int status; musb->mregs += USB_MENTOR_CORE_OFFSET; - clk_enable(musb->clock); - DBG(2, "musb->clock=%lud\n", clk_get_rate(musb->clock)); - - musb->phy_clock = clk_get(musb->controller, "fck"); - if (IS_ERR(musb->phy_clock)) { - status = PTR_ERR(musb->phy_clock); - goto exit0; - } - clk_enable(musb->phy_clock); - DBG(2, "musb->phy_clock=%lud\n", clk_get_rate(musb->phy_clock)); - /* Returns zero if e.g. not clocked */ rev = musb_readl(reg_base, USB_REVISION_REG); - if (!rev) { - status = -ENODEV; - goto exit1; - } + if (!rev) + return -ENODEV; usb_nop_xceiv_register(); musb->xceiv = otg_get_transceiver(); - if (!musb->xceiv) { - status = -ENODEV; - goto exit1; - } + if (!musb->xceiv) + return -ENODEV; if (is_host_enabled(musb)) setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); @@ -459,13 +445,8 @@ static int am35x_musb_init(struct musb *musb) lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); lvl_intr |= AM35XX_USBOTGSS_INT_CLR; omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR); + return 0; -exit1: - clk_disable(musb->phy_clock); - clk_put(musb->phy_clock); -exit0: - clk_disable(musb->clock); - return status; } static int am35x_musb_exit(struct musb *musb) @@ -478,11 +459,6 @@ static int am35x_musb_exit(struct musb *musb) otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); - clk_disable(musb->clock); - - clk_disable(musb->phy_clock); - clk_put(musb->phy_clock); - return 0; } @@ -551,6 +527,9 @@ static int __init am35x_probe(struct platform_device *pdev) struct platform_device *musb; struct am35x_glue *glue; + struct clk *phy_clk; + struct clk *clk; + int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); @@ -565,12 +544,40 @@ static int __init am35x_probe(struct platform_device *pdev) goto err1; } + phy_clk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(phy_clk)) { + dev_err(&pdev->dev, "failed to get PHY clock\n"); + ret = PTR_ERR(phy_clk); + goto err2; + } + + clk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + ret = PTR_ERR(clk); + goto err3; + } + + ret = clk_enable(phy_clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable PHY clock\n"); + goto err4; + } + + ret = clk_enable(clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock\n"); + goto err5; + } + musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &am35x_dmamask; musb->dev.coherent_dma_mask = am35x_dmamask; glue->dev = &pdev->dev; glue->musb = musb; + glue->phy_clk = phy_clk; + glue->clk = clk; pdata->platform_ops = &am35x_ops; @@ -580,23 +587,35 @@ static int __init am35x_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err6; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err6; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err6; } return 0; +err6: + clk_disable(clk); + +err5: + clk_disable(phy_clk); + +err4: + clk_put(clk); + +err3: + clk_put(phy_clk); + err2: platform_device_put(musb); @@ -613,6 +632,10 @@ static int __exit am35x_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + clk_disable(glue->clk); + clk_disable(glue->phy_clk); + clk_put(glue->clk); + clk_put(glue->phy_clk); kfree(glue); return 0; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 45ccac3aad9..387f4a75706 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -83,6 +83,7 @@ struct da8xx_glue { struct device *dev; struct platform_device *musb; + struct clk *clk; }; /* @@ -423,8 +424,6 @@ static int da8xx_musb_init(struct musb *musb) musb->mregs += DA8XX_MENTOR_CORE_OFFSET; - clk_enable(musb->clock); - /* Returns zero if e.g. not clocked */ rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG); if (!rev) @@ -456,7 +455,6 @@ static int da8xx_musb_init(struct musb *musb) musb->isr = da8xx_musb_interrupt; return 0; fail: - clk_disable(musb->clock); return -ENODEV; } @@ -470,8 +468,6 @@ static int da8xx_musb_exit(struct musb *musb) otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); - clk_disable(musb->clock); - return 0; } @@ -496,6 +492,8 @@ static int __init da8xx_probe(struct platform_device *pdev) struct platform_device *musb; struct da8xx_glue *glue; + struct clk *clk; + int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); @@ -510,12 +508,26 @@ static int __init da8xx_probe(struct platform_device *pdev) goto err1; } + clk = clk_get(&pdev->dev, "usb20"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + ret = PTR_ERR(clk); + goto err2; + } + + ret = clk_enable(clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock\n"); + goto err3; + } + musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &da8xx_dmamask; musb->dev.coherent_dma_mask = da8xx_dmamask; glue->dev = &pdev->dev; glue->musb = musb; + glue->clk = clk; pdata->platform_ops = &da8xx_ops; @@ -525,23 +537,29 @@ static int __init da8xx_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err4; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err4; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err4; } return 0; +err4: + clk_disable(clk); + +err3: + clk_put(clk); + err2: platform_device_put(musb); @@ -558,6 +576,8 @@ static int __exit da8xx_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + clk_disable(glue->clk); + clk_put(glue->clk); kfree(glue); return 0; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 831a04dd5a5..de67480d4f1 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -56,6 +56,7 @@ struct davinci_glue { struct device *dev; struct platform_device *musb; + struct clk *clk; }; /* REVISIT (PM) we should be able to keep the PHY in low power mode most @@ -395,8 +396,6 @@ static int davinci_musb_init(struct musb *musb) musb->mregs += DAVINCI_BASE_OFFSET; - clk_enable(musb->clock); - /* returns zero if e.g. not clocked */ revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); if (revision == 0) @@ -451,8 +450,6 @@ static int davinci_musb_init(struct musb *musb) return 0; fail: - clk_disable(musb->clock); - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); return -ENODEV; @@ -502,8 +499,6 @@ static int davinci_musb_exit(struct musb *musb) phy_off(); - clk_disable(musb->clock); - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); @@ -529,6 +524,7 @@ static int __init davinci_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; struct davinci_glue *glue; + struct clk *clk; int ret = -ENOMEM; @@ -544,12 +540,26 @@ static int __init davinci_probe(struct platform_device *pdev) goto err1; } + clk = clk_get(&pdev->dev, "usb"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + ret = PTR_ERR(clk); + goto err2; + } + + ret = clk_enable(clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock\n"); + goto err3; + } + musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &davinci_dmamask; musb->dev.coherent_dma_mask = davinci_dmamask; glue->dev = &pdev->dev; glue->musb = musb; + glue->clk = clk; pdata->platform_ops = &davinci_ops; @@ -559,23 +569,29 @@ static int __init davinci_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err4; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err4; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err4; } return 0; +err4: + clk_disable(clk); + +err3: + clk_put(clk); + err2: platform_device_put(musb); @@ -592,6 +608,8 @@ static int __exit davinci_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + clk_disable(glue->clk); + clk_put(glue->clk); kfree(glue); return 0; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index dcc77ef6cff..6078eece74c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1048,8 +1048,6 @@ static void musb_shutdown(struct platform_device *pdev) spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); musb_generic_disable(musb); - if (musb->clock) - clk_put(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); /* FIXME power down */ @@ -1994,29 +1992,13 @@ bad_config: spin_lock_init(&musb->lock); musb->board_mode = plat->mode; musb->board_set_power = plat->set_power; - musb->set_clock = plat->set_clock; musb->min_power = plat->min_power; musb->ops = plat->platform_ops; - /* Clock usage is chip-specific ... functional clock (DaVinci, - * OMAP2430), or PHY ref (some TUSB6010 boards). All this core - * code does is make sure a clock handle is available; platform - * code manages it during start/stop and suspend/resume. - */ - if (plat->clock) { - musb->clock = clk_get(dev, plat->clock); - if (IS_ERR(musb->clock)) { - status = PTR_ERR(musb->clock); - musb->clock = NULL; - goto fail1; - } - } - /* The musb_platform_init() call: * - adjusts musb->mregs and musb->isr if needed, * - may initialize an integrated tranceiver * - initializes musb->xceiv, usually by otg_get_transceiver() - * - activates clocks. * - stops powering VBUS * - assigns musb->board_set_vbus if host mode is enabled * @@ -2028,7 +2010,7 @@ bad_config: musb->isr = generic_interrupt; status = musb_platform_init(musb); if (status < 0) - goto fail2; + goto fail1; if (!musb->isr) { status = -ENODEV; @@ -2178,10 +2160,6 @@ fail3: device_init_wakeup(dev, 0); musb_platform_exit(musb); -fail2: - if (musb->clock) - clk_put(musb->clock); - fail1: dev_err(musb->controller, "musb_init_controller failed with status %d\n", status); @@ -2410,9 +2388,6 @@ static int musb_suspend(struct device *dev) unsigned long flags; struct musb *musb = dev_to_musb(&pdev->dev); - if (!musb->clock) - return 0; - spin_lock_irqsave(&musb->lock, flags); if (is_peripheral_active(musb)) { @@ -2427,10 +2402,6 @@ static int musb_suspend(struct device *dev) musb_save_context(musb); - if (musb->set_clock) - musb->set_clock(musb->clock, 0); - else - clk_disable(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); return 0; } @@ -2440,14 +2411,6 @@ static int musb_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct musb *musb = dev_to_musb(&pdev->dev); - if (!musb->clock) - return 0; - - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else - clk_enable(musb->clock); - musb_restore_context(musb); /* for static cmos like DaVinci, register values were preserved diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index fac1eab3c59..6c8e9630fb1 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -384,8 +384,6 @@ struct musb_context_registers { struct musb { /* device lock */ spinlock_t lock; - struct clk *clock; - struct clk *phy_clock; const struct musb_platform_ops *ops; struct musb_context_registers context; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2eea1703e63..fa3154b0304 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -40,6 +40,7 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; + struct clk *clk; }; static struct timer_list musb_idle_timer; @@ -277,9 +278,6 @@ static int omap2430_musb_suspend(struct musb *musb) { u32 l; - if (!musb->clock) - return 0; - /* in any role */ l = musb_readl(musb->mregs, OTG_FORCESTDBY); l |= ENABLEFORCE; /* enable MSTANDBY */ @@ -291,11 +289,6 @@ static int omap2430_musb_suspend(struct musb *musb) otg_set_suspend(musb->xceiv, 1); - if (musb->set_clock) - musb->set_clock(musb->clock, 0); - else - clk_disable(musb->clock); - return 0; } @@ -303,16 +296,8 @@ static int omap2430_musb_resume(struct musb *musb) { u32 l; - if (!musb->clock) - return 0; - otg_set_suspend(musb->xceiv, 0); - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else - clk_enable(musb->clock); - l = musb_readl(musb->mregs, OTG_SYSCONFIG); l &= ~ENABLEWAKEUP; /* disable wakeup */ musb_writel(musb->mregs, OTG_SYSCONFIG, l); @@ -356,6 +341,7 @@ static int __init omap2430_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; struct omap2430_glue *glue; + struct clk *clk; int ret = -ENOMEM; @@ -371,12 +357,26 @@ static int __init omap2430_probe(struct platform_device *pdev) goto err1; } + clk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + ret = PTR_ERR(clk); + goto err2; + } + + ret = clk_enable(clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock\n"); + goto err3; + } + musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &omap2430_dmamask; musb->dev.coherent_dma_mask = omap2430_dmamask; glue->dev = &pdev->dev; glue->musb = musb; + glue->clk = clk; pdata->platform_ops = &omap2430_ops; @@ -386,23 +386,29 @@ static int __init omap2430_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err4; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err4; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err4; } return 0; +err4: + clk_disable(clk); + +err3: + clk_put(clk); + err2: platform_device_put(musb); @@ -419,6 +425,8 @@ static int __exit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + clk_disable(glue->clk); + clk_put(glue->clk); kfree(glue); return 0; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index d6b832641c5..2ba3b070ed0 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -281,17 +281,6 @@ static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) void __iomem *tbase = musb->ctrl_base; u32 reg; - /* - * Keep clock active when enabled. Note that this is not tied to - * drawing VBUS, as with OTG mA can be less than musb->min_power. - */ - if (musb->set_clock) { - if (mA) - musb->set_clock(musb->clock, 1); - else - musb->set_clock(musb->clock, 0); - } - /* tps65030 seems to consume max 100mA, with maybe 60mA available * (measured on one board) for things other than tps and tusb. * @@ -537,8 +526,6 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (is_on) { - if (musb->set_clock) - musb->set_clock(musb->clock, 1); timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); musb->xceiv->default_a = 1; musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; @@ -577,8 +564,6 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) devctl &= ~MUSB_DEVCTL_SESSION; conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; - if (musb->set_clock) - musb->set_clock(musb->clock, 0); } prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN); -- cgit v1.2.3-70-g09d2