Merge branches 'dmtimer_precleanup_3.1', 'hwmod_core_cleanup_a_3.1', 'combine_common_...
[pandora-kernel.git] / arch / arm / mach-omap2 / smartreflex.c
index 13e24f9..2ce2fb7 100644 (file)
@@ -143,7 +143,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;
@@ -258,9 +258,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 +268,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 +277,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)
@@ -808,10 +807,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;
 }
@@ -847,6 +849,14 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                goto err_free_devinfo;
        }
 
+       mem = request_mem_region(mem->start, resource_size(mem),
+                                       dev_name(&pdev->dev));
+       if (!mem) {
+               dev_err(&pdev->dev, "%s: no mem region\n", __func__);
+               ret = -EBUSY;
+               goto err_free_devinfo;
+       }
+
        irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
        pm_runtime_enable(&pdev->dev);
@@ -883,7 +893,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                ret = sr_late_init(sr_info);
                if (ret) {
                        pr_warning("%s: Error in SR late init\n", __func__);
-                       goto err_release_region;
+                       return ret;
                }
        }
 
@@ -896,7 +906,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
        if (!vdd_dbg_dir) {
                ret = -EINVAL;
-               goto err_release_region;
+               goto err_iounmap;
        }
 
        sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
@@ -904,7 +914,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
                        __func__);
                ret = PTR_ERR(sr_info->dbg_dir);
-               goto err_release_region;
+               goto err_iounmap;
        }
 
        (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -921,7 +931,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
                        "for n-values\n", __func__);
                ret = PTR_ERR(nvalue_dir);
-               goto err_release_region;
+               goto err_debugfs;
        }
 
        omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
@@ -931,7 +941,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                        "entries for n-values\n",
                        __func__, sr_info->voltdm->name);
                ret = -ENODATA;
-               goto err_release_region;
+               goto err_debugfs;
        }
 
        for (i = 0; i < sr_info->nvalue_count; i++) {
@@ -945,6 +955,11 @@ static int __init omap_sr_probe(struct platform_device *pdev)
 
        return ret;
 
+err_debugfs:
+       debugfs_remove_recursive(sr_info->dbg_dir);
+err_iounmap:
+       list_del(&sr_info->node);
+       iounmap(sr_info->base);
 err_release_region:
        release_mem_region(mem->start, resource_size(mem));
 err_free_devinfo: