On Thu, Nov 15, 2012 at 04:34:00PM +0200, Roger Quadros wrote: > Every channel has a functional clock that is similarly named. > It makes sense to use a for loop to manage these clocks as OMAPs > can come with upto 3 channels. s/upto/up to BTW, this patch is doing a lot more than "cleaning up clock handling". This needs to be split into smaller patches. > Signed-off-by: Roger Quadros <rogerq@xxxxxx> > --- > drivers/mfd/omap-usb-tll.c | 130 +++++++++++++++++++++++++------------------- > 1 files changed, 74 insertions(+), 56 deletions(-) > > diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c > index d1750a4..943ac14 100644 > --- a/drivers/mfd/omap-usb-tll.c > +++ b/drivers/mfd/omap-usb-tll.c > @@ -82,8 +82,12 @@ > #define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) > #define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) > > -#define OMAP_REV2_TLL_CHANNEL_COUNT 2 > -#define OMAP_TLL_CHANNEL_COUNT 3 > +#define REV2_TLL_CHANNEL_COUNT 2 why are you dropping the OMAP_ prefix ? You shouldn't do that. > +#define DEFAULT_TLL_CHANNEL_COUNT 3 Add OMAP_ prefix here. > + > +/* Update if any chip has more */ > +#define MAX_TLL_CHANNEL_COUNT 3 can't you figure this one out in runtime ? If this isn't in any registers (and looks like it's not), you can pass this information to the driver via DT or just use driver_data field on struct platform_driver. > #define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0) > #define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1) > #define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2) > @@ -96,8 +100,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; > + void __iomem *base; > + int nch; /* number of channels */ > + struct clk *ch_clk[MAX_TLL_CHANNEL_COUNT]; should be allocated dynamically. > struct usbtll_omap_platform_data *pdata; > /* secure the register updates */ > spinlock_t lock; > @@ -210,49 +215,35 @@ static int __devinit usbtll_omap_probe(struct platform_device *pdev) > unsigned reg; > unsigned long flags; > int ret = 0; > - int i, ver, count; > + int i, ver; > > dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); > > tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL); > if (!tll) { > dev_err(dev, "Memory allocation failed\n"); > - ret = -ENOMEM; > - goto end; > + return -ENOMEM; > } > > spin_lock_init(&tll->lock); > > 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); > - goto err_tll; > - } > - > - 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_usbtll_p1_fck; > - } > - > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > if (!res) { > dev_err(dev, "usb tll get resource failed\n"); > ret = -ENODEV; > - goto err_usbtll_p2_fck; > + goto err_mem; > } > > base = ioremap(res->start, resource_size(res)); > if (!base) { > dev_err(dev, "TLL ioremap failed\n"); > ret = -ENOMEM; > - goto err_usbtll_p2_fck; > + goto err_mem; > } > > + tll->base = base; > platform_set_drvdata(pdev, tll); > pm_runtime_enable(dev); > pm_runtime_get_sync(dev); > @@ -262,16 +253,33 @@ static int __devinit usbtll_omap_probe(struct platform_device *pdev) > ver = usbtll_read(base, OMAP_USBTLL_REVISION); > switch (ver) { > case OMAP_USBTLL_REV1: > - case OMAP_USBTLL_REV2: > - count = OMAP_TLL_CHANNEL_COUNT; > + tll->nch = DEFAULT_TLL_CHANNEL_COUNT; > break; > + case OMAP_USBTLL_REV2: > case OMAP_USBTLL_REV3: > - count = OMAP_REV2_TLL_CHANNEL_COUNT; > + tll->nch = REV2_TLL_CHANNEL_COUNT; nice, you *can* figure that out based on the revision... In that case, you shouldn't even define MAX_TLL_CHANNEL_COUNT, just allocate the array dynamically for the exact size you need. > break; > default: > - dev_err(dev, "TLL version failed\n"); > - ret = -ENODEV; > - goto err_ioremap; > + tll->nch = DEFAULT_TLL_CHANNEL_COUNT; > + dev_info(dev, > + "USB TLL Rev : 0x%x not recognized, assuming %d channels\n", > + ver, tll->nch); this hsould be dev_dbg(). > + break; > + } > + > + for (i = 0; i < tll->nch; i++) { > + char clk_name[] = "usb_tll_hs_usb_chx_clk"; just lazyness of counting the amount of letters ? :-p > + struct clk *fck; > + > + sprintf(clk_name, "usb_tll_hs_usb_ch%d_clk", i); this will overflow if 'i' (for whatever reason) goes over 9. > + fck = clk_get(dev, clk_name); please use devm_clk_get(). > + if (IS_ERR(fck)) { > + dev_err(dev, "can't get clock : %s\n", clk_name); > + ret = PTR_ERR(fck); > + goto err_clk; > + } > + tll->ch_clk[i] = fck; > } > > if (is_ehci_tll_mode(pdata->port_mode[0]) || > @@ -291,7 +299,7 @@ static int __devinit usbtll_omap_probe(struct platform_device *pdev) > usbtll_write(base, OMAP_TLL_SHARED_CONF, reg); > > /* Enable channels now */ > - for (i = 0; i < count; i++) { > + for (i = 0; i < tll->nch; i++) { > reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i)); > > if (is_ohci_port(pdata->port_mode[i])) { > @@ -319,25 +327,25 @@ static int __devinit usbtll_omap_probe(struct platform_device *pdev) > } > } > > -err_ioremap: > - spin_unlock_irqrestore(&tll->lock, flags); > - iounmap(base); > - pm_runtime_put_sync(dev); > tll_pdev = pdev; > - if (!ret) > - goto end; > - pm_runtime_disable(dev); > > -err_usbtll_p2_fck: > - clk_put(tll->usbtll_p2_fck); > +err_clk: > + for (--i; i >= 0 ; i--) > + clk_put(tll->ch_clk[i]); is clk_put(NULL) safe ?? > -err_usbtll_p1_fck: > - clk_put(tll->usbtll_p1_fck); > + spin_unlock_irqrestore(&tll->lock, flags); > + pm_runtime_put_sync(dev); > + if (ret == 0) { > + pr_info("OMAP USB TLL : revision 0x%x, channels %d\n", > + ver, tll->nch); > + return 0; > + } the whole thing is quite confusing. Please while cleaning up the driver, also try to clean up the error path. > -err_tll: > - kfree(tll); > + iounmap(base); could be using devm_request_and_ioremap() > + pm_runtime_disable(dev); > > -end: > +err_mem: > + kfree(tll); could be using devm_kzalloc() > return ret; > } > > @@ -350,9 +358,12 @@ end: > static int __devexit usbtll_omap_remove(struct platform_device *pdev) > { > struct usbtll_omap *tll = platform_get_drvdata(pdev); > + int i; > + > + iounmap(tll->base); > + 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); > kfree(tll); > return 0; > @@ -363,6 +374,7 @@ static int usbtll_runtime_resume(struct device *dev) > struct usbtll_omap *tll = dev_get_drvdata(dev); > struct usbtll_omap_platform_data *pdata = tll->pdata; > unsigned long flags; > + int i; > > dev_dbg(dev, "usbtll_runtime_resume\n"); > > @@ -373,11 +385,17 @@ 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); > - > - if (is_ehci_tll_mode(pdata->port_mode[1])) > - clk_enable(tll->usbtll_p2_fck); > + for (i = 0; i < tll->nch; i++) { > + if (is_ehci_tll_mode(pdata->port_mode[i])) { > + int r; > + r = clk_enable(tll->ch_clk[i]); > + if (r) { > + dev_err(dev, > + "%s : Error enabling ch %d clock: %d\n", > + __func__, i, r); you don't need __func__. -- balbi
Attachment:
signature.asc
Description: Digital signature