Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 192501
b: refs/heads/master
c: 2f60ba7
h: refs/heads/master
i:
  192499: 35afa65
v: v3
  • Loading branch information
Rafael J. Wysocki committed May 10, 2010
1 parent c22216a commit c203d4b
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 70 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ed77134bfccf5e75b6cbadab268e559dbe6a4ebb
refs/heads/master: 2f60ba706bd9af84c4eab704243b262e69556f2e
166 changes: 97 additions & 69 deletions trunk/drivers/i2c/i2c-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,107 +159,131 @@ static void i2c_device_shutdown(struct device *dev)
driver->shutdown(client);
}

#ifdef CONFIG_SUSPEND
static int i2c_device_pm_suspend(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int i2c_legacy_suspend(struct device *dev, pm_message_t mesg)
{
const struct dev_pm_ops *pm;
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;

if (!dev->driver)
if (!client || !dev->driver)
return 0;
pm = dev->driver->pm;
if (!pm || !pm->suspend)
driver = to_i2c_driver(dev->driver);
if (!driver->suspend)
return 0;
return pm->suspend(dev);
return driver->suspend(client, mesg);
}

static int i2c_device_pm_resume(struct device *dev)
static int i2c_legacy_resume(struct device *dev)
{
const struct dev_pm_ops *pm;
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;

if (!dev->driver)
if (!client || !dev->driver)
return 0;
pm = dev->driver->pm;
if (!pm || !pm->resume)
driver = to_i2c_driver(dev->driver);
if (!driver->resume)
return 0;
return pm->resume(dev);
return driver->resume(client);
}
#else
#define i2c_device_pm_suspend NULL
#define i2c_device_pm_resume NULL
#endif

#ifdef CONFIG_PM_RUNTIME
static int i2c_device_runtime_suspend(struct device *dev)
static int i2c_device_pm_suspend(struct device *dev)
{
const struct dev_pm_ops *pm;
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

if (!dev->driver)
return 0;
pm = dev->driver->pm;
if (!pm || !pm->runtime_suspend)
if (pm_runtime_suspended(dev))
return 0;
return pm->runtime_suspend(dev);
}

static int i2c_device_runtime_resume(struct device *dev)
{
const struct dev_pm_ops *pm;
if (pm)
return pm->suspend ? pm->suspend(dev) : 0;

if (!dev->driver)
return 0;
pm = dev->driver->pm;
if (!pm || !pm->runtime_resume)
return 0;
return pm->runtime_resume(dev);
return i2c_legacy_suspend(dev, PMSG_SUSPEND);
}

static int i2c_device_runtime_idle(struct device *dev)
static int i2c_device_pm_resume(struct device *dev)
{
const struct dev_pm_ops *pm = NULL;
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret;

if (dev->driver)
pm = dev->driver->pm;
if (pm && pm->runtime_idle) {
ret = pm->runtime_idle(dev);
if (ret)
return ret;
if (pm)
ret = pm->resume ? pm->resume(dev) : 0;
else
ret = i2c_legacy_resume(dev);

if (!ret) {
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
}

return pm_runtime_suspend(dev);
return ret;
}
#else
#define i2c_device_runtime_suspend NULL
#define i2c_device_runtime_resume NULL
#define i2c_device_runtime_idle NULL
#endif

static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
static int i2c_device_pm_freeze(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

if (!client || !dev->driver)
if (pm_runtime_suspended(dev))
return 0;
driver = to_i2c_driver(dev->driver);
if (!driver->suspend)
return 0;
return driver->suspend(client, mesg);

if (pm)
return pm->freeze ? pm->freeze(dev) : 0;

return i2c_legacy_suspend(dev, PMSG_FREEZE);
}

static int i2c_device_resume(struct device *dev)
static int i2c_device_pm_thaw(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

if (!client || !dev->driver)
if (pm_runtime_suspended(dev))
return 0;
driver = to_i2c_driver(dev->driver);
if (!driver->resume)

if (pm)
return pm->thaw ? pm->thaw(dev) : 0;

return i2c_legacy_resume(dev);
}

static int i2c_device_pm_poweroff(struct device *dev)
{
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

if (pm_runtime_suspended(dev))
return 0;
return driver->resume(client);

if (pm)
return pm->poweroff ? pm->poweroff(dev) : 0;

return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
}

static int i2c_device_pm_restore(struct device *dev)
{
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret;

if (pm)
ret = pm->restore ? pm->restore(dev) : 0;
else
ret = i2c_legacy_resume(dev);

if (!ret) {
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
}

return ret;
}
#else /* !CONFIG_PM_SLEEP */
#define i2c_device_pm_suspend NULL
#define i2c_device_pm_resume NULL
#define i2c_device_pm_freeze NULL
#define i2c_device_pm_thaw NULL
#define i2c_device_pm_poweroff NULL
#define i2c_device_pm_restore NULL
#endif /* !CONFIG_PM_SLEEP */

static void i2c_client_dev_release(struct device *dev)
{
kfree(to_i2c_client(dev));
Expand Down Expand Up @@ -301,9 +325,15 @@ static const struct attribute_group *i2c_dev_attr_groups[] = {
static const struct dev_pm_ops i2c_device_pm_ops = {
.suspend = i2c_device_pm_suspend,
.resume = i2c_device_pm_resume,
.runtime_suspend = i2c_device_runtime_suspend,
.runtime_resume = i2c_device_runtime_resume,
.runtime_idle = i2c_device_runtime_idle,
.freeze = i2c_device_pm_freeze,
.thaw = i2c_device_pm_thaw,
.poweroff = i2c_device_pm_poweroff,
.restore = i2c_device_pm_restore,
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
};

struct bus_type i2c_bus_type = {
Expand All @@ -312,8 +342,6 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
.pm = &i2c_device_pm_ops,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);
Expand Down
7 changes: 7 additions & 0 deletions trunk/include/linux/pm_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ extern void pm_runtime_enable(struct device *dev);
extern void __pm_runtime_disable(struct device *dev, bool check_resume);
extern void pm_runtime_allow(struct device *dev);
extern void pm_runtime_forbid(struct device *dev);
extern int pm_generic_runtime_idle(struct device *dev);
extern int pm_generic_runtime_suspend(struct device *dev);
extern int pm_generic_runtime_resume(struct device *dev);

static inline bool pm_children_suspended(struct device *dev)
{
Expand Down Expand Up @@ -96,6 +99,10 @@ static inline bool device_run_wake(struct device *dev) { return false; }
static inline void device_set_run_wake(struct device *dev, bool enable) {}
static inline bool pm_runtime_suspended(struct device *dev) { return false; }

static inline int pm_generic_runtime_idle(struct device *dev) { return 0; }
static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }

#endif /* !CONFIG_PM_RUNTIME */

static inline int pm_runtime_get(struct device *dev)
Expand Down

0 comments on commit c203d4b

Please sign in to comment.