Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Mark Brown and committed by
Samuel Ortiz
d450f19e 4c90aa94

+23 -23
+23 -23
drivers/mfd/wm8994-core.c
··· 18 18 #include <linux/i2c.h> 19 19 #include <linux/delay.h> 20 20 #include <linux/mfd/core.h> 21 + #include <linux/pm_runtime.h> 21 22 #include <linux/regulator/consumer.h> 22 23 #include <linux/regulator/machine.h> 23 24 ··· 170 169 EXPORT_SYMBOL_GPL(wm8994_set_bits); 171 170 172 171 static struct mfd_cell wm8994_regulator_devs[] = { 173 - { .name = "wm8994-ldo", .id = 1 }, 174 - { .name = "wm8994-ldo", .id = 2 }, 172 + { 173 + .name = "wm8994-ldo", 174 + .id = 1, 175 + .pm_runtime_no_callbacks = true, 176 + }, 177 + { 178 + .name = "wm8994-ldo", 179 + .id = 2, 180 + .pm_runtime_no_callbacks = true, 181 + }, 175 182 }; 176 183 177 184 static struct resource wm8994_codec_resources[] = { ··· 209 200 .name = "wm8994-gpio", 210 201 .num_resources = ARRAY_SIZE(wm8994_gpio_resources), 211 202 .resources = wm8994_gpio_resources, 203 + .pm_runtime_no_callbacks = true, 212 204 }, 213 205 }; 214 206 ··· 241 231 }; 242 232 243 233 #ifdef CONFIG_PM 244 - static int wm8994_device_suspend(struct device *dev) 234 + static int wm8994_suspend(struct device *dev) 245 235 { 246 236 struct wm8994 *wm8994 = dev_get_drvdata(dev); 247 237 int ret; ··· 271 261 return 0; 272 262 } 273 263 274 - static int wm8994_device_resume(struct device *dev) 264 + static int wm8994_resume(struct device *dev) 275 265 { 276 266 struct wm8994 *wm8994 = dev_get_drvdata(dev); 277 267 int ret; ··· 481 471 goto err_irq; 482 472 } 483 473 474 + pm_runtime_enable(wm8994->dev); 475 + pm_runtime_resume(wm8994->dev); 476 + 484 477 return 0; 485 478 486 479 err_irq: ··· 503 490 504 491 static void wm8994_device_exit(struct wm8994 *wm8994) 505 492 { 493 + pm_runtime_disable(wm8994->dev); 506 494 mfd_remove_devices(wm8994->dev); 507 495 wm8994_irq_exit(wm8994); 508 496 regulator_bulk_disable(wm8994->num_supplies, ··· 587 573 return 0; 588 574 } 589 575 590 - #ifdef CONFIG_PM 591 - static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state) 592 - { 593 - return wm8994_device_suspend(&i2c->dev); 594 - } 595 - 596 - static int wm8994_i2c_resume(struct i2c_client *i2c) 597 - { 598 - return wm8994_device_resume(&i2c->dev); 599 - } 600 - #else 601 - #define wm8994_i2c_suspend NULL 602 - #define wm8994_i2c_resume NULL 603 - #endif 604 - 605 576 static const struct i2c_device_id wm8994_i2c_id[] = { 606 577 { "wm8994", WM8994 }, 607 578 { "wm8958", WM8958 }, ··· 594 595 }; 595 596 MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); 596 597 598 + UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); 599 + 597 600 static struct i2c_driver wm8994_i2c_driver = { 598 601 .driver = { 599 - .name = "wm8994", 600 - .owner = THIS_MODULE, 602 + .name = "wm8994", 603 + .owner = THIS_MODULE, 604 + .pm = &wm8994_pm_ops, 601 605 }, 602 606 .probe = wm8994_i2c_probe, 603 607 .remove = wm8994_i2c_remove, 604 - .suspend = wm8994_i2c_suspend, 605 - .resume = wm8994_i2c_resume, 606 608 .id_table = wm8994_i2c_id, 607 609 }; 608 610