Message ID | 1358511445-26656-6-git-send-email-rogerq@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Jan 18, 2013 at 02:17:08PM +0200, Roger Quadros wrote: > + tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]), > + GFP_KERNEL); > + if (!tll->ch_clk) { > + ret = -ENOMEM; > + dev_err(dev, "Couldn't allocate memory for channel clocks\n"); > + goto err_clk_alloc; > + } > + > + for (i = 0; i < tll->nch; i++) { > + char clkname[] = "usb_tll_hs_usb_chx_clk"; > + struct clk *fck; > + > + snprintf(clkname, sizeof(clkname), > + "usb_tll_hs_usb_ch%d_clk", i); > + fck = clk_get(dev, clkname); > + > + if (IS_ERR(fck)) > + dev_dbg(dev, "can't get clock : %s\n", clkname); > + else > + tll->ch_clk[i] = fck; Hmm. I'd actually suggest that this becomes: tll->ch_clk[i] = fck; if (IS_ERR(fck) dev_dbg(dev, "can't get clock: %s\n", clkname); so that tll->ch_clk is always written to. > static int usbtll_omap_remove(struct platform_device *pdev) > { > struct usbtll_omap *tll = platform_get_drvdata(pdev); > + int i; > + > + for (i = 0; i < tll->nch; i++) > + clk_put(tll->ch_clk[i]); And change this to: for (i = 0; i < tll->nch; i++) if (!IS_ERR(tll->ch_clk[i])) clk_put(tll->ch_clk[i]); so that you're not passing a NULL pointer in. > + for (i = 0; i < tll->nch; i++) { > + if (is_ehci_tll_mode(pdata->port_mode[i])) { > + int r; > > - if (is_ehci_tll_mode(pdata->port_mode[1])) > - clk_enable(tll->usbtll_p2_fck); > + if (!tll->ch_clk[i]) if (IS_ERR(tll->ch_clk[i])) > + continue; > + > + r = clk_enable(tll->ch_clk[i]); > + if (r) { > + dev_err(dev, > + "Error enabling ch %d clock: %d\n", i, r); > + } > + } > + } > @@ -387,11 +409,12 @@ static int usbtll_runtime_suspend(struct device *dev) > > spin_lock_irqsave(&tll->lock, flags); > > - if (is_ehci_tll_mode(pdata->port_mode[0])) > - clk_disable(tll->usbtll_p1_fck); > - > - if (is_ehci_tll_mode(pdata->port_mode[1])) > - clk_disable(tll->usbtll_p2_fck); > + for (i = 0; i < tll->nch; i++) { > + if (is_ehci_tll_mode(pdata->port_mode[i])) { > + if (tll->ch_clk[i]) if (!IS_ERR(tll->ch_clk[i])) > + clk_disable(tll->ch_clk[i]); > + } > + } > > spin_unlock_irqrestore(&tll->lock, flags); > > -- > 1.7.4.1 >
On 01/18/2013 04:59 PM, Russell King - ARM Linux wrote: > On Fri, Jan 18, 2013 at 02:17:08PM +0200, Roger Quadros wrote: >> + tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]), >> + GFP_KERNEL); >> + if (!tll->ch_clk) { >> + ret = -ENOMEM; >> + dev_err(dev, "Couldn't allocate memory for channel clocks\n"); >> + goto err_clk_alloc; >> + } >> + >> + for (i = 0; i < tll->nch; i++) { >> + char clkname[] = "usb_tll_hs_usb_chx_clk"; >> + struct clk *fck; >> + >> + snprintf(clkname, sizeof(clkname), >> + "usb_tll_hs_usb_ch%d_clk", i); >> + fck = clk_get(dev, clkname); >> + >> + if (IS_ERR(fck)) >> + dev_dbg(dev, "can't get clock : %s\n", clkname); >> + else >> + tll->ch_clk[i] = fck; > > Hmm. I'd actually suggest that this becomes: > > tll->ch_clk[i] = fck; > if (IS_ERR(fck) > dev_dbg(dev, "can't get clock: %s\n", clkname); > > so that tll->ch_clk is always written to. Yes, I'll fix this. > >> static int usbtll_omap_remove(struct platform_device *pdev) >> { >> struct usbtll_omap *tll = platform_get_drvdata(pdev); >> + int i; >> + >> + for (i = 0; i < tll->nch; i++) >> + clk_put(tll->ch_clk[i]); > > And change this to: > > for (i = 0; i < tll->nch; i++) > if (!IS_ERR(tll->ch_clk[i])) > clk_put(tll->ch_clk[i]); > > so that you're not passing a NULL pointer in. > ok. >> + for (i = 0; i < tll->nch; i++) { >> + if (is_ehci_tll_mode(pdata->port_mode[i])) { >> + int r; >> >> - if (is_ehci_tll_mode(pdata->port_mode[1])) >> - clk_enable(tll->usbtll_p2_fck); >> + if (!tll->ch_clk[i]) > > if (IS_ERR(tll->ch_clk[i])) ok. > >> + continue; >> + >> + r = clk_enable(tll->ch_clk[i]); >> + if (r) { >> + dev_err(dev, >> + "Error enabling ch %d clock: %d\n", i, r); >> + } >> + } >> + } > >> @@ -387,11 +409,12 @@ static int usbtll_runtime_suspend(struct device *dev) >> >> spin_lock_irqsave(&tll->lock, flags); >> >> - if (is_ehci_tll_mode(pdata->port_mode[0])) >> - clk_disable(tll->usbtll_p1_fck); >> - >> - if (is_ehci_tll_mode(pdata->port_mode[1])) >> - clk_disable(tll->usbtll_p2_fck); >> + for (i = 0; i < tll->nch; i++) { >> + if (is_ehci_tll_mode(pdata->port_mode[i])) { >> + if (tll->ch_clk[i]) > > if (!IS_ERR(tll->ch_clk[i])) ok. > >> + clk_disable(tll->ch_clk[i]); >> + } >> + } >> >> spin_unlock_irqrestore(&tll->lock, flags); >> -- cheers, -roger
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 9a19cc7..4ce134b 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c @@ -96,10 +96,9 @@ #define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) struct usbtll_omap { - struct clk *usbtll_p1_fck; - struct clk *usbtll_p2_fck; int nch; /* num. of channels */ struct usbhs_omap_platform_data *pdata; + struct clk **ch_clk; /* secure the register updates */ spinlock_t lock; }; @@ -225,26 +224,12 @@ static int usbtll_omap_probe(struct platform_device *pdev) tll->pdata = pdata; - tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); - if (IS_ERR(tll->usbtll_p1_fck)) { - ret = PTR_ERR(tll->usbtll_p1_fck); - dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); - return ret; - } - - tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); - if (IS_ERR(tll->usbtll_p2_fck)) { - ret = PTR_ERR(tll->usbtll_p2_fck); - dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); - goto err_p2_fck; - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_request_and_ioremap(dev, res); if (!base) { ret = -EADDRNOTAVAIL; dev_err(dev, "Resource request/ioremap failed:%d\n", ret); - goto err_res; + return ret; } platform_set_drvdata(pdev, tll); @@ -270,6 +255,32 @@ static int usbtll_omap_probe(struct platform_device *pdev) break; } + spin_unlock_irqrestore(&tll->lock, flags); + + tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]), + GFP_KERNEL); + if (!tll->ch_clk) { + ret = -ENOMEM; + dev_err(dev, "Couldn't allocate memory for channel clocks\n"); + goto err_clk_alloc; + } + + for (i = 0; i < tll->nch; i++) { + char clkname[] = "usb_tll_hs_usb_chx_clk"; + struct clk *fck; + + snprintf(clkname, sizeof(clkname), + "usb_tll_hs_usb_ch%d_clk", i); + fck = clk_get(dev, clkname); + + if (IS_ERR(fck)) + dev_dbg(dev, "can't get clock : %s\n", clkname); + else + tll->ch_clk[i] = fck; + } + + spin_lock_irqsave(&tll->lock, flags); + if (is_ehci_tll_mode(pdata->port_mode[0]) || is_ehci_tll_mode(pdata->port_mode[1]) || is_ehci_tll_mode(pdata->port_mode[2]) || @@ -321,11 +332,9 @@ static int usbtll_omap_probe(struct platform_device *pdev) return 0; -err_res: - clk_put(tll->usbtll_p2_fck); - -err_p2_fck: - clk_put(tll->usbtll_p1_fck); +err_clk_alloc: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); return ret; } @@ -339,9 +348,11 @@ err_p2_fck: static int usbtll_omap_remove(struct platform_device *pdev) { struct usbtll_omap *tll = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < tll->nch; i++) + clk_put(tll->ch_clk[i]); - clk_put(tll->usbtll_p2_fck); - clk_put(tll->usbtll_p1_fck); pm_runtime_disable(&pdev->dev); return 0; } @@ -351,6 +362,7 @@ static int usbtll_runtime_resume(struct device *dev) struct usbtll_omap *tll = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = tll->pdata; unsigned long flags; + int i; dev_dbg(dev, "usbtll_runtime_resume\n"); @@ -361,11 +373,20 @@ static int usbtll_runtime_resume(struct device *dev) spin_lock_irqsave(&tll->lock, flags); - if (is_ehci_tll_mode(pdata->port_mode[0])) - clk_enable(tll->usbtll_p1_fck); + for (i = 0; i < tll->nch; i++) { + if (is_ehci_tll_mode(pdata->port_mode[i])) { + int r; - if (is_ehci_tll_mode(pdata->port_mode[1])) - clk_enable(tll->usbtll_p2_fck); + if (!tll->ch_clk[i]) + continue; + + r = clk_enable(tll->ch_clk[i]); + if (r) { + dev_err(dev, + "Error enabling ch %d clock: %d\n", i, r); + } + } + } spin_unlock_irqrestore(&tll->lock, flags); @@ -377,6 +398,7 @@ static int usbtll_runtime_suspend(struct device *dev) struct usbtll_omap *tll = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = tll->pdata; unsigned long flags; + int i; dev_dbg(dev, "usbtll_runtime_suspend\n"); @@ -387,11 +409,12 @@ static int usbtll_runtime_suspend(struct device *dev) spin_lock_irqsave(&tll->lock, flags); - if (is_ehci_tll_mode(pdata->port_mode[0])) - clk_disable(tll->usbtll_p1_fck); - - if (is_ehci_tll_mode(pdata->port_mode[1])) - clk_disable(tll->usbtll_p2_fck); + for (i = 0; i < tll->nch; i++) { + if (is_ehci_tll_mode(pdata->port_mode[i])) { + if (tll->ch_clk[i]) + clk_disable(tll->ch_clk[i]); + } + } spin_unlock_irqrestore(&tll->lock, flags);