md/raid10: always initialise ->state on newly allocated r10_bio
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / arizona-core.c
index cfc191abae4a5d777c07e59fa26fd78ec4340287..10a0cb90619ae49c2969fe7d123bc7f45733ff8a 100644 (file)
@@ -123,6 +123,8 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
                dev_err(arizona->dev, "AIF2 underclocked\n");
        if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "AIF1 underclocked\n");
+       if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
+               dev_err(arizona->dev, "ISRC3 underclocked\n");
        if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "ISRC2 underclocked\n");
        if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
@@ -192,6 +194,8 @@ static irqreturn_t arizona_overclocked(int irq, void *data)
                dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
        if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
                dev_err(arizona->dev, "DSP1 overclocked\n");
+       if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
+               dev_err(arizona->dev, "ISRC3 overclocked\n");
        if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
                dev_err(arizona->dev, "ISRC2 overclocked\n");
        if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
@@ -497,12 +501,12 @@ const struct dev_pm_ops arizona_pm_ops = {
 EXPORT_SYMBOL_GPL(arizona_pm_ops);
 
 #ifdef CONFIG_OF
-int arizona_of_get_type(struct device *dev)
+unsigned long arizona_of_get_type(struct device *dev)
 {
        const struct of_device_id *id = of_match_device(arizona_of_match, dev);
 
        if (id)
-               return (int)id->data;
+               return (unsigned long)id->data;
        else
                return 0;
 }
@@ -578,17 +582,21 @@ static const struct mfd_cell early_devs[] = {
 };
 
 static const char *wm5102_supplies[] = {
+       "MICVDD",
        "DBVDD2",
        "DBVDD3",
        "CPVDD",
        "SPKVDDL",
        "SPKVDDR",
-       "MICVDD",
 };
 
 static const struct mfd_cell wm5102_devs[] = {
        { .name = "arizona-micsupp" },
-       { .name = "arizona-extcon" },
+       {
+               .name = "arizona-extcon",
+               .parent_supplies = wm5102_supplies,
+               .num_parent_supplies = 1, /* We only need MICVDD */
+       },
        { .name = "arizona-gpio" },
        { .name = "arizona-haptics" },
        { .name = "arizona-pwm" },
@@ -601,7 +609,11 @@ static const struct mfd_cell wm5102_devs[] = {
 
 static const struct mfd_cell wm5110_devs[] = {
        { .name = "arizona-micsupp" },
-       { .name = "arizona-extcon" },
+       {
+               .name = "arizona-extcon",
+               .parent_supplies = wm5102_supplies,
+               .num_parent_supplies = 1, /* We only need MICVDD */
+       },
        { .name = "arizona-gpio" },
        { .name = "arizona-haptics" },
        { .name = "arizona-pwm" },
@@ -613,6 +625,7 @@ static const struct mfd_cell wm5110_devs[] = {
 };
 
 static const char *wm8997_supplies[] = {
+       "MICVDD",
        "DBVDD2",
        "CPVDD",
        "SPKVDD",
@@ -620,7 +633,11 @@ static const char *wm8997_supplies[] = {
 
 static const struct mfd_cell wm8997_devs[] = {
        { .name = "arizona-micsupp" },
-       { .name = "arizona-extcon" },
+       {
+               .name = "arizona-extcon",
+               .parent_supplies = wm8997_supplies,
+               .num_parent_supplies = 1, /* We only need MICVDD */
+       },
        { .name = "arizona-gpio" },
        { .name = "arizona-haptics" },
        { .name = "arizona-pwm" },
@@ -683,7 +700,13 @@ int arizona_dev_init(struct arizona *arizona)
                goto err_early;
        }
 
-       arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
+       /**
+        * Don't use devres here because the only device we have to get
+        * against is the MFD device and DCVDD will likely be supplied by
+        * one of its children. Meaning that the regulator will be
+        * destroyed by the time devres calls regulator put.
+        */
+       arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
        if (IS_ERR(arizona->dcvdd)) {
                ret = PTR_ERR(arizona->dcvdd);
                dev_err(dev, "Failed to request DCVDD: %d\n", ret);
@@ -697,7 +720,7 @@ int arizona_dev_init(struct arizona *arizona)
                                       "arizona /RESET");
                if (ret != 0) {
                        dev_err(dev, "Failed to request /RESET: %d\n", ret);
-                       goto err_early;
+                       goto err_dcvdd;
                }
        }
 
@@ -706,7 +729,7 @@ int arizona_dev_init(struct arizona *arizona)
        if (ret != 0) {
                dev_err(dev, "Failed to enable core supplies: %d\n",
                        ret);
-               goto err_early;
+               goto err_dcvdd;
        }
 
        ret = regulator_enable(arizona->dcvdd);
@@ -1015,6 +1038,8 @@ err_reset:
 err_enable:
        regulator_bulk_disable(arizona->num_core_supplies,
                               arizona->core_supplies);
+err_dcvdd:
+       regulator_put(arizona->dcvdd);
 err_early:
        mfd_remove_devices(dev);
        return ret;
@@ -1023,16 +1048,20 @@ EXPORT_SYMBOL_GPL(arizona_dev_init);
 
 int arizona_dev_exit(struct arizona *arizona)
 {
+       pm_runtime_disable(arizona->dev);
+
+       regulator_disable(arizona->dcvdd);
+       regulator_put(arizona->dcvdd);
+
        mfd_remove_devices(arizona->dev);
        arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
        arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
        arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
-       pm_runtime_disable(arizona->dev);
        arizona_irq_exit(arizona);
        if (arizona->pdata.reset)
                gpio_set_value_cansleep(arizona->pdata.reset, 0);
-       regulator_disable(arizona->dcvdd);
-       regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
+
+       regulator_bulk_disable(arizona->num_core_supplies,
                               arizona->core_supplies);
        return 0;
 }