* published by the Free Software Foundation.
*/
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
case ARIZONA_32KZ_MCLK1:
ret = pm_runtime_get_sync(arizona->dev);
if (ret != 0)
- goto out;
+ goto err_ref;
+ ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
+ if (ret != 0)
+ goto err_pm;
+ break;
+ case ARIZONA_32KZ_MCLK2:
+ ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
+ if (ret != 0)
+ goto err_ref;
break;
}
ARIZONA_CLK_32K_ENA);
}
-out:
+err_pm:
+ pm_runtime_put_sync(arizona->dev);
+err_ref:
if (ret != 0)
arizona->clk32k_ref--;
switch (arizona->pdata.clk32k_src) {
case ARIZONA_32KZ_MCLK1:
pm_runtime_put_sync(arizona->dev);
+ clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
+ break;
+ case ARIZONA_32KZ_MCLK2:
+ clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
break;
}
}
return 0;
}
-static int arizona_suspend_late(struct device *dev)
+static int arizona_suspend_noirq(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
{
struct arizona *arizona = dev_get_drvdata(dev);
- dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
+ dev_dbg(arizona->dev, "Resume, reenabling IRQ\n");
enable_irq(arizona->irq);
return 0;
arizona_runtime_resume,
NULL)
SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
-#ifdef CONFIG_PM_SLEEP
- .suspend_late = arizona_suspend_late,
- .resume_noirq = arizona_resume_noirq,
-#endif
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
+ arizona_resume_noirq)
};
EXPORT_SYMBOL_GPL(arizona_pm_ops);
int arizona_dev_init(struct arizona *arizona)
{
+ const char * const mclk_name[] = { "mclk1", "mclk2" };
struct device *dev = arizona->dev;
const char *type_name = NULL;
unsigned int reg, val, mask;
else
arizona_of_get_core_pdata(arizona);
+ BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
+ for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
+ arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
+ if (IS_ERR(arizona->mclk[i])) {
+ dev_info(arizona->dev, "Failed to get %s: %ld\n",
+ mclk_name[i], PTR_ERR(arizona->mclk[i]));
+ arizona->mclk[i] = NULL;
+ }
+ }
+
regcache_cache_only(arizona->regmap, true);
switch (arizona->type) {
default:
dev_err(arizona->dev, "Unknown device type %d\n",
arizona->type);
- return -EINVAL;
+ return -ENODEV;
}
/* Mark DCVDD as external, LDO1 driver will clear if internal */
break;
default:
dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
+ ret = -ENODEV;
goto err_reset;
}
break;
default:
dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+ ret = -ENODEV;
goto err_reset;
}
if (!subdevs) {
dev_err(arizona->dev,
"No kernel support for device ID %x\n", reg);
+ ret = -ENODEV;
goto err_reset;
}