提交 d450f19e 编写于 作者: M Mark Brown 提交者: Samuel Ortiz

mfd: Implement runtime PM for WM8994 core driver

Allow the WM8994 to completely power off, including disabling the LDOs
if they are software controlled, when it goes idle. The CODEC subdevice
controls activity for the MFD as a whole.

If the GPIOs need to be used while the device is active runtime PM
should be disabled for the device by machine specific code.
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: NSamuel Ortiz <sameo@linux.intel.com>
上级 4c90aa94
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
...@@ -169,8 +170,16 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, ...@@ -169,8 +170,16 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
EXPORT_SYMBOL_GPL(wm8994_set_bits); EXPORT_SYMBOL_GPL(wm8994_set_bits);
static struct mfd_cell wm8994_regulator_devs[] = { static struct mfd_cell wm8994_regulator_devs[] = {
{ .name = "wm8994-ldo", .id = 1 }, {
{ .name = "wm8994-ldo", .id = 2 }, .name = "wm8994-ldo",
.id = 1,
.pm_runtime_no_callbacks = true,
},
{
.name = "wm8994-ldo",
.id = 2,
.pm_runtime_no_callbacks = true,
},
}; };
static struct resource wm8994_codec_resources[] = { static struct resource wm8994_codec_resources[] = {
...@@ -200,6 +209,7 @@ static struct mfd_cell wm8994_devs[] = { ...@@ -200,6 +209,7 @@ static struct mfd_cell wm8994_devs[] = {
.name = "wm8994-gpio", .name = "wm8994-gpio",
.num_resources = ARRAY_SIZE(wm8994_gpio_resources), .num_resources = ARRAY_SIZE(wm8994_gpio_resources),
.resources = wm8994_gpio_resources, .resources = wm8994_gpio_resources,
.pm_runtime_no_callbacks = true,
}, },
}; };
...@@ -231,7 +241,7 @@ static const char *wm8958_main_supplies[] = { ...@@ -231,7 +241,7 @@ static const char *wm8958_main_supplies[] = {
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int wm8994_device_suspend(struct device *dev) static int wm8994_suspend(struct device *dev)
{ {
struct wm8994 *wm8994 = dev_get_drvdata(dev); struct wm8994 *wm8994 = dev_get_drvdata(dev);
int ret; int ret;
...@@ -261,7 +271,7 @@ static int wm8994_device_suspend(struct device *dev) ...@@ -261,7 +271,7 @@ static int wm8994_device_suspend(struct device *dev)
return 0; return 0;
} }
static int wm8994_device_resume(struct device *dev) static int wm8994_resume(struct device *dev)
{ {
struct wm8994 *wm8994 = dev_get_drvdata(dev); struct wm8994 *wm8994 = dev_get_drvdata(dev);
int ret; int ret;
...@@ -471,6 +481,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) ...@@ -471,6 +481,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
goto err_irq; goto err_irq;
} }
pm_runtime_enable(wm8994->dev);
pm_runtime_resume(wm8994->dev);
return 0; return 0;
err_irq: err_irq:
...@@ -490,6 +503,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) ...@@ -490,6 +503,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
static void wm8994_device_exit(struct wm8994 *wm8994) static void wm8994_device_exit(struct wm8994 *wm8994)
{ {
pm_runtime_disable(wm8994->dev);
mfd_remove_devices(wm8994->dev); mfd_remove_devices(wm8994->dev);
wm8994_irq_exit(wm8994); wm8994_irq_exit(wm8994);
regulator_bulk_disable(wm8994->num_supplies, regulator_bulk_disable(wm8994->num_supplies,
...@@ -573,21 +587,6 @@ static int wm8994_i2c_remove(struct i2c_client *i2c) ...@@ -573,21 +587,6 @@ static int wm8994_i2c_remove(struct i2c_client *i2c)
return 0; return 0;
} }
#ifdef CONFIG_PM
static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state)
{
return wm8994_device_suspend(&i2c->dev);
}
static int wm8994_i2c_resume(struct i2c_client *i2c)
{
return wm8994_device_resume(&i2c->dev);
}
#else
#define wm8994_i2c_suspend NULL
#define wm8994_i2c_resume NULL
#endif
static const struct i2c_device_id wm8994_i2c_id[] = { static const struct i2c_device_id wm8994_i2c_id[] = {
{ "wm8994", WM8994 }, { "wm8994", WM8994 },
{ "wm8958", WM8958 }, { "wm8958", WM8958 },
...@@ -595,15 +594,16 @@ static const struct i2c_device_id wm8994_i2c_id[] = { ...@@ -595,15 +594,16 @@ static const struct i2c_device_id wm8994_i2c_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL);
static struct i2c_driver wm8994_i2c_driver = { static struct i2c_driver wm8994_i2c_driver = {
.driver = { .driver = {
.name = "wm8994", .name = "wm8994",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &wm8994_pm_ops,
}, },
.probe = wm8994_i2c_probe, .probe = wm8994_i2c_probe,
.remove = wm8994_i2c_remove, .remove = wm8994_i2c_remove,
.suspend = wm8994_i2c_suspend,
.resume = wm8994_i2c_resume,
.id_table = wm8994_i2c_id, .id_table = wm8994_i2c_id,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册