diff options
Diffstat (limited to 'arch/arm/mach-omap2/smartreflex.c')
-rw-r--r-- | arch/arm/mach-omap2/smartreflex.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index fb7dc52394a8..6a4f6839a7d9 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -17,6 +17,7 @@ * published by the Free Software Foundation. */ +#include <linux/module.h> #include <linux/interrupt.h> #include <linux/clk.h> #include <linux/io.h> @@ -62,6 +63,7 @@ static LIST_HEAD(sr_list); static struct omap_sr_class_data *sr_class; static struct omap_sr_pmic_data *sr_pmic_data; +static struct dentry *sr_dbg_dir; static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value) { @@ -143,7 +145,7 @@ static irqreturn_t sr_interrupt(int irq, void *data) sr_write_reg(sr_info, IRQSTATUS, status); } - if (sr_class->class_type == SR_CLASS2 && sr_class->notify) + if (sr_class->notify) sr_class->notify(sr_info->voltdm, status); return IRQ_HANDLED; @@ -247,7 +249,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr) * driver register and sr device intializtion API's. Only one call * will ultimately succeed. * - * Currently this function registers interrrupt handler for a particular SR + * Currently this function registers interrupt handler for a particular SR * if smartreflex class driver is already registered and has * requested for interrupts and the SR interrupt line in present. */ @@ -258,9 +260,7 @@ static int sr_late_init(struct omap_sr *sr_info) struct resource *mem; int ret = 0; - if (sr_class->class_type == SR_CLASS2 && - sr_class->notify_flags && sr_info->irq) { - + if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); if (name == NULL) { ret = -ENOMEM; @@ -270,6 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info) 0, name, (void *)sr_info); if (ret) goto error; + disable_irq(sr_info->irq); } if (pdata && pdata->enable_on_init) @@ -278,16 +279,16 @@ static int sr_late_init(struct omap_sr *sr_info) return ret; error: - iounmap(sr_info->base); - mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); - list_del(&sr_info->node); - dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" - "interrupt handler. Smartreflex will" - "not function as desired\n", __func__); - kfree(name); - kfree(sr_info); - return ret; + iounmap(sr_info->base); + mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, resource_size(mem)); + list_del(&sr_info->node); + dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" + "interrupt handler. Smartreflex will" + "not function as desired\n", __func__); + kfree(name); + kfree(sr_info); + return ret; } static void sr_v1_disable(struct omap_sr *sr) @@ -622,7 +623,7 @@ void sr_disable(struct voltagedomain *voltdm) sr_v2_disable(sr); } - pm_runtime_put_sync(&sr->pdev->dev); + pm_runtime_put_sync_suspend(&sr->pdev->dev); } /** @@ -808,10 +809,13 @@ static int omap_sr_autocomp_store(void *data, u64 val) return -EINVAL; } - if (!val) - sr_stop_vddautocomp(sr_info); - else - sr_start_vddautocomp(sr_info); + /* control enable/disable only if there is a delta in value */ + if (sr_info->autocomp_active != val) { + if (!val) + sr_stop_vddautocomp(sr_info); + else + sr_start_vddautocomp(sr_info); + } return 0; } @@ -824,9 +828,10 @@ static int __init omap_sr_probe(struct platform_device *pdev) struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; - struct dentry *vdd_dbg_dir, *nvalue_dir; + struct dentry *nvalue_dir; struct omap_volt_data *volt_data; int i, ret = 0; + char *name; if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", @@ -858,6 +863,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(&pdev->dev); + pm_runtime_irq_safe(&pdev->dev); sr_info->pdev = pdev; sr_info->srid = pdev->id; @@ -896,18 +902,25 @@ static int __init omap_sr_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); + if (!sr_dbg_dir) { + sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); + if (!sr_dbg_dir) { + ret = PTR_ERR(sr_dbg_dir); + pr_err("%s:sr debugfs dir creation failed(%d)\n", + __func__, ret); + goto err_iounmap; + } + } - /* - * If the voltage domain debugfs directory is not created, do - * not try to create rest of the debugfs entries. - */ - vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm); - if (!vdd_dbg_dir) { - ret = -EINVAL; + name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); + if (!name) { + dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n", + __func__); + ret = -ENOMEM; goto err_iounmap; } - - sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); + sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); + kfree(name); if (IS_ERR(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); |