Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
common.c
Go to the documentation of this file.
1 /*
2  * drivers/base/power/common.c - Common device power management code.
3  *
4  * Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, 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 
25 {
26  struct pm_subsys_data *psd;
27 
28  psd = kzalloc(sizeof(*psd), GFP_KERNEL);
29  if (!psd)
30  return -ENOMEM;
31 
32  spin_lock_irq(&dev->power.lock);
33 
34  if (dev->power.subsys_data) {
35  dev->power.subsys_data->refcount++;
36  } else {
37  spin_lock_init(&psd->lock);
38  psd->refcount = 1;
39  dev->power.subsys_data = psd;
40  pm_clk_init(dev);
41  psd = NULL;
42  }
43 
44  spin_unlock_irq(&dev->power.lock);
45 
46  /* kfree() verifies that its argument is nonzero. */
47  kfree(psd);
48 
49  return 0;
50 }
52 
62 {
63  struct pm_subsys_data *psd;
64  int ret = 0;
65 
66  spin_lock_irq(&dev->power.lock);
67 
68  psd = dev_to_psd(dev);
69  if (!psd) {
70  ret = -EINVAL;
71  goto out;
72  }
73 
74  if (--psd->refcount == 0) {
75  dev->power.subsys_data = NULL;
76  kfree(psd);
77  ret = 1;
78  }
79 
80  out:
81  spin_unlock_irq(&dev->power.lock);
82 
83  return ret;
84 }