aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 23:21:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 23:21:54 -0400
commit2481bc75283ea10e75d5fb1a8b42af363fc4b45c (patch)
tree42dd659a23041a08955aceebab859b616164c2f6 /drivers/pnp/core.c
parent8691c130fae136bb2b7d0554422a2dff4c6ac169 (diff)
parent518b4e272d99dcb13699b229ea480bc845c141f6 (diff)
Merge tag 'pm+acpi-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI updates from Rafael Wysocki: "These are mostly fixes and cleanups all over, although there are a few items that sort of fall into the new feature category. First off, we have new callbacks for PM domains that should help us to handle some issues related to device initialization in a better way. There also is some consolidation in the unified device properties API area allowing us to use that inferface for accessing data coming from platform initialization code in addition to firmware-provided data. We have some new device/CPU IDs in a few drivers, support for new chips and a new cpufreq driver too. Specifics: - Generic PM domains support update including new PM domain callbacks to handle device initialization better (Russell King, Rafael J Wysocki, Kevin Hilman) - Unified device properties API update including a new mechanism for accessing data provided by platform initialization code (Rafael J Wysocki, Adrian Hunter) - ARM cpuidle update including ARM32/ARM64 handling consolidation (Daniel Lezcano) - intel_idle update including support for the Silvermont Core in the Baytrail SOC and for the Airmont Core in the Cherrytrail and Braswell SOCs (Len Brown, Mathias Krause) - New cpufreq driver for Hisilicon ACPU (Leo Yan) - intel_pstate update including support for the Knights Landing chip (Dasaratharaman Chandramouli, Kristen Carlson Accardi) - QorIQ cpufreq driver update (Tang Yuantian, Arnd Bergmann) - powernv cpufreq driver update (Shilpasri G Bhat) - devfreq update including Tegra support changes (Tomeu Vizoso, MyungJoo Ham, Chanwoo Choi) - powercap RAPL (Running-Average Power Limit) driver update including support for Intel Broadwell server chips (Jacob Pan, Mathias Krause) - ACPI device enumeration update related to the handling of the special PRP0001 device ID allowing DT-style 'compatible' property to be used for ACPI device identification (Rafael J Wysocki) - ACPI EC driver update including limited _DEP support (Lan Tianyu, Lv Zheng) - ACPI backlight driver update including a new mechanism to allow native backlight handling to be forced on non-Windows 8 systems and a new quirk for Lenovo Ideapad Z570 (Aaron Lu, Hans de Goede) - New Windows Vista compatibility quirk for Sony VGN-SR19XN (Chen Yu) - Assorted ACPI fixes and cleanups (Aaron Lu, Martin Kepplinger, Masanari Iida, Mika Westerberg, Nan Li, Rafael J Wysocki) - Fixes related to suspend-to-idle for the iTCO watchdog driver and the ACPI core system suspend/resume code (Rafael J Wysocki, Chen Yu) - PM tracing support for the suspend phase of system suspend/resume transitions (Zhonghui Fu) - Configurable delay for the system suspend/resume testing facility (Brian Norris) - PNP subsystem cleanups (Peter Huewe, Rafael J Wysocki)" * tag 'pm+acpi-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (74 commits) ACPI / scan: Fix NULL pointer dereference in acpi_companion_match() ACPI / scan: Rework modalias creation when "compatible" is present intel_idle: mark cpu id array as __initconst powercap / RAPL: mark rapl_ids array as __initconst powercap / RAPL: add ID for Broadwell server intel_pstate: Knights Landing support intel_pstate: remove MSR test cpufreq: fix qoriq uniprocessor build ACPI / scan: Take the PRP0001 position in the list of IDs into account ACPI / scan: Simplify acpi_match_device() ACPI / scan: Generalize of_compatible matching device property: Introduce firmware node type for platform data device property: Make it possible to use secondary firmware nodes PM / watchdog: iTCO: stop watchdog during system suspend cpufreq: hisilicon: add acpu driver ACPI / EC: Call acpi_walk_dep_device_list() after installing EC opregion handler cpufreq: powernv: Report cpu frequency throttling intel_idle: Add support for the Airmont Core in the Cherrytrail and Braswell SOCs intel_idle: Update support for Silvermont Core in Baytrail SOC PM / devfreq: tegra: Register governor on module init ...
Diffstat (limited to 'drivers/pnp/core.c')
-rw-r--r--drivers/pnp/core.c64
1 files changed, 46 insertions, 18 deletions
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index cb6ce42f8e77..b54620e53830 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -9,6 +9,7 @@
9#include <linux/list.h> 9#include <linux/list.h>
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/mutex.h>
12#include <linux/init.h> 13#include <linux/init.h>
13#include <linux/string.h> 14#include <linux/string.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -19,7 +20,7 @@
19 20
20static LIST_HEAD(pnp_protocols); 21static LIST_HEAD(pnp_protocols);
21LIST_HEAD(pnp_global); 22LIST_HEAD(pnp_global);
22DEFINE_SPINLOCK(pnp_lock); 23DEFINE_MUTEX(pnp_lock);
23 24
24/* 25/*
25 * ACPI or PNPBIOS should tell us about all platform devices, so we can 26 * ACPI or PNPBIOS should tell us about all platform devices, so we can
@@ -41,6 +42,13 @@ void *pnp_alloc(long size)
41 return result; 42 return result;
42} 43}
43 44
45static void pnp_remove_protocol(struct pnp_protocol *protocol)
46{
47 mutex_lock(&pnp_lock);
48 list_del(&protocol->protocol_list);
49 mutex_unlock(&pnp_lock);
50}
51
44/** 52/**
45 * pnp_protocol_register - adds a pnp protocol to the pnp layer 53 * pnp_protocol_register - adds a pnp protocol to the pnp layer
46 * @protocol: pointer to the corresponding pnp_protocol structure 54 * @protocol: pointer to the corresponding pnp_protocol structure
@@ -49,13 +57,14 @@ void *pnp_alloc(long size)
49 */ 57 */
50int pnp_register_protocol(struct pnp_protocol *protocol) 58int pnp_register_protocol(struct pnp_protocol *protocol)
51{ 59{
52 int nodenum;
53 struct list_head *pos; 60 struct list_head *pos;
61 int nodenum, ret;
54 62
55 INIT_LIST_HEAD(&protocol->devices); 63 INIT_LIST_HEAD(&protocol->devices);
56 INIT_LIST_HEAD(&protocol->cards); 64 INIT_LIST_HEAD(&protocol->cards);
57 nodenum = 0; 65 nodenum = 0;
58 spin_lock(&pnp_lock); 66
67 mutex_lock(&pnp_lock);
59 68
60 /* assign the lowest unused number */ 69 /* assign the lowest unused number */
61 list_for_each(pos, &pnp_protocols) { 70 list_for_each(pos, &pnp_protocols) {
@@ -66,12 +75,18 @@ int pnp_register_protocol(struct pnp_protocol *protocol)
66 } 75 }
67 } 76 }
68 77
69 list_add_tail(&protocol->protocol_list, &pnp_protocols);
70 spin_unlock(&pnp_lock);
71
72 protocol->number = nodenum; 78 protocol->number = nodenum;
73 dev_set_name(&protocol->dev, "pnp%d", nodenum); 79 dev_set_name(&protocol->dev, "pnp%d", nodenum);
74 return device_register(&protocol->dev); 80
81 list_add_tail(&protocol->protocol_list, &pnp_protocols);
82
83 mutex_unlock(&pnp_lock);
84
85 ret = device_register(&protocol->dev);
86 if (ret)
87 pnp_remove_protocol(protocol);
88
89 return ret;
75} 90}
76 91
77/** 92/**
@@ -80,9 +95,7 @@ int pnp_register_protocol(struct pnp_protocol *protocol)
80 */ 95 */
81void pnp_unregister_protocol(struct pnp_protocol *protocol) 96void pnp_unregister_protocol(struct pnp_protocol *protocol)
82{ 97{
83 spin_lock(&pnp_lock); 98 pnp_remove_protocol(protocol);
84 list_del(&protocol->protocol_list);
85 spin_unlock(&pnp_lock);
86 device_unregister(&protocol->dev); 99 device_unregister(&protocol->dev);
87} 100}
88 101
@@ -157,18 +170,36 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
157 return dev; 170 return dev;
158} 171}
159 172
173static void pnp_delist_device(struct pnp_dev *dev)
174{
175 mutex_lock(&pnp_lock);
176 list_del(&dev->global_list);
177 list_del(&dev->protocol_list);
178 mutex_unlock(&pnp_lock);
179}
180
160int __pnp_add_device(struct pnp_dev *dev) 181int __pnp_add_device(struct pnp_dev *dev)
161{ 182{
183 int ret;
184
162 pnp_fixup_device(dev); 185 pnp_fixup_device(dev);
163 dev->status = PNP_READY; 186 dev->status = PNP_READY;
164 spin_lock(&pnp_lock); 187
188 mutex_lock(&pnp_lock);
189
165 list_add_tail(&dev->global_list, &pnp_global); 190 list_add_tail(&dev->global_list, &pnp_global);
166 list_add_tail(&dev->protocol_list, &dev->protocol->devices); 191 list_add_tail(&dev->protocol_list, &dev->protocol->devices);
167 spin_unlock(&pnp_lock); 192
168 if (dev->protocol->can_wakeup) 193 mutex_unlock(&pnp_lock);
194
195 ret = device_register(&dev->dev);
196 if (ret)
197 pnp_delist_device(dev);
198 else if (dev->protocol->can_wakeup)
169 device_set_wakeup_capable(&dev->dev, 199 device_set_wakeup_capable(&dev->dev,
170 dev->protocol->can_wakeup(dev)); 200 dev->protocol->can_wakeup(dev));
171 return device_register(&dev->dev); 201
202 return ret;
172} 203}
173 204
174/* 205/*
@@ -203,10 +234,7 @@ int pnp_add_device(struct pnp_dev *dev)
203 234
204void __pnp_remove_device(struct pnp_dev *dev) 235void __pnp_remove_device(struct pnp_dev *dev)
205{ 236{
206 spin_lock(&pnp_lock); 237 pnp_delist_device(dev);
207 list_del(&dev->global_list);
208 list_del(&dev->protocol_list);
209 spin_unlock(&pnp_lock);
210 device_unregister(&dev->dev); 238 device_unregister(&dev->dev);
211} 239}
212 240