diff options
author | Ian Wisbon <ian.wisbon@timesys.com> | 2011-02-15 15:53:51 -0500 |
---|---|---|
committer | Ian Wisbon <ian.wisbon@timesys.com> | 2011-02-15 15:53:51 -0500 |
commit | dfdbf3f6e2d279f2a46ed95614cb4bf07657394d (patch) | |
tree | 2cc05669c5d3e47f7d4b28e31076b6dc6e771f36 /arch/arm/plat-mxc/dptc.c | |
parent | effff5718c380983788fe6c380671c18e15ac7c2 (diff) |
Digi del-5.6 Complete2.6.31-digi-201102151558
Diffstat (limited to 'arch/arm/plat-mxc/dptc.c')
-rw-r--r-- | arch/arm/plat-mxc/dptc.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/arch/arm/plat-mxc/dptc.c b/arch/arm/plat-mxc/dptc.c index 6b7f5599909e..a26fd9b8d516 100644 --- a/arch/arm/plat-mxc/dptc.c +++ b/arch/arm/plat-mxc/dptc.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -67,6 +67,7 @@ enum { struct device *dev_data0; struct device *dev_data1; +struct dptc_device *dptc_device_data; /*! * In case the MXC device has multiple DPTC modules, this structure is used to @@ -89,6 +90,8 @@ struct dptc_device { int curr_wp; /* DPTC vai bits */ u32 ptvai; + /* The base address of the DPTC */ + void __iomem *membase; /* The interrupt number used by the DPTC device */ int irq; /* DPTC platform data pointer */ @@ -104,13 +107,13 @@ static void update_dptc_wp(struct dptc_device *drv_data, u32 wp) voltage_uV = dptc_data->dptc_wp_allfreq[wp].voltage * 1000; __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr0, - dptc_data->dcvr0_reg_addr); + drv_data->membase + dptc_data->dcvr0_reg_addr); __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr1, - dptc_data->dcvr0_reg_addr + 0x4); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0x4); __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr2, - dptc_data->dcvr0_reg_addr + 0x8); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0x8); __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr3, - dptc_data->dcvr0_reg_addr + 0xC); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0xC); /* Set the voltage */ ret = regulator_set_voltage(drv_data->dptc_reg, voltage_uV, voltage_uV); @@ -130,7 +133,8 @@ static irqreturn_t dptc_irq(int irq, void *dev_id) struct device *dev = dev_id; struct dptc_device *drv_data = dev->driver_data; struct mxc_dptc_data *dptc_data = dev->platform_data; - u32 dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + u32 dptccr = __raw_readl(drv_data->membase + + dptc_data->dptccr_reg_addr); u32 gpc_cntr = __raw_readl(dptc_data->gpc_cntr_reg_addr); gpc_cntr = (gpc_cntr & dptc_data->dptccr); @@ -145,7 +149,8 @@ static irqreturn_t dptc_irq(int irq, void *dev_id) dptccr = (dptccr & ~(dptc_data->dptc_enable_bit)) | (dptc_data->irq_mask); dptccr = (dptccr & ~(dptc_data->dptc_nvcr_bit)); - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + + dptc_data->dptccr_reg_addr); if (drv_data->turbo_mode_active == 1) schedule_delayed_work(&drv_data->dptc_work, 0); @@ -162,7 +167,8 @@ static void dptc_workqueue_handler(struct work_struct *work1) struct dptc_device *drv_data = container_of(dptc_work_tmp, struct dptc_device, dptc_work); struct mxc_dptc_data *dptc_data = drv_data->dptc_platform_data; - u32 dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + u32 dptccr = __raw_readl(drv_data->membase + + dptc_data->dptccr_reg_addr); switch (drv_data->ptvai) { case DPTC_PTVAI_DECREASE: @@ -193,7 +199,7 @@ static void dptc_workqueue_handler(struct work_struct *work1) /* Enable DPTC and unmask its interrupt */ dptccr = (dptccr & ~(dptc_data->irq_mask)) | dptc_data->dptc_nvcr_bit | dptc_data->dptc_enable_bit; - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + dptc_data->dptccr_reg_addr); } /* Start DPTC unconditionally */ @@ -228,12 +234,12 @@ static int start_dptc(struct device *dev) dptc_data->gpc_cntr_reg_addr); } - dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + dptccr = __raw_readl(drv_data->membase + dptc_data->dptccr_reg_addr); /* Enable DPTC and unmask its interrupt */ dptccr = ((dptccr & ~(dptc_data->irq_mask)) | dptc_data->enable_config); - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + dptc_data->dptccr_reg_addr); spin_unlock_irqrestore(&drv_data->lock, flags); @@ -257,13 +263,13 @@ static void stop_dptc(struct device *dev) struct dptc_device *drv_data = dev->driver_data; u32 dptccr; - dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + dptccr = __raw_readl(drv_data->membase + dptc_data->dptccr_reg_addr); /* disable DPTC and mask its interrupt */ dptccr = ((dptccr & ~(dptc_data->dptc_enable_bit)) | dptc_data->irq_mask) & (~dptc_data->dptc_nvcr_bit); - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + dptc_data->dptccr_reg_addr); /* Restore Turbo Mode voltage to highest wp */ update_dptc_wp(drv_data, 0); @@ -304,12 +310,12 @@ void dptc_suspend(int id) if (!drv_data->dptc_is_active) return; - dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + dptccr = __raw_readl(drv_data->membase + dptc_data->dptccr_reg_addr); /* Disable DPTC and mask its interrupt */ dptccr = (dptccr & ~(dptc_data->dptc_enable_bit)) | dptc_data->irq_mask; - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + dptc_data->dptccr_reg_addr); } EXPORT_SYMBOL(dptc_suspend); @@ -344,20 +350,20 @@ void dptc_resume(int id) return; __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr0, - dptc_data->dcvr0_reg_addr); + drv_data->membase + dptc_data->dcvr0_reg_addr); __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr1, - dptc_data->dcvr0_reg_addr + 0x4); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0x4); __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr2, - dptc_data->dcvr0_reg_addr + 0x8); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0x8); __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr3, - dptc_data->dcvr0_reg_addr + 0xC); + drv_data->membase + dptc_data->dcvr0_reg_addr + 0xC); - dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + dptccr = __raw_readl(drv_data->membase + dptc_data->dptccr_reg_addr); /* Enable DPTC and unmask its interrupt */ dptccr = (dptccr & ~(dptc_data->irq_mask)) | dptc_data->dptc_enable_bit; - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, drv_data->membase + dptc_data->dptccr_reg_addr); } EXPORT_SYMBOL(dptc_resume); @@ -426,7 +432,6 @@ static DEVICE_ATTR(enable, 0644, dptc_show, dptc_store); */ static int __devinit mxc_dptc_probe(struct platform_device *pdev) { - struct dptc_device *dptc_device_data; int ret = 0; struct resource *res; u32 dptccr = 0; @@ -449,13 +454,16 @@ static int __devinit mxc_dptc_probe(struct platform_device *pdev) goto err1; } + dptc_device_data->membase = ioremap(res->start, + res->end - res->start + 1); + /* * Request the DPTC interrupt */ dptc_device_data->irq = platform_get_irq(pdev, 0); if (dptc_device_data->irq < 0) { ret = dptc_device_data->irq; - goto err1; + goto err2; } ret = @@ -463,7 +471,7 @@ static int __devinit mxc_dptc_probe(struct platform_device *pdev) pdev->name, &pdev->dev); if (ret) { printk(KERN_ERR "DPTC: Unable to attach to DPTC interrupt\n"); - goto err1; + goto err2; } dptc_device_data->curr_wp = 0; @@ -471,7 +479,8 @@ static int __devinit mxc_dptc_probe(struct platform_device *pdev) dptc_device_data->turbo_mode_active = 0; dptc_device_data->ptvai = 0; - dptccr = __raw_readl(dptc_data->dptccr_reg_addr); + dptccr = __raw_readl(dptc_device_data->membase + + dptc_data->dptccr_reg_addr); printk(KERN_INFO "DPTC mxc_dptc_probe()\n"); @@ -487,32 +496,33 @@ static int __devinit mxc_dptc_probe(struct platform_device *pdev) else printk(KERN_ERR "DPTC: Pointer to DPTC table is NULL\ not started\n"); - goto err1; + goto err3; } dptc_device_data->dptc_reg = regulator_get(NULL, dptc_data->reg_id); if (IS_ERR(dptc_device_data->dptc_reg)) { clk_put(dptc_device_data->dptc_clk); printk(KERN_ERR "%s: failed to get regulator\n", __func__); - goto err1; + goto err3; } INIT_DELAYED_WORK(&dptc_device_data->dptc_work, dptc_workqueue_handler); /* Enable Reference Circuits */ dptccr = (dptccr & ~(dptc_data->dcr_mask)) | dptc_data->init_config; - __raw_writel(dptccr, dptc_data->dptccr_reg_addr); + __raw_writel(dptccr, dptc_device_data->membase + + dptc_data->dptccr_reg_addr); ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (ret) { printk(KERN_ERR "DPTC: Unable to register sysdev entry for dptc"); - goto err1; + goto err3; } if (ret != 0) { printk(KERN_ERR "DPTC: Unable to start"); - goto err1; + goto err3; } dptc_device_data->dptc_clk = clk_get(NULL, dptc_data->clk_id); @@ -529,6 +539,10 @@ static int __devinit mxc_dptc_probe(struct platform_device *pdev) return 0; +err3: + free_irq(dptc_device_data->irq, &pdev->dev); +err2: + iounmap(dptc_device_data->membase); err1: dev_err(&pdev->dev, "Failed to probe DPTC\n"); kfree(dptc_device_data); @@ -607,6 +621,10 @@ static int __init dptc_init(void) static void __exit dptc_cleanup(void) { + free_irq(dptc_device_data->irq, NULL); + iounmap(dptc_device_data->membase); + kfree(dptc_device_data); + /* Unregister the device structure */ platform_driver_unregister(&mxc_dptc_driver); |