Merge tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[deliverable/linux.git] / drivers / base / power / common.c
1 /*
2 * drivers/base/power/common.c - Common device power management code.
3 *
4 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
5 *
6 * This file is released under the GPLv2.
7 */
8
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/device.h>
12 #include <linux/export.h>
13 #include <linux/slab.h>
14 #include <linux/pm_clock.h>
15
16 /**
17 * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
18 * @dev: Device to handle.
19 *
20 * If power.subsys_data is NULL, point it to a new object, otherwise increment
21 * its reference counter. Return 1 if a new object has been created, otherwise
22 * return 0 or error code.
23 */
24 int dev_pm_get_subsys_data(struct device *dev)
25 {
26 struct pm_subsys_data *psd;
27 int ret = 0;
28
29 psd = kzalloc(sizeof(*psd), GFP_KERNEL);
30 if (!psd)
31 return -ENOMEM;
32
33 spin_lock_irq(&dev->power.lock);
34
35 if (dev->power.subsys_data) {
36 dev->power.subsys_data->refcount++;
37 } else {
38 spin_lock_init(&psd->lock);
39 psd->refcount = 1;
40 dev->power.subsys_data = psd;
41 pm_clk_init(dev);
42 psd = NULL;
43 ret = 1;
44 }
45
46 spin_unlock_irq(&dev->power.lock);
47
48 /* kfree() verifies that its argument is nonzero. */
49 kfree(psd);
50
51 return ret;
52 }
53 EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
54
55 /**
56 * dev_pm_put_subsys_data - Drop reference to power.subsys_data.
57 * @dev: Device to handle.
58 *
59 * If the reference counter of power.subsys_data is zero after dropping the
60 * reference, power.subsys_data is removed. Return 1 if that happens or 0
61 * otherwise.
62 */
63 int dev_pm_put_subsys_data(struct device *dev)
64 {
65 struct pm_subsys_data *psd;
66 int ret = 0;
67
68 spin_lock_irq(&dev->power.lock);
69
70 psd = dev_to_psd(dev);
71 if (!psd) {
72 ret = -EINVAL;
73 goto out;
74 }
75
76 if (--psd->refcount == 0) {
77 dev->power.subsys_data = NULL;
78 kfree(psd);
79 ret = 1;
80 }
81
82 out:
83 spin_unlock_irq(&dev->power.lock);
84
85 return ret;
86 }
87 EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
This page took 0.031804 seconds and 5 git commands to generate.