diff options
96 files changed, 1797 insertions, 928 deletions
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index 9b121a569ab4..750401f91341 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt | |||
@@ -254,8 +254,13 @@ GPIO support | |||
254 | ~~~~~~~~~~~~ | 254 | ~~~~~~~~~~~~ |
255 | ACPI 5 introduced two new resources to describe GPIO connections: GpioIo | 255 | ACPI 5 introduced two new resources to describe GPIO connections: GpioIo |
256 | and GpioInt. These resources are used be used to pass GPIO numbers used by | 256 | and GpioInt. These resources are used be used to pass GPIO numbers used by |
257 | the device to the driver. For example: | 257 | the device to the driver. ACPI 5.1 extended this with _DSD (Device |
258 | Specific Data) which made it possible to name the GPIOs among other things. | ||
258 | 259 | ||
260 | For example: | ||
261 | |||
262 | Device (DEV) | ||
263 | { | ||
259 | Method (_CRS, 0, NotSerialized) | 264 | Method (_CRS, 0, NotSerialized) |
260 | { | 265 | { |
261 | Name (SBUF, ResourceTemplate() | 266 | Name (SBUF, ResourceTemplate() |
@@ -285,6 +290,18 @@ the device to the driver. For example: | |||
285 | Return (SBUF) | 290 | Return (SBUF) |
286 | } | 291 | } |
287 | 292 | ||
293 | // ACPI 5.1 _DSD used for naming the GPIOs | ||
294 | Name (_DSD, Package () | ||
295 | { | ||
296 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), | ||
297 | Package () | ||
298 | { | ||
299 | Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }}, | ||
300 | Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }}, | ||
301 | } | ||
302 | }) | ||
303 | ... | ||
304 | |||
288 | These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" | 305 | These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" |
289 | specifies the path to the controller. In order to use these GPIOs in Linux | 306 | specifies the path to the controller. In order to use these GPIOs in Linux |
290 | we need to translate them to the corresponding Linux GPIO descriptors. | 307 | we need to translate them to the corresponding Linux GPIO descriptors. |
@@ -300,11 +317,11 @@ a code like this: | |||
300 | 317 | ||
301 | struct gpio_desc *irq_desc, *power_desc; | 318 | struct gpio_desc *irq_desc, *power_desc; |
302 | 319 | ||
303 | irq_desc = gpiod_get_index(dev, NULL, 1); | 320 | irq_desc = gpiod_get(dev, "irq"); |
304 | if (IS_ERR(irq_desc)) | 321 | if (IS_ERR(irq_desc)) |
305 | /* handle error */ | 322 | /* handle error */ |
306 | 323 | ||
307 | power_desc = gpiod_get_index(dev, NULL, 0); | 324 | power_desc = gpiod_get(dev, "power"); |
308 | if (IS_ERR(power_desc)) | 325 | if (IS_ERR(power_desc)) |
309 | /* handle error */ | 326 | /* handle error */ |
310 | 327 | ||
@@ -313,6 +330,9 @@ a code like this: | |||
313 | There are also devm_* versions of these functions which release the | 330 | There are also devm_* versions of these functions which release the |
314 | descriptors once the device is released. | 331 | descriptors once the device is released. |
315 | 332 | ||
333 | See Documentation/acpi/gpio-properties.txt for more information about the | ||
334 | _DSD binding related to GPIOs. | ||
335 | |||
316 | MFD devices | 336 | MFD devices |
317 | ~~~~~~~~~~~ | 337 | ~~~~~~~~~~~ |
318 | The MFD devices register their children as platform devices. For the child | 338 | The MFD devices register their children as platform devices. For the child |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 327556349757..491bbd104b06 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -3477,6 +3477,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3477 | improve throughput, but will also increase the | 3477 | improve throughput, but will also increase the |
3478 | amount of memory reserved for use by the client. | 3478 | amount of memory reserved for use by the client. |
3479 | 3479 | ||
3480 | suspend.pm_test_delay= | ||
3481 | [SUSPEND] | ||
3482 | Sets the number of seconds to remain in a suspend test | ||
3483 | mode before resuming the system (see | ||
3484 | /sys/power/pm_test). Only available when CONFIG_PM_DEBUG | ||
3485 | is set. Default value is 5. | ||
3486 | |||
3480 | swapaccount=[0|1] | 3487 | swapaccount=[0|1] |
3481 | [KNL] Enable accounting of swap in memory resource | 3488 | [KNL] Enable accounting of swap in memory resource |
3482 | controller if no parameter or 1 is given or disable | 3489 | controller if no parameter or 1 is given or disable |
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt index edeecd447d23..b96098ccfe69 100644 --- a/Documentation/power/basic-pm-debugging.txt +++ b/Documentation/power/basic-pm-debugging.txt | |||
@@ -75,12 +75,14 @@ you should do the following: | |||
75 | # echo platform > /sys/power/disk | 75 | # echo platform > /sys/power/disk |
76 | # echo disk > /sys/power/state | 76 | # echo disk > /sys/power/state |
77 | 77 | ||
78 | Then, the kernel will try to freeze processes, suspend devices, wait 5 seconds, | 78 | Then, the kernel will try to freeze processes, suspend devices, wait a few |
79 | resume devices and thaw processes. If "platform" is written to | 79 | seconds (5 by default, but configurable by the suspend.pm_test_delay module |
80 | parameter), resume devices and thaw processes. If "platform" is written to | ||
80 | /sys/power/pm_test , then after suspending devices the kernel will additionally | 81 | /sys/power/pm_test , then after suspending devices the kernel will additionally |
81 | invoke the global control methods (eg. ACPI global control methods) used to | 82 | invoke the global control methods (eg. ACPI global control methods) used to |
82 | prepare the platform firmware for hibernation. Next, it will wait 5 seconds and | 83 | prepare the platform firmware for hibernation. Next, it will wait a |
83 | invoke the platform (eg. ACPI) global methods used to cancel hibernation etc. | 84 | configurable number of seconds and invoke the platform (eg. ACPI) global |
85 | methods used to cancel hibernation etc. | ||
84 | 86 | ||
85 | Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal | 87 | Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal |
86 | hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test | 88 | hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test |
diff --git a/MAINTAINERS b/MAINTAINERS index 283d1145e6d8..40eaa356e355 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4331,6 +4331,15 @@ S: Supported | |||
4331 | F: drivers/phy/ | 4331 | F: drivers/phy/ |
4332 | F: include/linux/phy/ | 4332 | F: include/linux/phy/ |
4333 | 4333 | ||
4334 | GENERIC PM DOMAINS | ||
4335 | M: "Rafael J. Wysocki" <rjw@rjwysocki.net> | ||
4336 | M: Kevin Hilman <khilman@kernel.org> | ||
4337 | M: Ulf Hansson <ulf.hansson@linaro.org> | ||
4338 | L: linux-pm@vger.kernel.org | ||
4339 | S: Supported | ||
4340 | F: drivers/base/power/domain*.c | ||
4341 | F: include/linux/pm_domain.h | ||
4342 | |||
4334 | GENERIC UIO DRIVER FOR PCI DEVICES | 4343 | GENERIC UIO DRIVER FOR PCI DEVICES |
4335 | M: "Michael S. Tsirkin" <mst@redhat.com> | 4344 | M: "Michael S. Tsirkin" <mst@redhat.com> |
4336 | L: kvm@vger.kernel.org | 4345 | L: kvm@vger.kernel.org |
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index af319ac4960c..0f8424924902 100644 --- a/arch/arm/include/asm/cpuidle.h +++ b/arch/arm/include/asm/cpuidle.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __ASM_ARM_CPUIDLE_H | 1 | #ifndef __ASM_ARM_CPUIDLE_H |
2 | #define __ASM_ARM_CPUIDLE_H | 2 | #define __ASM_ARM_CPUIDLE_H |
3 | 3 | ||
4 | #include <asm/proc-fns.h> | ||
5 | |||
4 | #ifdef CONFIG_CPU_IDLE | 6 | #ifdef CONFIG_CPU_IDLE |
5 | extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, | 7 | extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, |
6 | struct cpuidle_driver *drv, int index); | 8 | struct cpuidle_driver *drv, int index); |
@@ -25,4 +27,25 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, | |||
25 | */ | 27 | */ |
26 | #define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) | 28 | #define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) |
27 | 29 | ||
30 | struct device_node; | ||
31 | |||
32 | struct cpuidle_ops { | ||
33 | int (*suspend)(int cpu, unsigned long arg); | ||
34 | int (*init)(struct device_node *, int cpu); | ||
35 | }; | ||
36 | |||
37 | struct of_cpuidle_method { | ||
38 | const char *method; | ||
39 | struct cpuidle_ops *ops; | ||
40 | }; | ||
41 | |||
42 | #define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \ | ||
43 | static const struct of_cpuidle_method __cpuidle_method_of_table_##name \ | ||
44 | __used __section(__cpuidle_method_of_table) \ | ||
45 | = { .method = _method, .ops = _ops } | ||
46 | |||
47 | extern int arm_cpuidle_suspend(int index); | ||
48 | |||
49 | extern int arm_cpuidle_init(int cpu); | ||
50 | |||
28 | #endif | 51 | #endif |
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index 89545f6c8403..318da33465f4 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c | |||
@@ -10,8 +10,28 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/cpuidle.h> | 12 | #include <linux/cpuidle.h> |
13 | #include <asm/proc-fns.h> | 13 | #include <linux/of.h> |
14 | #include <linux/of_device.h> | ||
15 | #include <asm/cpuidle.h> | ||
14 | 16 | ||
17 | extern struct of_cpuidle_method __cpuidle_method_of_table[]; | ||
18 | |||
19 | static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel | ||
20 | __used __section(__cpuidle_method_of_table_end); | ||
21 | |||
22 | static struct cpuidle_ops cpuidle_ops[NR_CPUS]; | ||
23 | |||
24 | /** | ||
25 | * arm_cpuidle_simple_enter() - a wrapper to cpu_do_idle() | ||
26 | * @dev: not used | ||
27 | * @drv: not used | ||
28 | * @index: not used | ||
29 | * | ||
30 | * A trivial wrapper to allow the cpu_do_idle function to be assigned as a | ||
31 | * cpuidle callback by matching the function signature. | ||
32 | * | ||
33 | * Returns the index passed as parameter | ||
34 | */ | ||
15 | int arm_cpuidle_simple_enter(struct cpuidle_device *dev, | 35 | int arm_cpuidle_simple_enter(struct cpuidle_device *dev, |
16 | struct cpuidle_driver *drv, int index) | 36 | struct cpuidle_driver *drv, int index) |
17 | { | 37 | { |
@@ -19,3 +39,114 @@ int arm_cpuidle_simple_enter(struct cpuidle_device *dev, | |||
19 | 39 | ||
20 | return index; | 40 | return index; |
21 | } | 41 | } |
42 | |||
43 | /** | ||
44 | * arm_cpuidle_suspend() - function to enter low power idle states | ||
45 | * @index: an integer used as an identifier for the low level PM callbacks | ||
46 | * | ||
47 | * This function calls the underlying arch specific low level PM code as | ||
48 | * registered at the init time. | ||
49 | * | ||
50 | * Returns -EOPNOTSUPP if no suspend callback is defined, the result of the | ||
51 | * callback otherwise. | ||
52 | */ | ||
53 | int arm_cpuidle_suspend(int index) | ||
54 | { | ||
55 | int ret = -EOPNOTSUPP; | ||
56 | int cpu = smp_processor_id(); | ||
57 | |||
58 | if (cpuidle_ops[cpu].suspend) | ||
59 | ret = cpuidle_ops[cpu].suspend(cpu, index); | ||
60 | |||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * arm_cpuidle_get_ops() - find a registered cpuidle_ops by name | ||
66 | * @method: the method name | ||
67 | * | ||
68 | * Search in the __cpuidle_method_of_table array the cpuidle ops matching the | ||
69 | * method name. | ||
70 | * | ||
71 | * Returns a struct cpuidle_ops pointer, NULL if not found. | ||
72 | */ | ||
73 | static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method) | ||
74 | { | ||
75 | struct of_cpuidle_method *m = __cpuidle_method_of_table; | ||
76 | |||
77 | for (; m->method; m++) | ||
78 | if (!strcmp(m->method, method)) | ||
79 | return m->ops; | ||
80 | |||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * arm_cpuidle_read_ops() - Initialize the cpuidle ops with the device tree | ||
86 | * @dn: a pointer to a struct device node corresponding to a cpu node | ||
87 | * @cpu: the cpu identifier | ||
88 | * | ||
89 | * Get the method name defined in the 'enable-method' property, retrieve the | ||
90 | * associated cpuidle_ops and do a struct copy. This copy is needed because all | ||
91 | * cpuidle_ops are tagged __initdata and will be unloaded after the init | ||
92 | * process. | ||
93 | * | ||
94 | * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if | ||
95 | * no cpuidle_ops is registered for the 'enable-method'. | ||
96 | */ | ||
97 | static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) | ||
98 | { | ||
99 | const char *enable_method; | ||
100 | struct cpuidle_ops *ops; | ||
101 | |||
102 | enable_method = of_get_property(dn, "enable-method", NULL); | ||
103 | if (!enable_method) | ||
104 | return -ENOENT; | ||
105 | |||
106 | ops = arm_cpuidle_get_ops(enable_method); | ||
107 | if (!ops) { | ||
108 | pr_warn("%s: unsupported enable-method property: %s\n", | ||
109 | dn->full_name, enable_method); | ||
110 | return -EOPNOTSUPP; | ||
111 | } | ||
112 | |||
113 | cpuidle_ops[cpu] = *ops; /* structure copy */ | ||
114 | |||
115 | pr_notice("cpuidle: enable-method property '%s'" | ||
116 | " found operations\n", enable_method); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * arm_cpuidle_init() - Initialize cpuidle_ops for a specific cpu | ||
123 | * @cpu: the cpu to be initialized | ||
124 | * | ||
125 | * Initialize the cpuidle ops with the device for the cpu and then call | ||
126 | * the cpu's idle initialization callback. This may fail if the underlying HW | ||
127 | * is not operational. | ||
128 | * | ||
129 | * Returns: | ||
130 | * 0 on success, | ||
131 | * -ENODEV if it fails to find the cpu node in the device tree, | ||
132 | * -EOPNOTSUPP if it does not find a registered cpuidle_ops for this cpu, | ||
133 | * -ENOENT if it fails to find an 'enable-method' property, | ||
134 | * -ENXIO if the HW reports a failure or a misconfiguration, | ||
135 | * -ENOMEM if the HW report an memory allocation failure | ||
136 | */ | ||
137 | int __init arm_cpuidle_init(int cpu) | ||
138 | { | ||
139 | struct device_node *cpu_node = of_cpu_device_node_get(cpu); | ||
140 | int ret; | ||
141 | |||
142 | if (!cpu_node) | ||
143 | return -ENODEV; | ||
144 | |||
145 | ret = arm_cpuidle_read_ops(cpu_node, cpu); | ||
146 | if (!ret && cpuidle_ops[cpu].init) | ||
147 | ret = cpuidle_ops[cpu].init(cpu_node, cpu); | ||
148 | |||
149 | of_node_put(cpu_node); | ||
150 | |||
151 | return ret; | ||
152 | } | ||
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index e365c1bb1265..306ebc51599a 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/cpuidle.h> | 17 | #include <linux/cpuidle.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include <asm/proc-fns.h> | ||
21 | #include <asm/cpuidle.h> | 20 | #include <asm/cpuidle.h> |
22 | 21 | ||
23 | #include <mach/cpuidle.h> | 22 | #include <mach/cpuidle.h> |
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index d76d08623f9f..8e21ccc1eda2 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/cpuidle.h> | 9 | #include <linux/cpuidle.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <asm/cpuidle.h> | 11 | #include <asm/cpuidle.h> |
12 | #include <asm/proc-fns.h> | ||
13 | 12 | ||
14 | #include "common.h" | 13 | #include "common.h" |
15 | #include "cpuidle.h" | 14 | #include "cpuidle.h" |
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index 7d92e6584551..5742a9fd1ef2 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/cpuidle.h> | 9 | #include <linux/cpuidle.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <asm/cpuidle.h> | 11 | #include <asm/cpuidle.h> |
12 | #include <asm/proc-fns.h> | ||
13 | 12 | ||
14 | #include "common.h" | 13 | #include "common.h" |
15 | #include "cpuidle.h" | 14 | #include "cpuidle.h" |
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index 5a36722b089d..2c9f1a8bf245 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/cpu_pm.h> | 10 | #include <linux/cpu_pm.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <asm/cpuidle.h> | 12 | #include <asm/cpuidle.h> |
13 | #include <asm/proc-fns.h> | ||
14 | #include <asm/suspend.h> | 13 | #include <asm/suspend.h> |
15 | 14 | ||
16 | #include "common.h" | 15 | #include "common.h" |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 57d429830e09..4b8e9f4d59ea 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/tick.h> | 17 | #include <linux/tick.h> |
18 | 18 | ||
19 | #include <asm/cpuidle.h> | 19 | #include <asm/cpuidle.h> |
20 | #include <asm/proc-fns.h> | ||
21 | 20 | ||
22 | #include "common.h" | 21 | #include "common.h" |
23 | #include "pm.h" | 22 | #include "pm.h" |
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c index 2eb072440dfa..93aa8cb70195 100644 --- a/arch/arm/mach-s3c64xx/cpuidle.c +++ b/arch/arm/mach-s3c64xx/cpuidle.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/export.h> | 16 | #include <linux/export.h> |
17 | #include <linux/time.h> | 17 | #include <linux/time.h> |
18 | 18 | ||
19 | #include <asm/proc-fns.h> | 19 | #include <asm/cpuidle.h> |
20 | 20 | ||
21 | #include <mach/map.h> | 21 | #include <mach/map.h> |
22 | 22 | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c index 48844ae6c3a1..88de2dce2e87 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra20.c +++ b/arch/arm/mach-tegra/cpuidle-tegra20.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | 28 | ||
29 | #include <asm/cpuidle.h> | 29 | #include <asm/cpuidle.h> |
30 | #include <asm/proc-fns.h> | ||
31 | #include <asm/smp_plat.h> | 30 | #include <asm/smp_plat.h> |
32 | #include <asm/suspend.h> | 31 | #include <asm/suspend.h> |
33 | 32 | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c index 84d809a3cba3..4dbe1dae937c 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | 28 | ||
29 | #include <asm/cpuidle.h> | 29 | #include <asm/cpuidle.h> |
30 | #include <asm/proc-fns.h> | ||
31 | #include <asm/smp_plat.h> | 30 | #include <asm/smp_plat.h> |
32 | #include <asm/suspend.h> | 31 | #include <asm/suspend.h> |
33 | 32 | ||
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index be1f12a5a5f0..af6a452b1aac 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -48,7 +48,7 @@ CONFIG_CMDLINE="console=ttyAMA0" | |||
48 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 48 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
49 | CONFIG_COMPAT=y | 49 | CONFIG_COMPAT=y |
50 | CONFIG_CPU_IDLE=y | 50 | CONFIG_CPU_IDLE=y |
51 | CONFIG_ARM64_CPUIDLE=y | 51 | CONFIG_ARM_CPUIDLE=y |
52 | CONFIG_NET=y | 52 | CONFIG_NET=y |
53 | CONFIG_PACKET=y | 53 | CONFIG_PACKET=y |
54 | CONFIG_UNIX=y | 54 | CONFIG_UNIX=y |
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h index c60643f14cda..141b2fcabaa6 100644 --- a/arch/arm64/include/asm/cpuidle.h +++ b/arch/arm64/include/asm/cpuidle.h | |||
@@ -4,10 +4,10 @@ | |||
4 | #include <asm/proc-fns.h> | 4 | #include <asm/proc-fns.h> |
5 | 5 | ||
6 | #ifdef CONFIG_CPU_IDLE | 6 | #ifdef CONFIG_CPU_IDLE |
7 | extern int cpu_init_idle(unsigned int cpu); | 7 | extern int arm_cpuidle_init(unsigned int cpu); |
8 | extern int cpu_suspend(unsigned long arg); | 8 | extern int cpu_suspend(unsigned long arg); |
9 | #else | 9 | #else |
10 | static inline int cpu_init_idle(unsigned int cpu) | 10 | static inline int arm_cpuidle_init(unsigned int cpu) |
11 | { | 11 | { |
12 | return -EOPNOTSUPP; | 12 | return -EOPNOTSUPP; |
13 | } | 13 | } |
@@ -17,5 +17,8 @@ static inline int cpu_suspend(unsigned long arg) | |||
17 | return -EOPNOTSUPP; | 17 | return -EOPNOTSUPP; |
18 | } | 18 | } |
19 | #endif | 19 | #endif |
20 | 20 | static inline int arm_cpuidle_suspend(int index) | |
21 | { | ||
22 | return cpu_suspend(index); | ||
23 | } | ||
21 | #endif | 24 | #endif |
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index 5c0896647fd1..a78143a5c99f 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <asm/cpuidle.h> | 15 | #include <asm/cpuidle.h> |
16 | #include <asm/cpu_ops.h> | 16 | #include <asm/cpu_ops.h> |
17 | 17 | ||
18 | int cpu_init_idle(unsigned int cpu) | 18 | int arm_cpuidle_init(unsigned int cpu) |
19 | { | 19 | { |
20 | int ret = -EOPNOTSUPP; | 20 | int ret = -EOPNOTSUPP; |
21 | struct device_node *cpu_node = of_cpu_device_node_get(cpu); | 21 | struct device_node *cpu_node = of_cpu_device_node_get(cpu); |
diff --git a/arch/x86/include/asm/resume-trace.h b/arch/x86/include/asm/pm-trace.h index 3ff1c2cb1da5..7b7ac42c3661 100644 --- a/arch/x86/include/asm/resume-trace.h +++ b/arch/x86/include/asm/pm-trace.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef _ASM_X86_RESUME_TRACE_H | 1 | #ifndef _ASM_X86_PM_TRACE_H |
2 | #define _ASM_X86_RESUME_TRACE_H | 2 | #define _ASM_X86_PM_TRACE_H |
3 | 3 | ||
4 | #include <asm/asm.h> | 4 | #include <asm/asm.h> |
5 | 5 | ||
@@ -14,8 +14,10 @@ do { \ | |||
14 | ".previous" \ | 14 | ".previous" \ |
15 | :"=r" (tracedata) \ | 15 | :"=r" (tracedata) \ |
16 | : "i" (__LINE__), "i" (__FILE__)); \ | 16 | : "i" (__LINE__), "i" (__FILE__)); \ |
17 | generate_resume_trace(tracedata, user); \ | 17 | generate_pm_trace(tracedata, user); \ |
18 | } \ | 18 | } \ |
19 | } while (0) | 19 | } while (0) |
20 | 20 | ||
21 | #endif /* _ASM_X86_RESUME_TRACE_H */ | 21 | #define TRACE_SUSPEND(user) TRACE_RESUME(user) |
22 | |||
23 | #endif /* _ASM_X86_PM_TRACE_H */ | ||
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1284138e42ab..4bf75597f732 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -102,7 +102,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
102 | pdevinfo.id = -1; | 102 | pdevinfo.id = -1; |
103 | pdevinfo.res = resources; | 103 | pdevinfo.res = resources; |
104 | pdevinfo.num_res = count; | 104 | pdevinfo.num_res = count; |
105 | pdevinfo.acpi_node.companion = adev; | 105 | pdevinfo.fwnode = acpi_fwnode_handle(adev); |
106 | pdevinfo.dma_mask = DMA_BIT_MASK(32); | 106 | pdevinfo.dma_mask = DMA_BIT_MASK(32); |
107 | pdev = platform_device_register_full(&pdevinfo); | 107 | pdev = platform_device_register_full(&pdevinfo); |
108 | if (IS_ERR(pdev)) | 108 | if (IS_ERR(pdev)) |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 672263a3832c..63d43677f644 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -531,8 +531,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
531 | battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && | 531 | battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && |
532 | (s16)(battery->rate_now) < 0) { | 532 | (s16)(battery->rate_now) < 0) { |
533 | battery->rate_now = abs((s16)battery->rate_now); | 533 | battery->rate_now = abs((s16)battery->rate_now); |
534 | printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate" | 534 | printk_once(KERN_WARNING FW_BUG |
535 | " invalid.\n"); | 535 | "battery: (dis)charge rate invalid.\n"); |
536 | } | 536 | } |
537 | 537 | ||
538 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) | 538 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 9b693d54c743..1d1791935c31 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -215,6 +215,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
215 | }, | 215 | }, |
216 | { | 216 | { |
217 | .callback = dmi_disable_osi_vista, | 217 | .callback = dmi_disable_osi_vista, |
218 | .ident = "VGN-SR19XN", | ||
219 | .matches = { | ||
220 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
221 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), | ||
222 | }, | ||
223 | }, | ||
224 | { | ||
225 | .callback = dmi_disable_osi_vista, | ||
218 | .ident = "Toshiba Satellite L355", | 226 | .ident = "Toshiba Satellite L355", |
219 | .matches = { | 227 | .matches = { |
220 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 228 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index d9339b442a4e..a688aa243f6c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -615,7 +615,7 @@ void acpi_dock_add(struct acpi_device *adev) | |||
615 | memset(&pdevinfo, 0, sizeof(pdevinfo)); | 615 | memset(&pdevinfo, 0, sizeof(pdevinfo)); |
616 | pdevinfo.name = "dock"; | 616 | pdevinfo.name = "dock"; |
617 | pdevinfo.id = dock_station_count; | 617 | pdevinfo.id = dock_station_count; |
618 | pdevinfo.acpi_node.companion = adev; | 618 | pdevinfo.fwnode = acpi_fwnode_handle(adev); |
619 | pdevinfo.data = &ds; | 619 | pdevinfo.data = &ds; |
620 | pdevinfo.size_data = sizeof(ds); | 620 | pdevinfo.size_data = sizeof(ds); |
621 | dd = platform_device_register_full(&pdevinfo); | 621 | dd = platform_device_register_full(&pdevinfo); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a8dd2f763382..220d6406c9e9 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -137,6 +137,50 @@ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | |||
137 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ | 137 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ |
138 | 138 | ||
139 | /* -------------------------------------------------------------------------- | 139 | /* -------------------------------------------------------------------------- |
140 | * Logging/Debugging | ||
141 | * -------------------------------------------------------------------------- */ | ||
142 | |||
143 | /* | ||
144 | * Splitters used by the developers to track the boundary of the EC | ||
145 | * handling processes. | ||
146 | */ | ||
147 | #ifdef DEBUG | ||
148 | #define EC_DBG_SEP " " | ||
149 | #define EC_DBG_DRV "+++++" | ||
150 | #define EC_DBG_STM "=====" | ||
151 | #define EC_DBG_REQ "*****" | ||
152 | #define EC_DBG_EVT "#####" | ||
153 | #else | ||
154 | #define EC_DBG_SEP "" | ||
155 | #define EC_DBG_DRV | ||
156 | #define EC_DBG_STM | ||
157 | #define EC_DBG_REQ | ||
158 | #define EC_DBG_EVT | ||
159 | #endif | ||
160 | |||
161 | #define ec_log_raw(fmt, ...) \ | ||
162 | pr_info(fmt "\n", ##__VA_ARGS__) | ||
163 | #define ec_dbg_raw(fmt, ...) \ | ||
164 | pr_debug(fmt "\n", ##__VA_ARGS__) | ||
165 | #define ec_log(filter, fmt, ...) \ | ||
166 | ec_log_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__) | ||
167 | #define ec_dbg(filter, fmt, ...) \ | ||
168 | ec_dbg_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__) | ||
169 | |||
170 | #define ec_log_drv(fmt, ...) \ | ||
171 | ec_log(EC_DBG_DRV, fmt, ##__VA_ARGS__) | ||
172 | #define ec_dbg_drv(fmt, ...) \ | ||
173 | ec_dbg(EC_DBG_DRV, fmt, ##__VA_ARGS__) | ||
174 | #define ec_dbg_stm(fmt, ...) \ | ||
175 | ec_dbg(EC_DBG_STM, fmt, ##__VA_ARGS__) | ||
176 | #define ec_dbg_req(fmt, ...) \ | ||
177 | ec_dbg(EC_DBG_REQ, fmt, ##__VA_ARGS__) | ||
178 | #define ec_dbg_evt(fmt, ...) \ | ||
179 | ec_dbg(EC_DBG_EVT, fmt, ##__VA_ARGS__) | ||
180 | #define ec_dbg_ref(ec, fmt, ...) \ | ||
181 | ec_dbg_raw("%lu: " fmt, ec->reference_count, ## __VA_ARGS__) | ||
182 | |||
183 | /* -------------------------------------------------------------------------- | ||
140 | * Device Flags | 184 | * Device Flags |
141 | * -------------------------------------------------------------------------- */ | 185 | * -------------------------------------------------------------------------- */ |
142 | 186 | ||
@@ -159,14 +203,14 @@ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | |||
159 | { | 203 | { |
160 | u8 x = inb(ec->command_addr); | 204 | u8 x = inb(ec->command_addr); |
161 | 205 | ||
162 | pr_debug("EC_SC(R) = 0x%2.2x " | 206 | ec_dbg_raw("EC_SC(R) = 0x%2.2x " |
163 | "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", | 207 | "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d", |
164 | x, | 208 | x, |
165 | !!(x & ACPI_EC_FLAG_SCI), | 209 | !!(x & ACPI_EC_FLAG_SCI), |
166 | !!(x & ACPI_EC_FLAG_BURST), | 210 | !!(x & ACPI_EC_FLAG_BURST), |
167 | !!(x & ACPI_EC_FLAG_CMD), | 211 | !!(x & ACPI_EC_FLAG_CMD), |
168 | !!(x & ACPI_EC_FLAG_IBF), | 212 | !!(x & ACPI_EC_FLAG_IBF), |
169 | !!(x & ACPI_EC_FLAG_OBF)); | 213 | !!(x & ACPI_EC_FLAG_OBF)); |
170 | return x; | 214 | return x; |
171 | } | 215 | } |
172 | 216 | ||
@@ -175,20 +219,20 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | |||
175 | u8 x = inb(ec->data_addr); | 219 | u8 x = inb(ec->data_addr); |
176 | 220 | ||
177 | ec->curr->timestamp = jiffies; | 221 | ec->curr->timestamp = jiffies; |
178 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); | 222 | ec_dbg_raw("EC_DATA(R) = 0x%2.2x", x); |
179 | return x; | 223 | return x; |
180 | } | 224 | } |
181 | 225 | ||
182 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 226 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
183 | { | 227 | { |
184 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); | 228 | ec_dbg_raw("EC_SC(W) = 0x%2.2x", command); |
185 | outb(command, ec->command_addr); | 229 | outb(command, ec->command_addr); |
186 | ec->curr->timestamp = jiffies; | 230 | ec->curr->timestamp = jiffies; |
187 | } | 231 | } |
188 | 232 | ||
189 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 233 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
190 | { | 234 | { |
191 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); | 235 | ec_dbg_raw("EC_DATA(W) = 0x%2.2x", data); |
192 | outb(data, ec->data_addr); | 236 | outb(data, ec->data_addr); |
193 | ec->curr->timestamp = jiffies; | 237 | ec->curr->timestamp = jiffies; |
194 | } | 238 | } |
@@ -240,7 +284,7 @@ static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) | |||
240 | * software need to manually trigger a pseudo GPE event on | 284 | * software need to manually trigger a pseudo GPE event on |
241 | * EN=1 writes. | 285 | * EN=1 writes. |
242 | */ | 286 | */ |
243 | pr_debug("***** Polling quirk *****\n"); | 287 | ec_dbg_raw("Polling quirk"); |
244 | advance_transaction(ec); | 288 | advance_transaction(ec); |
245 | } | 289 | } |
246 | } | 290 | } |
@@ -299,7 +343,7 @@ static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag) | |||
299 | { | 343 | { |
300 | if (!test_bit(flag, &ec->flags)) { | 344 | if (!test_bit(flag, &ec->flags)) { |
301 | acpi_ec_disable_gpe(ec, false); | 345 | acpi_ec_disable_gpe(ec, false); |
302 | pr_debug("+++++ Polling enabled +++++\n"); | 346 | ec_dbg_drv("Polling enabled"); |
303 | set_bit(flag, &ec->flags); | 347 | set_bit(flag, &ec->flags); |
304 | } | 348 | } |
305 | } | 349 | } |
@@ -309,7 +353,7 @@ static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) | |||
309 | if (test_bit(flag, &ec->flags)) { | 353 | if (test_bit(flag, &ec->flags)) { |
310 | clear_bit(flag, &ec->flags); | 354 | clear_bit(flag, &ec->flags); |
311 | acpi_ec_enable_gpe(ec, false); | 355 | acpi_ec_enable_gpe(ec, false); |
312 | pr_debug("+++++ Polling disabled +++++\n"); | 356 | ec_dbg_drv("Polling disabled"); |
313 | } | 357 | } |
314 | } | 358 | } |
315 | 359 | ||
@@ -335,7 +379,7 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) | |||
335 | static void acpi_ec_submit_query(struct acpi_ec *ec) | 379 | static void acpi_ec_submit_query(struct acpi_ec *ec) |
336 | { | 380 | { |
337 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 381 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
338 | pr_debug("***** Event started *****\n"); | 382 | ec_dbg_req("Event started"); |
339 | schedule_work(&ec->work); | 383 | schedule_work(&ec->work); |
340 | } | 384 | } |
341 | } | 385 | } |
@@ -344,7 +388,7 @@ static void acpi_ec_complete_query(struct acpi_ec *ec) | |||
344 | { | 388 | { |
345 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | 389 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { |
346 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 390 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
347 | pr_debug("***** Event stopped *****\n"); | 391 | ec_dbg_req("Event stopped"); |
348 | } | 392 | } |
349 | } | 393 | } |
350 | 394 | ||
@@ -366,8 +410,8 @@ static void advance_transaction(struct acpi_ec *ec) | |||
366 | u8 status; | 410 | u8 status; |
367 | bool wakeup = false; | 411 | bool wakeup = false; |
368 | 412 | ||
369 | pr_debug("===== %s (%d) =====\n", | 413 | ec_dbg_stm("%s (%d)", in_interrupt() ? "IRQ" : "TASK", |
370 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); | 414 | smp_processor_id()); |
371 | /* | 415 | /* |
372 | * By always clearing STS before handling all indications, we can | 416 | * By always clearing STS before handling all indications, we can |
373 | * ensure a hardware STS 0->1 change after this clearing can always | 417 | * ensure a hardware STS 0->1 change after this clearing can always |
@@ -390,8 +434,8 @@ static void advance_transaction(struct acpi_ec *ec) | |||
390 | if (t->rlen == t->ri) { | 434 | if (t->rlen == t->ri) { |
391 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 435 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
392 | if (t->command == ACPI_EC_COMMAND_QUERY) | 436 | if (t->command == ACPI_EC_COMMAND_QUERY) |
393 | pr_debug("***** Command(%s) hardware completion *****\n", | 437 | ec_dbg_req("Command(%s) hardware completion", |
394 | acpi_ec_cmd_string(t->command)); | 438 | acpi_ec_cmd_string(t->command)); |
395 | wakeup = true; | 439 | wakeup = true; |
396 | } | 440 | } |
397 | } else | 441 | } else |
@@ -410,8 +454,8 @@ static void advance_transaction(struct acpi_ec *ec) | |||
410 | acpi_ec_complete_query(ec); | 454 | acpi_ec_complete_query(ec); |
411 | t->rdata[t->ri++] = 0x00; | 455 | t->rdata[t->ri++] = 0x00; |
412 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 456 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
413 | pr_debug("***** Command(%s) software completion *****\n", | 457 | ec_dbg_req("Command(%s) software completion", |
414 | acpi_ec_cmd_string(t->command)); | 458 | acpi_ec_cmd_string(t->command)); |
415 | wakeup = true; | 459 | wakeup = true; |
416 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | 460 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
417 | acpi_ec_write_cmd(ec, t->command); | 461 | acpi_ec_write_cmd(ec, t->command); |
@@ -502,21 +546,21 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
502 | ret = -EINVAL; | 546 | ret = -EINVAL; |
503 | goto unlock; | 547 | goto unlock; |
504 | } | 548 | } |
549 | ec_dbg_ref(ec, "Increase command"); | ||
505 | /* following two actions should be kept atomic */ | 550 | /* following two actions should be kept atomic */ |
506 | ec->curr = t; | 551 | ec->curr = t; |
507 | pr_debug("***** Command(%s) started *****\n", | 552 | ec_dbg_req("Command(%s) started", acpi_ec_cmd_string(t->command)); |
508 | acpi_ec_cmd_string(t->command)); | ||
509 | start_transaction(ec); | 553 | start_transaction(ec); |
510 | spin_unlock_irqrestore(&ec->lock, tmp); | 554 | spin_unlock_irqrestore(&ec->lock, tmp); |
511 | ret = ec_poll(ec); | 555 | ret = ec_poll(ec); |
512 | spin_lock_irqsave(&ec->lock, tmp); | 556 | spin_lock_irqsave(&ec->lock, tmp); |
513 | if (t->irq_count == ec_storm_threshold) | 557 | if (t->irq_count == ec_storm_threshold) |
514 | acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); | 558 | acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); |
515 | pr_debug("***** Command(%s) stopped *****\n", | 559 | ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command)); |
516 | acpi_ec_cmd_string(t->command)); | ||
517 | ec->curr = NULL; | 560 | ec->curr = NULL; |
518 | /* Disable GPE for command processing (IBF=0/OBF=1) */ | 561 | /* Disable GPE for command processing (IBF=0/OBF=1) */ |
519 | acpi_ec_complete_request(ec); | 562 | acpi_ec_complete_request(ec); |
563 | ec_dbg_ref(ec, "Decrease command"); | ||
520 | unlock: | 564 | unlock: |
521 | spin_unlock_irqrestore(&ec->lock, tmp); | 565 | spin_unlock_irqrestore(&ec->lock, tmp); |
522 | return ret; | 566 | return ret; |
@@ -676,11 +720,13 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) | |||
676 | 720 | ||
677 | spin_lock_irqsave(&ec->lock, flags); | 721 | spin_lock_irqsave(&ec->lock, flags); |
678 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { | 722 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { |
679 | pr_debug("+++++ Starting EC +++++\n"); | 723 | ec_dbg_drv("Starting EC"); |
680 | /* Enable GPE for event processing (SCI_EVT=1) */ | 724 | /* Enable GPE for event processing (SCI_EVT=1) */ |
681 | if (!resuming) | 725 | if (!resuming) { |
682 | acpi_ec_submit_request(ec); | 726 | acpi_ec_submit_request(ec); |
683 | pr_debug("EC started\n"); | 727 | ec_dbg_ref(ec, "Increase driver"); |
728 | } | ||
729 | ec_log_drv("EC started"); | ||
684 | } | 730 | } |
685 | spin_unlock_irqrestore(&ec->lock, flags); | 731 | spin_unlock_irqrestore(&ec->lock, flags); |
686 | } | 732 | } |
@@ -702,17 +748,19 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | |||
702 | 748 | ||
703 | spin_lock_irqsave(&ec->lock, flags); | 749 | spin_lock_irqsave(&ec->lock, flags); |
704 | if (acpi_ec_started(ec)) { | 750 | if (acpi_ec_started(ec)) { |
705 | pr_debug("+++++ Stopping EC +++++\n"); | 751 | ec_dbg_drv("Stopping EC"); |
706 | set_bit(EC_FLAGS_STOPPED, &ec->flags); | 752 | set_bit(EC_FLAGS_STOPPED, &ec->flags); |
707 | spin_unlock_irqrestore(&ec->lock, flags); | 753 | spin_unlock_irqrestore(&ec->lock, flags); |
708 | wait_event(ec->wait, acpi_ec_stopped(ec)); | 754 | wait_event(ec->wait, acpi_ec_stopped(ec)); |
709 | spin_lock_irqsave(&ec->lock, flags); | 755 | spin_lock_irqsave(&ec->lock, flags); |
710 | /* Disable GPE for event processing (SCI_EVT=1) */ | 756 | /* Disable GPE for event processing (SCI_EVT=1) */ |
711 | if (!suspending) | 757 | if (!suspending) { |
712 | acpi_ec_complete_request(ec); | 758 | acpi_ec_complete_request(ec); |
759 | ec_dbg_ref(ec, "Decrease driver"); | ||
760 | } | ||
713 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | 761 | clear_bit(EC_FLAGS_STARTED, &ec->flags); |
714 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | 762 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); |
715 | pr_debug("EC stopped\n"); | 763 | ec_log_drv("EC stopped"); |
716 | } | 764 | } |
717 | spin_unlock_irqrestore(&ec->lock, flags); | 765 | spin_unlock_irqrestore(&ec->lock, flags); |
718 | } | 766 | } |
@@ -824,12 +872,12 @@ static void acpi_ec_run(void *cxt) | |||
824 | 872 | ||
825 | if (!handler) | 873 | if (!handler) |
826 | return; | 874 | return; |
827 | pr_debug("##### Query(0x%02x) started #####\n", handler->query_bit); | 875 | ec_dbg_evt("Query(0x%02x) started", handler->query_bit); |
828 | if (handler->func) | 876 | if (handler->func) |
829 | handler->func(handler->data); | 877 | handler->func(handler->data); |
830 | else if (handler->handle) | 878 | else if (handler->handle) |
831 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 879 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
832 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); | 880 | ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); |
833 | acpi_ec_put_query_handler(handler); | 881 | acpi_ec_put_query_handler(handler); |
834 | } | 882 | } |
835 | 883 | ||
@@ -861,8 +909,8 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) | |||
861 | if (value == handler->query_bit) { | 909 | if (value == handler->query_bit) { |
862 | /* have custom handler for this bit */ | 910 | /* have custom handler for this bit */ |
863 | handler = acpi_ec_get_query_handler(handler); | 911 | handler = acpi_ec_get_query_handler(handler); |
864 | pr_debug("##### Query(0x%02x) scheduled #####\n", | 912 | ec_dbg_evt("Query(0x%02x) scheduled", |
865 | handler->query_bit); | 913 | handler->query_bit); |
866 | status = acpi_os_execute((handler->func) ? | 914 | status = acpi_os_execute((handler->func) ? |
867 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 915 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
868 | acpi_ec_run, handler); | 916 | acpi_ec_run, handler); |
@@ -1099,6 +1147,9 @@ static int acpi_ec_add(struct acpi_device *device) | |||
1099 | 1147 | ||
1100 | ret = ec_install_handlers(ec); | 1148 | ret = ec_install_handlers(ec); |
1101 | 1149 | ||
1150 | /* Reprobe devices depending on the EC */ | ||
1151 | acpi_walk_dep_device_list(ec->handle); | ||
1152 | |||
1102 | /* EC is fully operational, allow queries */ | 1153 | /* EC is fully operational, allow queries */ |
1103 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 1154 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
1104 | 1155 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index f774c65ecb8b..39c485b0c25c 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) | |||
168 | unsigned int node_id; | 168 | unsigned int node_id; |
169 | int retval = -EINVAL; | 169 | int retval = -EINVAL; |
170 | 170 | ||
171 | if (ACPI_COMPANION(dev)) { | 171 | if (has_acpi_companion(dev)) { |
172 | if (acpi_dev) { | 172 | if (acpi_dev) { |
173 | dev_warn(dev, "ACPI companion already set\n"); | 173 | dev_warn(dev, "ACPI companion already set\n"); |
174 | return -EINVAL; | 174 | return -EINVAL; |
@@ -220,7 +220,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) | |||
220 | list_add(&physical_node->node, physnode_list); | 220 | list_add(&physical_node->node, physnode_list); |
221 | acpi_dev->physical_node_count++; | 221 | acpi_dev->physical_node_count++; |
222 | 222 | ||
223 | if (!ACPI_COMPANION(dev)) | 223 | if (!has_acpi_companion(dev)) |
224 | ACPI_COMPANION_SET(dev, acpi_dev); | 224 | ACPI_COMPANION_SET(dev, acpi_dev); |
225 | 225 | ||
226 | acpi_physnode_link_name(physical_node_name, node_id); | 226 | acpi_physnode_link_name(physical_node_name, node_id); |
diff --git a/drivers/acpi/pmic/intel_pmic_crc.c b/drivers/acpi/pmic/intel_pmic_crc.c index ef7d8ff95abe..42df46a86c25 100644 --- a/drivers/acpi/pmic/intel_pmic_crc.c +++ b/drivers/acpi/pmic/intel_pmic_crc.c | |||
@@ -207,5 +207,5 @@ static int __init intel_crc_pmic_opregion_driver_init(void) | |||
207 | } | 207 | } |
208 | module_init(intel_crc_pmic_opregion_driver_init); | 208 | module_init(intel_crc_pmic_opregion_driver_init); |
209 | 209 | ||
210 | MODULE_DESCRIPTION("CrystalCove ACPI opration region driver"); | 210 | MODULE_DESCRIPTION("CrystalCove ACPI operation region driver"); |
211 | MODULE_LICENSE("GPL"); | 211 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bbca7830e18a..69bc0d888c01 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -114,7 +114,12 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, | |||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | /* | 117 | /** |
118 | * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent | ||
119 | * @acpi_dev: ACPI device object. | ||
120 | * @modalias: Buffer to print into. | ||
121 | * @size: Size of the buffer. | ||
122 | * | ||
118 | * Creates hid/cid(s) string needed for modalias and uevent | 123 | * Creates hid/cid(s) string needed for modalias and uevent |
119 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: | 124 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: |
120 | * char *modalias: "acpi:IBM0001:ACPI0001" | 125 | * char *modalias: "acpi:IBM0001:ACPI0001" |
@@ -122,68 +127,98 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, | |||
122 | * -EINVAL: output error | 127 | * -EINVAL: output error |
123 | * -ENOMEM: output is truncated | 128 | * -ENOMEM: output is truncated |
124 | */ | 129 | */ |
125 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | 130 | static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, |
126 | int size) | 131 | int size) |
127 | { | 132 | { |
128 | int len; | 133 | int len; |
129 | int count; | 134 | int count; |
130 | struct acpi_hardware_id *id; | 135 | struct acpi_hardware_id *id; |
131 | 136 | ||
132 | if (list_empty(&acpi_dev->pnp.ids)) | ||
133 | return 0; | ||
134 | |||
135 | /* | 137 | /* |
136 | * If the device has PRP0001 we expose DT compatible modalias | 138 | * Since we skip PRP0001 from the modalias below, 0 should be returned |
137 | * instead in form of of:NnameTCcompatible. | 139 | * if PRP0001 is the only ACPI/PNP ID in the device's list. |
138 | */ | 140 | */ |
139 | if (acpi_dev->data.of_compatible) { | 141 | count = 0; |
140 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; | 142 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) |
141 | const union acpi_object *of_compatible, *obj; | 143 | if (strcmp(id->id, "PRP0001")) |
142 | int i, nval; | 144 | count++; |
143 | char *c; | ||
144 | |||
145 | acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); | ||
146 | /* DT strings are all in lower case */ | ||
147 | for (c = buf.pointer; *c != '\0'; c++) | ||
148 | *c = tolower(*c); | ||
149 | |||
150 | len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); | ||
151 | ACPI_FREE(buf.pointer); | ||
152 | |||
153 | of_compatible = acpi_dev->data.of_compatible; | ||
154 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
155 | nval = of_compatible->package.count; | ||
156 | obj = of_compatible->package.elements; | ||
157 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
158 | nval = 1; | ||
159 | obj = of_compatible; | ||
160 | } | ||
161 | for (i = 0; i < nval; i++, obj++) { | ||
162 | count = snprintf(&modalias[len], size, "C%s", | ||
163 | obj->string.pointer); | ||
164 | if (count < 0) | ||
165 | return -EINVAL; | ||
166 | if (count >= size) | ||
167 | return -ENOMEM; | ||
168 | |||
169 | len += count; | ||
170 | size -= count; | ||
171 | } | ||
172 | } else { | ||
173 | len = snprintf(modalias, size, "acpi:"); | ||
174 | size -= len; | ||
175 | 145 | ||
176 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | 146 | if (!count) |
177 | count = snprintf(&modalias[len], size, "%s:", id->id); | 147 | return 0; |
178 | if (count < 0) | 148 | |
179 | return -EINVAL; | 149 | len = snprintf(modalias, size, "acpi:"); |
180 | if (count >= size) | 150 | if (len <= 0) |
181 | return -ENOMEM; | 151 | return len; |
182 | len += count; | 152 | |
183 | size -= count; | 153 | size -= len; |
184 | } | 154 | |
155 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | ||
156 | if (!strcmp(id->id, "PRP0001")) | ||
157 | continue; | ||
158 | |||
159 | count = snprintf(&modalias[len], size, "%s:", id->id); | ||
160 | if (count < 0) | ||
161 | return -EINVAL; | ||
162 | |||
163 | if (count >= size) | ||
164 | return -ENOMEM; | ||
165 | |||
166 | len += count; | ||
167 | size -= count; | ||
168 | } | ||
169 | modalias[len] = '\0'; | ||
170 | return len; | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * create_of_modalias - Creates DT compatible string for modalias and uevent | ||
175 | * @acpi_dev: ACPI device object. | ||
176 | * @modalias: Buffer to print into. | ||
177 | * @size: Size of the buffer. | ||
178 | * | ||
179 | * Expose DT compatible modalias as of:NnameTCcompatible. This function should | ||
180 | * only be called for devices having PRP0001 in their list of ACPI/PNP IDs. | ||
181 | */ | ||
182 | static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, | ||
183 | int size) | ||
184 | { | ||
185 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; | ||
186 | const union acpi_object *of_compatible, *obj; | ||
187 | int len, count; | ||
188 | int i, nval; | ||
189 | char *c; | ||
190 | |||
191 | acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); | ||
192 | /* DT strings are all in lower case */ | ||
193 | for (c = buf.pointer; *c != '\0'; c++) | ||
194 | *c = tolower(*c); | ||
195 | |||
196 | len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); | ||
197 | ACPI_FREE(buf.pointer); | ||
198 | |||
199 | if (len <= 0) | ||
200 | return len; | ||
201 | |||
202 | of_compatible = acpi_dev->data.of_compatible; | ||
203 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
204 | nval = of_compatible->package.count; | ||
205 | obj = of_compatible->package.elements; | ||
206 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
207 | nval = 1; | ||
208 | obj = of_compatible; | ||
185 | } | 209 | } |
210 | for (i = 0; i < nval; i++, obj++) { | ||
211 | count = snprintf(&modalias[len], size, "C%s", | ||
212 | obj->string.pointer); | ||
213 | if (count < 0) | ||
214 | return -EINVAL; | ||
186 | 215 | ||
216 | if (count >= size) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | len += count; | ||
220 | size -= count; | ||
221 | } | ||
187 | modalias[len] = '\0'; | 222 | modalias[len] = '\0'; |
188 | return len; | 223 | return len; |
189 | } | 224 | } |
@@ -194,7 +229,8 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
194 | * | 229 | * |
195 | * Check if the given device has an ACPI companion and if that companion has | 230 | * Check if the given device has an ACPI companion and if that companion has |
196 | * a valid list of PNP IDs, and if the device is the first (primary) physical | 231 | * a valid list of PNP IDs, and if the device is the first (primary) physical |
197 | * device associated with it. | 232 | * device associated with it. Return the companion pointer if that's the case |
233 | * or NULL otherwise. | ||
198 | * | 234 | * |
199 | * If multiple physical devices are attached to a single ACPI companion, we need | 235 | * If multiple physical devices are attached to a single ACPI companion, we need |
200 | * to be careful. The usage scenario for this kind of relationship is that all | 236 | * to be careful. The usage scenario for this kind of relationship is that all |
@@ -208,88 +244,129 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
208 | * resources available from it but they will be matched normally using functions | 244 | * resources available from it but they will be matched normally using functions |
209 | * provided by their bus types (and analogously for their modalias). | 245 | * provided by their bus types (and analogously for their modalias). |
210 | */ | 246 | */ |
211 | static bool acpi_companion_match(const struct device *dev) | 247 | static struct acpi_device *acpi_companion_match(const struct device *dev) |
212 | { | 248 | { |
213 | struct acpi_device *adev; | 249 | struct acpi_device *adev; |
214 | bool ret; | 250 | struct mutex *physical_node_lock; |
215 | 251 | ||
216 | adev = ACPI_COMPANION(dev); | 252 | adev = ACPI_COMPANION(dev); |
217 | if (!adev) | 253 | if (!adev) |
218 | return false; | 254 | return NULL; |
219 | 255 | ||
220 | if (list_empty(&adev->pnp.ids)) | 256 | if (list_empty(&adev->pnp.ids)) |
221 | return false; | 257 | return NULL; |
222 | 258 | ||
223 | mutex_lock(&adev->physical_node_lock); | 259 | physical_node_lock = &adev->physical_node_lock; |
260 | mutex_lock(physical_node_lock); | ||
224 | if (list_empty(&adev->physical_node_list)) { | 261 | if (list_empty(&adev->physical_node_list)) { |
225 | ret = false; | 262 | adev = NULL; |
226 | } else { | 263 | } else { |
227 | const struct acpi_device_physical_node *node; | 264 | const struct acpi_device_physical_node *node; |
228 | 265 | ||
229 | node = list_first_entry(&adev->physical_node_list, | 266 | node = list_first_entry(&adev->physical_node_list, |
230 | struct acpi_device_physical_node, node); | 267 | struct acpi_device_physical_node, node); |
231 | ret = node->dev == dev; | 268 | if (node->dev != dev) |
269 | adev = NULL; | ||
232 | } | 270 | } |
233 | mutex_unlock(&adev->physical_node_lock); | 271 | mutex_unlock(physical_node_lock); |
234 | 272 | ||
235 | return ret; | 273 | return adev; |
236 | } | 274 | } |
237 | 275 | ||
238 | /* | 276 | static int __acpi_device_uevent_modalias(struct acpi_device *adev, |
239 | * Creates uevent modalias field for ACPI enumerated devices. | 277 | struct kobj_uevent_env *env) |
240 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
241 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
242 | * "acpi:IBM0001:ACPI0001" | ||
243 | */ | ||
244 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) | ||
245 | { | 278 | { |
246 | int len; | 279 | int len; |
247 | 280 | ||
248 | if (!acpi_companion_match(dev)) | 281 | if (!adev) |
249 | return -ENODEV; | 282 | return -ENODEV; |
250 | 283 | ||
284 | if (list_empty(&adev->pnp.ids)) | ||
285 | return 0; | ||
286 | |||
251 | if (add_uevent_var(env, "MODALIAS=")) | 287 | if (add_uevent_var(env, "MODALIAS=")) |
252 | return -ENOMEM; | 288 | return -ENOMEM; |
253 | len = create_modalias(ACPI_COMPANION(dev), &env->buf[env->buflen - 1], | 289 | |
254 | sizeof(env->buf) - env->buflen); | 290 | len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], |
255 | if (len <= 0) | 291 | sizeof(env->buf) - env->buflen); |
292 | if (len < 0) | ||
293 | return len; | ||
294 | |||
295 | env->buflen += len; | ||
296 | if (!adev->data.of_compatible) | ||
297 | return 0; | ||
298 | |||
299 | if (len > 0 && add_uevent_var(env, "MODALIAS=")) | ||
300 | return -ENOMEM; | ||
301 | |||
302 | len = create_of_modalias(adev, &env->buf[env->buflen - 1], | ||
303 | sizeof(env->buf) - env->buflen); | ||
304 | if (len < 0) | ||
256 | return len; | 305 | return len; |
306 | |||
257 | env->buflen += len; | 307 | env->buflen += len; |
308 | |||
258 | return 0; | 309 | return 0; |
259 | } | 310 | } |
260 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); | ||
261 | 311 | ||
262 | /* | 312 | /* |
263 | * Creates modalias sysfs attribute for ACPI enumerated devices. | 313 | * Creates uevent modalias field for ACPI enumerated devices. |
264 | * Because the other buses does not support ACPI HIDs & CIDs. | 314 | * Because the other buses does not support ACPI HIDs & CIDs. |
265 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | 315 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: |
266 | * "acpi:IBM0001:ACPI0001" | 316 | * "acpi:IBM0001:ACPI0001" |
267 | */ | 317 | */ |
268 | int acpi_device_modalias(struct device *dev, char *buf, int size) | 318 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) |
269 | { | 319 | { |
270 | int len; | 320 | return __acpi_device_uevent_modalias(acpi_companion_match(dev), env); |
321 | } | ||
322 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); | ||
271 | 323 | ||
272 | if (!acpi_companion_match(dev)) | 324 | static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size) |
325 | { | ||
326 | int len, count; | ||
327 | |||
328 | if (!adev) | ||
273 | return -ENODEV; | 329 | return -ENODEV; |
274 | 330 | ||
275 | len = create_modalias(ACPI_COMPANION(dev), buf, size -1); | 331 | if (list_empty(&adev->pnp.ids)) |
276 | if (len <= 0) | 332 | return 0; |
333 | |||
334 | len = create_pnp_modalias(adev, buf, size - 1); | ||
335 | if (len < 0) { | ||
336 | return len; | ||
337 | } else if (len > 0) { | ||
338 | buf[len++] = '\n'; | ||
339 | size -= len; | ||
340 | } | ||
341 | if (!adev->data.of_compatible) | ||
277 | return len; | 342 | return len; |
278 | buf[len++] = '\n'; | 343 | |
344 | count = create_of_modalias(adev, buf + len, size - 1); | ||
345 | if (count < 0) { | ||
346 | return count; | ||
347 | } else if (count > 0) { | ||
348 | len += count; | ||
349 | buf[len++] = '\n'; | ||
350 | } | ||
351 | |||
279 | return len; | 352 | return len; |
280 | } | 353 | } |
354 | |||
355 | /* | ||
356 | * Creates modalias sysfs attribute for ACPI enumerated devices. | ||
357 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
358 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
359 | * "acpi:IBM0001:ACPI0001" | ||
360 | */ | ||
361 | int acpi_device_modalias(struct device *dev, char *buf, int size) | ||
362 | { | ||
363 | return __acpi_device_modalias(acpi_companion_match(dev), buf, size); | ||
364 | } | ||
281 | EXPORT_SYMBOL_GPL(acpi_device_modalias); | 365 | EXPORT_SYMBOL_GPL(acpi_device_modalias); |
282 | 366 | ||
283 | static ssize_t | 367 | static ssize_t |
284 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { | 368 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { |
285 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 369 | return __acpi_device_modalias(to_acpi_device(dev), buf, 1024); |
286 | int len; | ||
287 | |||
288 | len = create_modalias(acpi_dev, buf, 1024); | ||
289 | if (len <= 0) | ||
290 | return len; | ||
291 | buf[len++] = '\n'; | ||
292 | return len; | ||
293 | } | 370 | } |
294 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 371 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
295 | 372 | ||
@@ -894,8 +971,51 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
894 | ACPI Bus operations | 971 | ACPI Bus operations |
895 | -------------------------------------------------------------------------- */ | 972 | -------------------------------------------------------------------------- */ |
896 | 973 | ||
974 | /** | ||
975 | * acpi_of_match_device - Match device object using the "compatible" property. | ||
976 | * @adev: ACPI device object to match. | ||
977 | * @of_match_table: List of device IDs to match against. | ||
978 | * | ||
979 | * If @dev has an ACPI companion which has the special PRP0001 device ID in its | ||
980 | * list of identifiers and a _DSD object with the "compatible" property, use | ||
981 | * that property to match against the given list of identifiers. | ||
982 | */ | ||
983 | static bool acpi_of_match_device(struct acpi_device *adev, | ||
984 | const struct of_device_id *of_match_table) | ||
985 | { | ||
986 | const union acpi_object *of_compatible, *obj; | ||
987 | int i, nval; | ||
988 | |||
989 | if (!adev) | ||
990 | return false; | ||
991 | |||
992 | of_compatible = adev->data.of_compatible; | ||
993 | if (!of_match_table || !of_compatible) | ||
994 | return false; | ||
995 | |||
996 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
997 | nval = of_compatible->package.count; | ||
998 | obj = of_compatible->package.elements; | ||
999 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
1000 | nval = 1; | ||
1001 | obj = of_compatible; | ||
1002 | } | ||
1003 | /* Now we can look for the driver DT compatible strings */ | ||
1004 | for (i = 0; i < nval; i++, obj++) { | ||
1005 | const struct of_device_id *id; | ||
1006 | |||
1007 | for (id = of_match_table; id->compatible[0]; id++) | ||
1008 | if (!strcasecmp(obj->string.pointer, id->compatible)) | ||
1009 | return true; | ||
1010 | } | ||
1011 | |||
1012 | return false; | ||
1013 | } | ||
1014 | |||
897 | static const struct acpi_device_id *__acpi_match_device( | 1015 | static const struct acpi_device_id *__acpi_match_device( |
898 | struct acpi_device *device, const struct acpi_device_id *ids) | 1016 | struct acpi_device *device, |
1017 | const struct acpi_device_id *ids, | ||
1018 | const struct of_device_id *of_ids) | ||
899 | { | 1019 | { |
900 | const struct acpi_device_id *id; | 1020 | const struct acpi_device_id *id; |
901 | struct acpi_hardware_id *hwid; | 1021 | struct acpi_hardware_id *hwid; |
@@ -904,14 +1024,27 @@ static const struct acpi_device_id *__acpi_match_device( | |||
904 | * If the device is not present, it is unnecessary to load device | 1024 | * If the device is not present, it is unnecessary to load device |
905 | * driver for it. | 1025 | * driver for it. |
906 | */ | 1026 | */ |
907 | if (!device->status.present) | 1027 | if (!device || !device->status.present) |
908 | return NULL; | 1028 | return NULL; |
909 | 1029 | ||
910 | for (id = ids; id->id[0]; id++) | 1030 | list_for_each_entry(hwid, &device->pnp.ids, list) { |
911 | list_for_each_entry(hwid, &device->pnp.ids, list) | 1031 | /* First, check the ACPI/PNP IDs provided by the caller. */ |
1032 | for (id = ids; id->id[0]; id++) | ||
912 | if (!strcmp((char *) id->id, hwid->id)) | 1033 | if (!strcmp((char *) id->id, hwid->id)) |
913 | return id; | 1034 | return id; |
914 | 1035 | ||
1036 | /* | ||
1037 | * Next, check the special "PRP0001" ID and try to match the | ||
1038 | * "compatible" property if found. | ||
1039 | * | ||
1040 | * The id returned by the below is not valid, but the only | ||
1041 | * caller passing non-NULL of_ids here is only interested in | ||
1042 | * whether or not the return value is NULL. | ||
1043 | */ | ||
1044 | if (!strcmp("PRP0001", hwid->id) | ||
1045 | && acpi_of_match_device(device, of_ids)) | ||
1046 | return id; | ||
1047 | } | ||
915 | return NULL; | 1048 | return NULL; |
916 | } | 1049 | } |
917 | 1050 | ||
@@ -929,68 +1062,26 @@ static const struct acpi_device_id *__acpi_match_device( | |||
929 | const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, | 1062 | const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, |
930 | const struct device *dev) | 1063 | const struct device *dev) |
931 | { | 1064 | { |
932 | struct acpi_device *adev; | 1065 | return __acpi_match_device(acpi_companion_match(dev), ids, NULL); |
933 | acpi_handle handle = ACPI_HANDLE(dev); | ||
934 | |||
935 | if (!ids || !handle || acpi_bus_get_device(handle, &adev)) | ||
936 | return NULL; | ||
937 | |||
938 | if (!acpi_companion_match(dev)) | ||
939 | return NULL; | ||
940 | |||
941 | return __acpi_match_device(adev, ids); | ||
942 | } | 1066 | } |
943 | EXPORT_SYMBOL_GPL(acpi_match_device); | 1067 | EXPORT_SYMBOL_GPL(acpi_match_device); |
944 | 1068 | ||
945 | int acpi_match_device_ids(struct acpi_device *device, | 1069 | int acpi_match_device_ids(struct acpi_device *device, |
946 | const struct acpi_device_id *ids) | 1070 | const struct acpi_device_id *ids) |
947 | { | 1071 | { |
948 | return __acpi_match_device(device, ids) ? 0 : -ENOENT; | 1072 | return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT; |
949 | } | 1073 | } |
950 | EXPORT_SYMBOL(acpi_match_device_ids); | 1074 | EXPORT_SYMBOL(acpi_match_device_ids); |
951 | 1075 | ||
952 | /* Performs match against special "PRP0001" shoehorn ACPI ID */ | ||
953 | static bool acpi_of_driver_match_device(struct device *dev, | ||
954 | const struct device_driver *drv) | ||
955 | { | ||
956 | const union acpi_object *of_compatible, *obj; | ||
957 | struct acpi_device *adev; | ||
958 | int i, nval; | ||
959 | |||
960 | adev = ACPI_COMPANION(dev); | ||
961 | if (!adev) | ||
962 | return false; | ||
963 | |||
964 | of_compatible = adev->data.of_compatible; | ||
965 | if (!drv->of_match_table || !of_compatible) | ||
966 | return false; | ||
967 | |||
968 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
969 | nval = of_compatible->package.count; | ||
970 | obj = of_compatible->package.elements; | ||
971 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
972 | nval = 1; | ||
973 | obj = of_compatible; | ||
974 | } | ||
975 | /* Now we can look for the driver DT compatible strings */ | ||
976 | for (i = 0; i < nval; i++, obj++) { | ||
977 | const struct of_device_id *id; | ||
978 | |||
979 | for (id = drv->of_match_table; id->compatible[0]; id++) | ||
980 | if (!strcasecmp(obj->string.pointer, id->compatible)) | ||
981 | return true; | ||
982 | } | ||
983 | |||
984 | return false; | ||
985 | } | ||
986 | |||
987 | bool acpi_driver_match_device(struct device *dev, | 1076 | bool acpi_driver_match_device(struct device *dev, |
988 | const struct device_driver *drv) | 1077 | const struct device_driver *drv) |
989 | { | 1078 | { |
990 | if (!drv->acpi_match_table) | 1079 | if (!drv->acpi_match_table) |
991 | return acpi_of_driver_match_device(dev, drv); | 1080 | return acpi_of_match_device(ACPI_COMPANION(dev), |
1081 | drv->of_match_table); | ||
992 | 1082 | ||
993 | return !!acpi_match_device(drv->acpi_match_table, dev); | 1083 | return !!__acpi_match_device(acpi_companion_match(dev), |
1084 | drv->acpi_match_table, drv->of_match_table); | ||
994 | } | 1085 | } |
995 | EXPORT_SYMBOL_GPL(acpi_driver_match_device); | 1086 | EXPORT_SYMBOL_GPL(acpi_driver_match_device); |
996 | 1087 | ||
@@ -1031,20 +1122,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) | |||
1031 | 1122 | ||
1032 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 1123 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
1033 | { | 1124 | { |
1034 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 1125 | return __acpi_device_uevent_modalias(to_acpi_device(dev), env); |
1035 | int len; | ||
1036 | |||
1037 | if (list_empty(&acpi_dev->pnp.ids)) | ||
1038 | return 0; | ||
1039 | |||
1040 | if (add_uevent_var(env, "MODALIAS=")) | ||
1041 | return -ENOMEM; | ||
1042 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | ||
1043 | sizeof(env->buf) - env->buflen); | ||
1044 | if (len <= 0) | ||
1045 | return len; | ||
1046 | env->buflen += len; | ||
1047 | return 0; | ||
1048 | } | 1126 | } |
1049 | 1127 | ||
1050 | static void acpi_device_notify(acpi_handle handle, u32 event, void *data) | 1128 | static void acpi_device_notify(acpi_handle handle, u32 event, void *data) |
@@ -1062,10 +1140,10 @@ static void acpi_device_notify_fixed(void *data) | |||
1062 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); | 1140 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); |
1063 | } | 1141 | } |
1064 | 1142 | ||
1065 | static acpi_status acpi_device_fixed_event(void *data) | 1143 | static u32 acpi_device_fixed_event(void *data) |
1066 | { | 1144 | { |
1067 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); | 1145 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); |
1068 | return AE_OK; | 1146 | return ACPI_INTERRUPT_HANDLED; |
1069 | } | 1147 | } |
1070 | 1148 | ||
1071 | static int acpi_device_install_notify_handler(struct acpi_device *device) | 1149 | static int acpi_device_install_notify_handler(struct acpi_device *device) |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 7f251dd1a687..2f0d4db40a9e 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -629,6 +629,7 @@ static int acpi_freeze_begin(void) | |||
629 | 629 | ||
630 | static int acpi_freeze_prepare(void) | 630 | static int acpi_freeze_prepare(void) |
631 | { | 631 | { |
632 | acpi_enable_wakeup_devices(ACPI_STATE_S0); | ||
632 | acpi_enable_all_wakeup_gpes(); | 633 | acpi_enable_all_wakeup_gpes(); |
633 | acpi_os_wait_events_complete(); | 634 | acpi_os_wait_events_complete(); |
634 | enable_irq_wake(acpi_gbl_FADT.sci_interrupt); | 635 | enable_irq_wake(acpi_gbl_FADT.sci_interrupt); |
@@ -637,6 +638,7 @@ static int acpi_freeze_prepare(void) | |||
637 | 638 | ||
638 | static void acpi_freeze_restore(void) | 639 | static void acpi_freeze_restore(void) |
639 | { | 640 | { |
641 | acpi_disable_wakeup_devices(ACPI_STATE_S0); | ||
640 | disable_irq_wake(acpi_gbl_FADT.sci_interrupt); | 642 | disable_irq_wake(acpi_gbl_FADT.sci_interrupt); |
641 | acpi_enable_all_runtime_gpes(); | 643 | acpi_enable_all_runtime_gpes(); |
642 | } | 644 | } |
@@ -806,21 +808,6 @@ static void acpi_sleep_hibernate_setup(void) | |||
806 | static inline void acpi_sleep_hibernate_setup(void) {} | 808 | static inline void acpi_sleep_hibernate_setup(void) {} |
807 | #endif /* !CONFIG_HIBERNATION */ | 809 | #endif /* !CONFIG_HIBERNATION */ |
808 | 810 | ||
809 | int acpi_suspend(u32 acpi_state) | ||
810 | { | ||
811 | suspend_state_t states[] = { | ||
812 | [1] = PM_SUSPEND_STANDBY, | ||
813 | [3] = PM_SUSPEND_MEM, | ||
814 | [5] = PM_SUSPEND_MAX | ||
815 | }; | ||
816 | |||
817 | if (acpi_state < 6 && states[acpi_state]) | ||
818 | return pm_suspend(states[acpi_state]); | ||
819 | if (acpi_state == 4) | ||
820 | return hibernate(); | ||
821 | return -EINVAL; | ||
822 | } | ||
823 | |||
824 | static void acpi_power_off_prepare(void) | 811 | static void acpi_power_off_prepare(void) |
825 | { | 812 | { |
826 | /* Prepare to power off the system */ | 813 | /* Prepare to power off the system */ |
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 0143540a2519..c797ffa568d5 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h | |||
@@ -1,6 +1,4 @@ | |||
1 | 1 | ||
2 | extern int acpi_suspend(u32 state); | ||
3 | |||
4 | extern void acpi_enable_wakeup_devices(u8 sleep_state); | 2 | extern void acpi_enable_wakeup_devices(u8 sleep_state); |
5 | extern void acpi_disable_wakeup_devices(u8 sleep_state); | 3 | extern void acpi_disable_wakeup_devices(u8 sleep_state); |
6 | 4 | ||
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 13e577c80201..0876d77b3206 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -527,7 +527,7 @@ static ssize_t counter_show(struct kobject *kobj, | |||
527 | acpi_irq_not_handled; | 527 | acpi_irq_not_handled; |
528 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = | 528 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = |
529 | acpi_gpe_count; | 529 | acpi_gpe_count; |
530 | size = sprintf(buf, "%8d", all_counters[index].count); | 530 | size = sprintf(buf, "%8u", all_counters[index].count); |
531 | 531 | ||
532 | /* "gpe_all" or "sci" */ | 532 | /* "gpe_all" or "sci" */ |
533 | if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) | 533 | if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 26eb70c8f518..cc79d3fedfb2 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -82,9 +82,15 @@ module_param(allow_duplicates, bool, 0644); | |||
82 | * For Windows 8 systems: used to decide if video module | 82 | * For Windows 8 systems: used to decide if video module |
83 | * should skip registering backlight interface of its own. | 83 | * should skip registering backlight interface of its own. |
84 | */ | 84 | */ |
85 | static int use_native_backlight_param = -1; | 85 | enum { |
86 | NATIVE_BACKLIGHT_NOT_SET = -1, | ||
87 | NATIVE_BACKLIGHT_OFF, | ||
88 | NATIVE_BACKLIGHT_ON, | ||
89 | }; | ||
90 | |||
91 | static int use_native_backlight_param = NATIVE_BACKLIGHT_NOT_SET; | ||
86 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); | 92 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); |
87 | static bool use_native_backlight_dmi = true; | 93 | static int use_native_backlight_dmi = NATIVE_BACKLIGHT_NOT_SET; |
88 | 94 | ||
89 | static int register_count; | 95 | static int register_count; |
90 | static struct mutex video_list_lock; | 96 | static struct mutex video_list_lock; |
@@ -237,15 +243,16 @@ static void acpi_video_switch_brightness(struct work_struct *work); | |||
237 | 243 | ||
238 | static bool acpi_video_use_native_backlight(void) | 244 | static bool acpi_video_use_native_backlight(void) |
239 | { | 245 | { |
240 | if (use_native_backlight_param != -1) | 246 | if (use_native_backlight_param != NATIVE_BACKLIGHT_NOT_SET) |
241 | return use_native_backlight_param; | 247 | return use_native_backlight_param; |
242 | else | 248 | else if (use_native_backlight_dmi != NATIVE_BACKLIGHT_NOT_SET) |
243 | return use_native_backlight_dmi; | 249 | return use_native_backlight_dmi; |
250 | return acpi_osi_is_win8(); | ||
244 | } | 251 | } |
245 | 252 | ||
246 | bool acpi_video_verify_backlight_support(void) | 253 | bool acpi_video_verify_backlight_support(void) |
247 | { | 254 | { |
248 | if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && | 255 | if (acpi_video_use_native_backlight() && |
249 | backlight_device_registered(BACKLIGHT_RAW)) | 256 | backlight_device_registered(BACKLIGHT_RAW)) |
250 | return false; | 257 | return false; |
251 | return acpi_video_backlight_support(); | 258 | return acpi_video_backlight_support(); |
@@ -414,7 +421,13 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d) | |||
414 | 421 | ||
415 | static int __init video_disable_native_backlight(const struct dmi_system_id *d) | 422 | static int __init video_disable_native_backlight(const struct dmi_system_id *d) |
416 | { | 423 | { |
417 | use_native_backlight_dmi = false; | 424 | use_native_backlight_dmi = NATIVE_BACKLIGHT_OFF; |
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int __init video_enable_native_backlight(const struct dmi_system_id *d) | ||
429 | { | ||
430 | use_native_backlight_dmi = NATIVE_BACKLIGHT_ON; | ||
418 | return 0; | 431 | return 0; |
419 | } | 432 | } |
420 | 433 | ||
@@ -559,6 +572,17 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
559 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), | 572 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), |
560 | }, | 573 | }, |
561 | }, | 574 | }, |
575 | |||
576 | /* Non win8 machines which need native backlight nevertheless */ | ||
577 | { | ||
578 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ | ||
579 | .callback = video_enable_native_backlight, | ||
580 | .ident = "Lenovo Ideapad Z570", | ||
581 | .matches = { | ||
582 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
583 | DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), | ||
584 | }, | ||
585 | }, | ||
562 | {} | 586 | {} |
563 | }; | 587 | }; |
564 | 588 | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 27c43499977a..c42feb2bacd0 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -174,14 +174,6 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
174 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), | 174 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), |
175 | }, | 175 | }, |
176 | }, | 176 | }, |
177 | { | ||
178 | .callback = video_detect_force_vendor, | ||
179 | .ident = "Lenovo IdeaPad Z570", | ||
180 | .matches = { | ||
181 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
182 | DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"), | ||
183 | }, | ||
184 | }, | ||
185 | { }, | 177 | { }, |
186 | }; | 178 | }; |
187 | 179 | ||
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index b33d1f99b3a4..994f168b54a8 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c | |||
@@ -128,20 +128,8 @@ static struct pnp_driver isapnp_driver = { | |||
128 | .remove = isapnp_remove_one, | 128 | .remove = isapnp_remove_one, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static int __init isapnp_init(void) | 131 | module_pnp_driver(isapnp_driver); |
132 | { | ||
133 | return pnp_register_driver(&isapnp_driver); | ||
134 | } | ||
135 | |||
136 | static void __exit isapnp_exit(void) | ||
137 | { | ||
138 | pnp_unregister_driver(&isapnp_driver); | ||
139 | } | ||
140 | |||
141 | MODULE_AUTHOR("Alan Cox"); | 132 | MODULE_AUTHOR("Alan Cox"); |
142 | MODULE_DESCRIPTION("low-level driver for ISA PnP ATA"); | 133 | MODULE_DESCRIPTION("low-level driver for ISA PnP ATA"); |
143 | MODULE_LICENSE("GPL"); | 134 | MODULE_LICENSE("GPL"); |
144 | MODULE_VERSION(DRV_VERSION); | 135 | MODULE_VERSION(DRV_VERSION); |
145 | |||
146 | module_init(isapnp_init); | ||
147 | module_exit(isapnp_exit); | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index cadf165651d8..21d13038534e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fwnode.h> | ||
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
@@ -2144,3 +2145,53 @@ define_dev_printk_level(dev_notice, KERN_NOTICE); | |||
2144 | define_dev_printk_level(_dev_info, KERN_INFO); | 2145 | define_dev_printk_level(_dev_info, KERN_INFO); |
2145 | 2146 | ||
2146 | #endif | 2147 | #endif |
2148 | |||
2149 | static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) | ||
2150 | { | ||
2151 | return fwnode && !IS_ERR(fwnode->secondary); | ||
2152 | } | ||
2153 | |||
2154 | /** | ||
2155 | * set_primary_fwnode - Change the primary firmware node of a given device. | ||
2156 | * @dev: Device to handle. | ||
2157 | * @fwnode: New primary firmware node of the device. | ||
2158 | * | ||
2159 | * Set the device's firmware node pointer to @fwnode, but if a secondary | ||
2160 | * firmware node of the device is present, preserve it. | ||
2161 | */ | ||
2162 | void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) | ||
2163 | { | ||
2164 | if (fwnode) { | ||
2165 | struct fwnode_handle *fn = dev->fwnode; | ||
2166 | |||
2167 | if (fwnode_is_primary(fn)) | ||
2168 | fn = fn->secondary; | ||
2169 | |||
2170 | fwnode->secondary = fn; | ||
2171 | dev->fwnode = fwnode; | ||
2172 | } else { | ||
2173 | dev->fwnode = fwnode_is_primary(dev->fwnode) ? | ||
2174 | dev->fwnode->secondary : NULL; | ||
2175 | } | ||
2176 | } | ||
2177 | EXPORT_SYMBOL_GPL(set_primary_fwnode); | ||
2178 | |||
2179 | /** | ||
2180 | * set_secondary_fwnode - Change the secondary firmware node of a given device. | ||
2181 | * @dev: Device to handle. | ||
2182 | * @fwnode: New secondary firmware node of the device. | ||
2183 | * | ||
2184 | * If a primary firmware node of the device is present, set its secondary | ||
2185 | * pointer to @fwnode. Otherwise, set the device's firmware node pointer to | ||
2186 | * @fwnode. | ||
2187 | */ | ||
2188 | void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) | ||
2189 | { | ||
2190 | if (fwnode) | ||
2191 | fwnode->secondary = ERR_PTR(-ENODEV); | ||
2192 | |||
2193 | if (fwnode_is_primary(dev->fwnode)) | ||
2194 | dev->fwnode->secondary = fwnode; | ||
2195 | else | ||
2196 | dev->fwnode = fwnode; | ||
2197 | } | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 49a4a12fafef..e843fdbe4925 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -298,6 +298,12 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
298 | goto probe_failed; | 298 | goto probe_failed; |
299 | } | 299 | } |
300 | 300 | ||
301 | if (dev->pm_domain && dev->pm_domain->activate) { | ||
302 | ret = dev->pm_domain->activate(dev); | ||
303 | if (ret) | ||
304 | goto probe_failed; | ||
305 | } | ||
306 | |||
301 | if (dev->bus->probe) { | 307 | if (dev->bus->probe) { |
302 | ret = dev->bus->probe(dev); | 308 | ret = dev->bus->probe(dev); |
303 | if (ret) | 309 | if (ret) |
@@ -308,6 +314,9 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
308 | goto probe_failed; | 314 | goto probe_failed; |
309 | } | 315 | } |
310 | 316 | ||
317 | if (dev->pm_domain && dev->pm_domain->sync) | ||
318 | dev->pm_domain->sync(dev); | ||
319 | |||
311 | driver_bound(dev); | 320 | driver_bound(dev); |
312 | ret = 1; | 321 | ret = 1; |
313 | pr_debug("bus: '%s': %s: bound device %s to driver %s\n", | 322 | pr_debug("bus: '%s': %s: bound device %s to driver %s\n", |
@@ -319,6 +328,8 @@ probe_failed: | |||
319 | driver_sysfs_remove(dev); | 328 | driver_sysfs_remove(dev); |
320 | dev->driver = NULL; | 329 | dev->driver = NULL; |
321 | dev_set_drvdata(dev, NULL); | 330 | dev_set_drvdata(dev, NULL); |
331 | if (dev->pm_domain && dev->pm_domain->dismiss) | ||
332 | dev->pm_domain->dismiss(dev); | ||
322 | 333 | ||
323 | switch (ret) { | 334 | switch (ret) { |
324 | case -EPROBE_DEFER: | 335 | case -EPROBE_DEFER: |
@@ -529,6 +540,9 @@ static void __device_release_driver(struct device *dev) | |||
529 | devres_release_all(dev); | 540 | devres_release_all(dev); |
530 | dev->driver = NULL; | 541 | dev->driver = NULL; |
531 | dev_set_drvdata(dev, NULL); | 542 | dev_set_drvdata(dev, NULL); |
543 | if (dev->pm_domain && dev->pm_domain->dismiss) | ||
544 | dev->pm_domain->dismiss(dev); | ||
545 | |||
532 | klist_remove(&dev->p->knode_driver); | 546 | klist_remove(&dev->p->knode_driver); |
533 | if (dev->bus) | 547 | if (dev->bus) |
534 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 548 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index e68ab79df28b..ebf034b97278 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -463,7 +463,7 @@ struct platform_device *platform_device_register_full( | |||
463 | goto err_alloc; | 463 | goto err_alloc; |
464 | 464 | ||
465 | pdev->dev.parent = pdevinfo->parent; | 465 | pdev->dev.parent = pdevinfo->parent; |
466 | ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); | 466 | pdev->dev.fwnode = pdevinfo->fwnode; |
467 | 467 | ||
468 | if (pdevinfo->dma_mask) { | 468 | if (pdevinfo->dma_mask) { |
469 | /* | 469 | /* |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 45937f88e77c..2327613d4539 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -68,7 +68,36 @@ static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name) | |||
68 | return genpd; | 68 | return genpd; |
69 | } | 69 | } |
70 | 70 | ||
71 | struct generic_pm_domain *dev_to_genpd(struct device *dev) | 71 | /* |
72 | * Get the generic PM domain for a particular struct device. | ||
73 | * This validates the struct device pointer, the PM domain pointer, | ||
74 | * and checks that the PM domain pointer is a real generic PM domain. | ||
75 | * Any failure results in NULL being returned. | ||
76 | */ | ||
77 | struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev) | ||
78 | { | ||
79 | struct generic_pm_domain *genpd = NULL, *gpd; | ||
80 | |||
81 | if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) | ||
82 | return NULL; | ||
83 | |||
84 | mutex_lock(&gpd_list_lock); | ||
85 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
86 | if (&gpd->domain == dev->pm_domain) { | ||
87 | genpd = gpd; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | mutex_unlock(&gpd_list_lock); | ||
92 | |||
93 | return genpd; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * This should only be used where we are certain that the pm_domain | ||
98 | * attached to the device is a genpd domain. | ||
99 | */ | ||
100 | static struct generic_pm_domain *dev_to_genpd(struct device *dev) | ||
72 | { | 101 | { |
73 | if (IS_ERR_OR_NULL(dev->pm_domain)) | 102 | if (IS_ERR_OR_NULL(dev->pm_domain)) |
74 | return ERR_PTR(-EINVAL); | 103 | return ERR_PTR(-EINVAL); |
@@ -173,8 +202,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd) | |||
173 | genpd->power_on_latency_ns = elapsed_ns; | 202 | genpd->power_on_latency_ns = elapsed_ns; |
174 | genpd->max_off_time_changed = true; | 203 | genpd->max_off_time_changed = true; |
175 | genpd_recalc_cpu_exit_latency(genpd); | 204 | genpd_recalc_cpu_exit_latency(genpd); |
176 | pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", | 205 | pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", |
177 | genpd->name, "on", elapsed_ns); | 206 | genpd->name, "on", elapsed_ns); |
178 | 207 | ||
179 | return ret; | 208 | return ret; |
180 | } | 209 | } |
@@ -199,8 +228,8 @@ static int genpd_power_off(struct generic_pm_domain *genpd) | |||
199 | 228 | ||
200 | genpd->power_off_latency_ns = elapsed_ns; | 229 | genpd->power_off_latency_ns = elapsed_ns; |
201 | genpd->max_off_time_changed = true; | 230 | genpd->max_off_time_changed = true; |
202 | pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", | 231 | pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", |
203 | genpd->name, "off", elapsed_ns); | 232 | genpd->name, "off", elapsed_ns); |
204 | 233 | ||
205 | return ret; | 234 | return ret; |
206 | } | 235 | } |
@@ -1513,9 +1542,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1513 | 1542 | ||
1514 | dev_dbg(dev, "%s()\n", __func__); | 1543 | dev_dbg(dev, "%s()\n", __func__); |
1515 | 1544 | ||
1516 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev) | 1545 | if (!genpd || genpd != pm_genpd_lookup_dev(dev)) |
1517 | || IS_ERR_OR_NULL(dev->pm_domain) | ||
1518 | || pd_to_genpd(dev->pm_domain) != genpd) | ||
1519 | return -EINVAL; | 1546 | return -EINVAL; |
1520 | 1547 | ||
1521 | /* The above validation also means we have existing domain_data. */ | 1548 | /* The above validation also means we have existing domain_data. */ |
@@ -2093,21 +2120,10 @@ EXPORT_SYMBOL_GPL(of_genpd_get_from_provider); | |||
2093 | */ | 2120 | */ |
2094 | static void genpd_dev_pm_detach(struct device *dev, bool power_off) | 2121 | static void genpd_dev_pm_detach(struct device *dev, bool power_off) |
2095 | { | 2122 | { |
2096 | struct generic_pm_domain *pd = NULL, *gpd; | 2123 | struct generic_pm_domain *pd; |
2097 | int ret = 0; | 2124 | int ret = 0; |
2098 | 2125 | ||
2099 | if (!dev->pm_domain) | 2126 | pd = pm_genpd_lookup_dev(dev); |
2100 | return; | ||
2101 | |||
2102 | mutex_lock(&gpd_list_lock); | ||
2103 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
2104 | if (&gpd->domain == dev->pm_domain) { | ||
2105 | pd = gpd; | ||
2106 | break; | ||
2107 | } | ||
2108 | } | ||
2109 | mutex_unlock(&gpd_list_lock); | ||
2110 | |||
2111 | if (!pd) | 2127 | if (!pd) |
2112 | return; | 2128 | return; |
2113 | 2129 | ||
@@ -2130,6 +2146,17 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off) | |||
2130 | genpd_queue_power_off_work(pd); | 2146 | genpd_queue_power_off_work(pd); |
2131 | } | 2147 | } |
2132 | 2148 | ||
2149 | static void genpd_dev_pm_sync(struct device *dev) | ||
2150 | { | ||
2151 | struct generic_pm_domain *pd; | ||
2152 | |||
2153 | pd = dev_to_genpd(dev); | ||
2154 | if (IS_ERR(pd)) | ||
2155 | return; | ||
2156 | |||
2157 | genpd_queue_power_off_work(pd); | ||
2158 | } | ||
2159 | |||
2133 | /** | 2160 | /** |
2134 | * genpd_dev_pm_attach - Attach a device to its PM domain using DT. | 2161 | * genpd_dev_pm_attach - Attach a device to its PM domain using DT. |
2135 | * @dev: Device to attach. | 2162 | * @dev: Device to attach. |
@@ -2196,6 +2223,7 @@ int genpd_dev_pm_attach(struct device *dev) | |||
2196 | } | 2223 | } |
2197 | 2224 | ||
2198 | dev->pm_domain->detach = genpd_dev_pm_detach; | 2225 | dev->pm_domain->detach = genpd_dev_pm_detach; |
2226 | dev->pm_domain->sync = genpd_dev_pm_sync; | ||
2199 | pm_genpd_poweron(pd); | 2227 | pm_genpd_poweron(pd); |
2200 | 2228 | ||
2201 | return 0; | 2229 | return 0; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 9717d5f20139..3d874eca7104 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
26 | #include <linux/resume-trace.h> | 26 | #include <linux/pm-trace.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/async.h> | 29 | #include <linux/async.h> |
@@ -1017,6 +1017,9 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1017 | char *info = NULL; | 1017 | char *info = NULL; |
1018 | int error = 0; | 1018 | int error = 0; |
1019 | 1019 | ||
1020 | TRACE_DEVICE(dev); | ||
1021 | TRACE_SUSPEND(0); | ||
1022 | |||
1020 | if (async_error) | 1023 | if (async_error) |
1021 | goto Complete; | 1024 | goto Complete; |
1022 | 1025 | ||
@@ -1057,6 +1060,7 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1057 | 1060 | ||
1058 | Complete: | 1061 | Complete: |
1059 | complete_all(&dev->power.completion); | 1062 | complete_all(&dev->power.completion); |
1063 | TRACE_SUSPEND(error); | ||
1060 | return error; | 1064 | return error; |
1061 | } | 1065 | } |
1062 | 1066 | ||
@@ -1078,7 +1082,7 @@ static int device_suspend_noirq(struct device *dev) | |||
1078 | { | 1082 | { |
1079 | reinit_completion(&dev->power.completion); | 1083 | reinit_completion(&dev->power.completion); |
1080 | 1084 | ||
1081 | if (pm_async_enabled && dev->power.async_suspend) { | 1085 | if (is_async(dev)) { |
1082 | get_device(dev); | 1086 | get_device(dev); |
1083 | async_schedule(async_suspend_noirq, dev); | 1087 | async_schedule(async_suspend_noirq, dev); |
1084 | return 0; | 1088 | return 0; |
@@ -1157,6 +1161,9 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as | |||
1157 | char *info = NULL; | 1161 | char *info = NULL; |
1158 | int error = 0; | 1162 | int error = 0; |
1159 | 1163 | ||
1164 | TRACE_DEVICE(dev); | ||
1165 | TRACE_SUSPEND(0); | ||
1166 | |||
1160 | __pm_runtime_disable(dev, false); | 1167 | __pm_runtime_disable(dev, false); |
1161 | 1168 | ||
1162 | if (async_error) | 1169 | if (async_error) |
@@ -1198,6 +1205,7 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as | |||
1198 | async_error = error; | 1205 | async_error = error; |
1199 | 1206 | ||
1200 | Complete: | 1207 | Complete: |
1208 | TRACE_SUSPEND(error); | ||
1201 | complete_all(&dev->power.completion); | 1209 | complete_all(&dev->power.completion); |
1202 | return error; | 1210 | return error; |
1203 | } | 1211 | } |
@@ -1219,7 +1227,7 @@ static int device_suspend_late(struct device *dev) | |||
1219 | { | 1227 | { |
1220 | reinit_completion(&dev->power.completion); | 1228 | reinit_completion(&dev->power.completion); |
1221 | 1229 | ||
1222 | if (pm_async_enabled && dev->power.async_suspend) { | 1230 | if (is_async(dev)) { |
1223 | get_device(dev); | 1231 | get_device(dev); |
1224 | async_schedule(async_suspend_late, dev); | 1232 | async_schedule(async_suspend_late, dev); |
1225 | return 0; | 1233 | return 0; |
@@ -1338,6 +1346,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1338 | int error = 0; | 1346 | int error = 0; |
1339 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); | 1347 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); |
1340 | 1348 | ||
1349 | TRACE_DEVICE(dev); | ||
1350 | TRACE_SUSPEND(0); | ||
1351 | |||
1341 | dpm_wait_for_children(dev, async); | 1352 | dpm_wait_for_children(dev, async); |
1342 | 1353 | ||
1343 | if (async_error) | 1354 | if (async_error) |
@@ -1444,6 +1455,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1444 | if (error) | 1455 | if (error) |
1445 | async_error = error; | 1456 | async_error = error; |
1446 | 1457 | ||
1458 | TRACE_SUSPEND(error); | ||
1447 | return error; | 1459 | return error; |
1448 | } | 1460 | } |
1449 | 1461 | ||
@@ -1465,7 +1477,7 @@ static int device_suspend(struct device *dev) | |||
1465 | { | 1477 | { |
1466 | reinit_completion(&dev->power.completion); | 1478 | reinit_completion(&dev->power.completion); |
1467 | 1479 | ||
1468 | if (pm_async_enabled && dev->power.async_suspend) { | 1480 | if (is_async(dev)) { |
1469 | get_device(dev); | 1481 | get_device(dev); |
1470 | async_schedule(async_suspend, dev); | 1482 | async_schedule(async_suspend, dev); |
1471 | return 0; | 1483 | return 0; |
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index d94a1f5121cf..a311cfa4c5bd 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * devices may be working. | 7 | * devices may be working. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/resume-trace.h> | 10 | #include <linux/pm-trace.h> |
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | #include <linux/rtc.h> | 12 | #include <linux/rtc.h> |
13 | 13 | ||
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(set_trace_device); | |||
154 | * it's not any guarantee, but it's a high _likelihood_ that | 154 | * it's not any guarantee, but it's a high _likelihood_ that |
155 | * the match is valid). | 155 | * the match is valid). |
156 | */ | 156 | */ |
157 | void generate_resume_trace(const void *tracedata, unsigned int user) | 157 | void generate_pm_trace(const void *tracedata, unsigned int user) |
158 | { | 158 | { |
159 | unsigned short lineno = *(unsigned short *)tracedata; | 159 | unsigned short lineno = *(unsigned short *)tracedata; |
160 | const char *file = *(const char **)(tracedata + 2); | 160 | const char *file = *(const char **)(tracedata + 2); |
@@ -164,7 +164,7 @@ void generate_resume_trace(const void *tracedata, unsigned int user) | |||
164 | file_hash_value = hash_string(lineno, file, FILEHASH); | 164 | file_hash_value = hash_string(lineno, file, FILEHASH); |
165 | set_magic_time(user_hash_value, file_hash_value, dev_hash_value); | 165 | set_magic_time(user_hash_value, file_hash_value, dev_hash_value); |
166 | } | 166 | } |
167 | EXPORT_SYMBOL(generate_resume_trace); | 167 | EXPORT_SYMBOL(generate_pm_trace); |
168 | 168 | ||
169 | extern char __tracedata_start, __tracedata_end; | 169 | extern char __tracedata_start, __tracedata_end; |
170 | static int show_file_hash(unsigned int value) | 170 | static int show_file_hash(unsigned int value) |
diff --git a/drivers/base/property.c b/drivers/base/property.c index 423df593f262..1d0b116cae95 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c | |||
@@ -10,10 +10,102 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/property.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
14 | #include <linux/export.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/property.h> | ||
18 | |||
19 | /** | ||
20 | * device_add_property_set - Add a collection of properties to a device object. | ||
21 | * @dev: Device to add properties to. | ||
22 | * @pset: Collection of properties to add. | ||
23 | * | ||
24 | * Associate a collection of device properties represented by @pset with @dev | ||
25 | * as its secondary firmware node. | ||
26 | */ | ||
27 | void device_add_property_set(struct device *dev, struct property_set *pset) | ||
28 | { | ||
29 | if (pset) | ||
30 | pset->fwnode.type = FWNODE_PDATA; | ||
31 | |||
32 | set_secondary_fwnode(dev, &pset->fwnode); | ||
33 | } | ||
34 | EXPORT_SYMBOL_GPL(device_add_property_set); | ||
35 | |||
36 | static inline bool is_pset(struct fwnode_handle *fwnode) | ||
37 | { | ||
38 | return fwnode && fwnode->type == FWNODE_PDATA; | ||
39 | } | ||
40 | |||
41 | static inline struct property_set *to_pset(struct fwnode_handle *fwnode) | ||
42 | { | ||
43 | return is_pset(fwnode) ? | ||
44 | container_of(fwnode, struct property_set, fwnode) : NULL; | ||
45 | } | ||
46 | |||
47 | static struct property_entry *pset_prop_get(struct property_set *pset, | ||
48 | const char *name) | ||
49 | { | ||
50 | struct property_entry *prop; | ||
51 | |||
52 | if (!pset || !pset->properties) | ||
53 | return NULL; | ||
54 | |||
55 | for (prop = pset->properties; prop->name; prop++) | ||
56 | if (!strcmp(name, prop->name)) | ||
57 | return prop; | ||
58 | |||
59 | return NULL; | ||
60 | } | ||
61 | |||
62 | static int pset_prop_read_array(struct property_set *pset, const char *name, | ||
63 | enum dev_prop_type type, void *val, size_t nval) | ||
64 | { | ||
65 | struct property_entry *prop; | ||
66 | unsigned int item_size; | ||
67 | |||
68 | prop = pset_prop_get(pset, name); | ||
69 | if (!prop) | ||
70 | return -ENODATA; | ||
71 | |||
72 | if (prop->type != type) | ||
73 | return -EPROTO; | ||
74 | |||
75 | if (!val) | ||
76 | return prop->nval; | ||
77 | |||
78 | if (prop->nval < nval) | ||
79 | return -EOVERFLOW; | ||
80 | |||
81 | switch (type) { | ||
82 | case DEV_PROP_U8: | ||
83 | item_size = sizeof(u8); | ||
84 | break; | ||
85 | case DEV_PROP_U16: | ||
86 | item_size = sizeof(u16); | ||
87 | break; | ||
88 | case DEV_PROP_U32: | ||
89 | item_size = sizeof(u32); | ||
90 | break; | ||
91 | case DEV_PROP_U64: | ||
92 | item_size = sizeof(u64); | ||
93 | break; | ||
94 | case DEV_PROP_STRING: | ||
95 | item_size = sizeof(const char *); | ||
96 | break; | ||
97 | default: | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | memcpy(val, prop->value.raw_data, nval * item_size); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static inline struct fwnode_handle *dev_fwnode(struct device *dev) | ||
105 | { | ||
106 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | ||
107 | &dev->of_node->fwnode : dev->fwnode; | ||
108 | } | ||
17 | 109 | ||
18 | /** | 110 | /** |
19 | * device_property_present - check if a property of a device is present | 111 | * device_property_present - check if a property of a device is present |
@@ -24,10 +116,7 @@ | |||
24 | */ | 116 | */ |
25 | bool device_property_present(struct device *dev, const char *propname) | 117 | bool device_property_present(struct device *dev, const char *propname) |
26 | { | 118 | { |
27 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | 119 | return fwnode_property_present(dev_fwnode(dev), propname); |
28 | return of_property_read_bool(dev->of_node, propname); | ||
29 | |||
30 | return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL); | ||
31 | } | 120 | } |
32 | EXPORT_SYMBOL_GPL(device_property_present); | 121 | EXPORT_SYMBOL_GPL(device_property_present); |
33 | 122 | ||
@@ -43,32 +132,22 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) | |||
43 | else if (is_acpi_node(fwnode)) | 132 | else if (is_acpi_node(fwnode)) |
44 | return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL); | 133 | return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL); |
45 | 134 | ||
46 | return false; | 135 | return !!pset_prop_get(to_pset(fwnode), propname); |
47 | } | 136 | } |
48 | EXPORT_SYMBOL_GPL(fwnode_property_present); | 137 | EXPORT_SYMBOL_GPL(fwnode_property_present); |
49 | 138 | ||
50 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ | ||
51 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | ||
52 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | ||
53 | |||
54 | #define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \ | ||
55 | IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \ | ||
56 | (OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \ | ||
57 | _val_, _nval_)) : \ | ||
58 | acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \ | ||
59 | _proptype_, _val_, _nval_) | ||
60 | |||
61 | /** | 139 | /** |
62 | * device_property_read_u8_array - return a u8 array property of a device | 140 | * device_property_read_u8_array - return a u8 array property of a device |
63 | * @dev: Device to get the property of | 141 | * @dev: Device to get the property of |
64 | * @propname: Name of the property | 142 | * @propname: Name of the property |
65 | * @val: The values are stored here | 143 | * @val: The values are stored here or %NULL to return the number of values |
66 | * @nval: Size of the @val array | 144 | * @nval: Size of the @val array |
67 | * | 145 | * |
68 | * Function reads an array of u8 properties with @propname from the device | 146 | * Function reads an array of u8 properties with @propname from the device |
69 | * firmware description and stores them to @val if found. | 147 | * firmware description and stores them to @val if found. |
70 | * | 148 | * |
71 | * Return: %0 if the property was found (success), | 149 | * Return: number of values if @val was %NULL, |
150 | * %0 if the property was found (success), | ||
72 | * %-EINVAL if given arguments are not valid, | 151 | * %-EINVAL if given arguments are not valid, |
73 | * %-ENODATA if the property does not have a value, | 152 | * %-ENODATA if the property does not have a value, |
74 | * %-EPROTO if the property is not an array of numbers, | 153 | * %-EPROTO if the property is not an array of numbers, |
@@ -77,7 +156,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_present); | |||
77 | int device_property_read_u8_array(struct device *dev, const char *propname, | 156 | int device_property_read_u8_array(struct device *dev, const char *propname, |
78 | u8 *val, size_t nval) | 157 | u8 *val, size_t nval) |
79 | { | 158 | { |
80 | return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval); | 159 | return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); |
81 | } | 160 | } |
82 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); | 161 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); |
83 | 162 | ||
@@ -85,13 +164,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array); | |||
85 | * device_property_read_u16_array - return a u16 array property of a device | 164 | * device_property_read_u16_array - return a u16 array property of a device |
86 | * @dev: Device to get the property of | 165 | * @dev: Device to get the property of |
87 | * @propname: Name of the property | 166 | * @propname: Name of the property |
88 | * @val: The values are stored here | 167 | * @val: The values are stored here or %NULL to return the number of values |
89 | * @nval: Size of the @val array | 168 | * @nval: Size of the @val array |
90 | * | 169 | * |
91 | * Function reads an array of u16 properties with @propname from the device | 170 | * Function reads an array of u16 properties with @propname from the device |
92 | * firmware description and stores them to @val if found. | 171 | * firmware description and stores them to @val if found. |
93 | * | 172 | * |
94 | * Return: %0 if the property was found (success), | 173 | * Return: number of values if @val was %NULL, |
174 | * %0 if the property was found (success), | ||
95 | * %-EINVAL if given arguments are not valid, | 175 | * %-EINVAL if given arguments are not valid, |
96 | * %-ENODATA if the property does not have a value, | 176 | * %-ENODATA if the property does not have a value, |
97 | * %-EPROTO if the property is not an array of numbers, | 177 | * %-EPROTO if the property is not an array of numbers, |
@@ -100,7 +180,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array); | |||
100 | int device_property_read_u16_array(struct device *dev, const char *propname, | 180 | int device_property_read_u16_array(struct device *dev, const char *propname, |
101 | u16 *val, size_t nval) | 181 | u16 *val, size_t nval) |
102 | { | 182 | { |
103 | return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval); | 183 | return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); |
104 | } | 184 | } |
105 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); | 185 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); |
106 | 186 | ||
@@ -108,13 +188,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array); | |||
108 | * device_property_read_u32_array - return a u32 array property of a device | 188 | * device_property_read_u32_array - return a u32 array property of a device |
109 | * @dev: Device to get the property of | 189 | * @dev: Device to get the property of |
110 | * @propname: Name of the property | 190 | * @propname: Name of the property |
111 | * @val: The values are stored here | 191 | * @val: The values are stored here or %NULL to return the number of values |
112 | * @nval: Size of the @val array | 192 | * @nval: Size of the @val array |
113 | * | 193 | * |
114 | * Function reads an array of u32 properties with @propname from the device | 194 | * Function reads an array of u32 properties with @propname from the device |
115 | * firmware description and stores them to @val if found. | 195 | * firmware description and stores them to @val if found. |
116 | * | 196 | * |
117 | * Return: %0 if the property was found (success), | 197 | * Return: number of values if @val was %NULL, |
198 | * %0 if the property was found (success), | ||
118 | * %-EINVAL if given arguments are not valid, | 199 | * %-EINVAL if given arguments are not valid, |
119 | * %-ENODATA if the property does not have a value, | 200 | * %-ENODATA if the property does not have a value, |
120 | * %-EPROTO if the property is not an array of numbers, | 201 | * %-EPROTO if the property is not an array of numbers, |
@@ -123,7 +204,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array); | |||
123 | int device_property_read_u32_array(struct device *dev, const char *propname, | 204 | int device_property_read_u32_array(struct device *dev, const char *propname, |
124 | u32 *val, size_t nval) | 205 | u32 *val, size_t nval) |
125 | { | 206 | { |
126 | return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval); | 207 | return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); |
127 | } | 208 | } |
128 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); | 209 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); |
129 | 210 | ||
@@ -131,13 +212,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array); | |||
131 | * device_property_read_u64_array - return a u64 array property of a device | 212 | * device_property_read_u64_array - return a u64 array property of a device |
132 | * @dev: Device to get the property of | 213 | * @dev: Device to get the property of |
133 | * @propname: Name of the property | 214 | * @propname: Name of the property |
134 | * @val: The values are stored here | 215 | * @val: The values are stored here or %NULL to return the number of values |
135 | * @nval: Size of the @val array | 216 | * @nval: Size of the @val array |
136 | * | 217 | * |
137 | * Function reads an array of u64 properties with @propname from the device | 218 | * Function reads an array of u64 properties with @propname from the device |
138 | * firmware description and stores them to @val if found. | 219 | * firmware description and stores them to @val if found. |
139 | * | 220 | * |
140 | * Return: %0 if the property was found (success), | 221 | * Return: number of values if @val was %NULL, |
222 | * %0 if the property was found (success), | ||
141 | * %-EINVAL if given arguments are not valid, | 223 | * %-EINVAL if given arguments are not valid, |
142 | * %-ENODATA if the property does not have a value, | 224 | * %-ENODATA if the property does not have a value, |
143 | * %-EPROTO if the property is not an array of numbers, | 225 | * %-EPROTO if the property is not an array of numbers, |
@@ -146,7 +228,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array); | |||
146 | int device_property_read_u64_array(struct device *dev, const char *propname, | 228 | int device_property_read_u64_array(struct device *dev, const char *propname, |
147 | u64 *val, size_t nval) | 229 | u64 *val, size_t nval) |
148 | { | 230 | { |
149 | return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval); | 231 | return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); |
150 | } | 232 | } |
151 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); | 233 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); |
152 | 234 | ||
@@ -154,13 +236,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array); | |||
154 | * device_property_read_string_array - return a string array property of device | 236 | * device_property_read_string_array - return a string array property of device |
155 | * @dev: Device to get the property of | 237 | * @dev: Device to get the property of |
156 | * @propname: Name of the property | 238 | * @propname: Name of the property |
157 | * @val: The values are stored here | 239 | * @val: The values are stored here or %NULL to return the number of values |
158 | * @nval: Size of the @val array | 240 | * @nval: Size of the @val array |
159 | * | 241 | * |
160 | * Function reads an array of string properties with @propname from the device | 242 | * Function reads an array of string properties with @propname from the device |
161 | * firmware description and stores them to @val if found. | 243 | * firmware description and stores them to @val if found. |
162 | * | 244 | * |
163 | * Return: %0 if the property was found (success), | 245 | * Return: number of values if @val was %NULL, |
246 | * %0 if the property was found (success), | ||
164 | * %-EINVAL if given arguments are not valid, | 247 | * %-EINVAL if given arguments are not valid, |
165 | * %-ENODATA if the property does not have a value, | 248 | * %-ENODATA if the property does not have a value, |
166 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, | 249 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, |
@@ -169,10 +252,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array); | |||
169 | int device_property_read_string_array(struct device *dev, const char *propname, | 252 | int device_property_read_string_array(struct device *dev, const char *propname, |
170 | const char **val, size_t nval) | 253 | const char **val, size_t nval) |
171 | { | 254 | { |
172 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | 255 | return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); |
173 | of_property_read_string_array(dev->of_node, propname, val, nval) : | ||
174 | acpi_dev_prop_read(ACPI_COMPANION(dev), propname, | ||
175 | DEV_PROP_STRING, val, nval); | ||
176 | } | 256 | } |
177 | EXPORT_SYMBOL_GPL(device_property_read_string_array); | 257 | EXPORT_SYMBOL_GPL(device_property_read_string_array); |
178 | 258 | ||
@@ -193,13 +273,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string_array); | |||
193 | int device_property_read_string(struct device *dev, const char *propname, | 273 | int device_property_read_string(struct device *dev, const char *propname, |
194 | const char **val) | 274 | const char **val) |
195 | { | 275 | { |
196 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | 276 | return fwnode_property_read_string(dev_fwnode(dev), propname, val); |
197 | of_property_read_string(dev->of_node, propname, val) : | ||
198 | acpi_dev_prop_read(ACPI_COMPANION(dev), propname, | ||
199 | DEV_PROP_STRING, val, 1); | ||
200 | } | 277 | } |
201 | EXPORT_SYMBOL_GPL(device_property_read_string); | 278 | EXPORT_SYMBOL_GPL(device_property_read_string); |
202 | 279 | ||
280 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ | ||
281 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | ||
282 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | ||
283 | |||
203 | #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ | 284 | #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ |
204 | ({ \ | 285 | ({ \ |
205 | int _ret_; \ | 286 | int _ret_; \ |
@@ -210,7 +291,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string); | |||
210 | _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \ | 291 | _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \ |
211 | _proptype_, _val_, _nval_); \ | 292 | _proptype_, _val_, _nval_); \ |
212 | else \ | 293 | else \ |
213 | _ret_ = -ENXIO; \ | 294 | _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \ |
295 | _proptype_, _val_, _nval_); \ | ||
214 | _ret_; \ | 296 | _ret_; \ |
215 | }) | 297 | }) |
216 | 298 | ||
@@ -218,13 +300,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string); | |||
218 | * fwnode_property_read_u8_array - return a u8 array property of firmware node | 300 | * fwnode_property_read_u8_array - return a u8 array property of firmware node |
219 | * @fwnode: Firmware node to get the property of | 301 | * @fwnode: Firmware node to get the property of |
220 | * @propname: Name of the property | 302 | * @propname: Name of the property |
221 | * @val: The values are stored here | 303 | * @val: The values are stored here or %NULL to return the number of values |
222 | * @nval: Size of the @val array | 304 | * @nval: Size of the @val array |
223 | * | 305 | * |
224 | * Read an array of u8 properties with @propname from @fwnode and stores them to | 306 | * Read an array of u8 properties with @propname from @fwnode and stores them to |
225 | * @val if found. | 307 | * @val if found. |
226 | * | 308 | * |
227 | * Return: %0 if the property was found (success), | 309 | * Return: number of values if @val was %NULL, |
310 | * %0 if the property was found (success), | ||
228 | * %-EINVAL if given arguments are not valid, | 311 | * %-EINVAL if given arguments are not valid, |
229 | * %-ENODATA if the property does not have a value, | 312 | * %-ENODATA if the property does not have a value, |
230 | * %-EPROTO if the property is not an array of numbers, | 313 | * %-EPROTO if the property is not an array of numbers, |
@@ -243,13 +326,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); | |||
243 | * fwnode_property_read_u16_array - return a u16 array property of firmware node | 326 | * fwnode_property_read_u16_array - return a u16 array property of firmware node |
244 | * @fwnode: Firmware node to get the property of | 327 | * @fwnode: Firmware node to get the property of |
245 | * @propname: Name of the property | 328 | * @propname: Name of the property |
246 | * @val: The values are stored here | 329 | * @val: The values are stored here or %NULL to return the number of values |
247 | * @nval: Size of the @val array | 330 | * @nval: Size of the @val array |
248 | * | 331 | * |
249 | * Read an array of u16 properties with @propname from @fwnode and store them to | 332 | * Read an array of u16 properties with @propname from @fwnode and store them to |
250 | * @val if found. | 333 | * @val if found. |
251 | * | 334 | * |
252 | * Return: %0 if the property was found (success), | 335 | * Return: number of values if @val was %NULL, |
336 | * %0 if the property was found (success), | ||
253 | * %-EINVAL if given arguments are not valid, | 337 | * %-EINVAL if given arguments are not valid, |
254 | * %-ENODATA if the property does not have a value, | 338 | * %-ENODATA if the property does not have a value, |
255 | * %-EPROTO if the property is not an array of numbers, | 339 | * %-EPROTO if the property is not an array of numbers, |
@@ -268,13 +352,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); | |||
268 | * fwnode_property_read_u32_array - return a u32 array property of firmware node | 352 | * fwnode_property_read_u32_array - return a u32 array property of firmware node |
269 | * @fwnode: Firmware node to get the property of | 353 | * @fwnode: Firmware node to get the property of |
270 | * @propname: Name of the property | 354 | * @propname: Name of the property |
271 | * @val: The values are stored here | 355 | * @val: The values are stored here or %NULL to return the number of values |
272 | * @nval: Size of the @val array | 356 | * @nval: Size of the @val array |
273 | * | 357 | * |
274 | * Read an array of u32 properties with @propname from @fwnode store them to | 358 | * Read an array of u32 properties with @propname from @fwnode store them to |
275 | * @val if found. | 359 | * @val if found. |
276 | * | 360 | * |
277 | * Return: %0 if the property was found (success), | 361 | * Return: number of values if @val was %NULL, |
362 | * %0 if the property was found (success), | ||
278 | * %-EINVAL if given arguments are not valid, | 363 | * %-EINVAL if given arguments are not valid, |
279 | * %-ENODATA if the property does not have a value, | 364 | * %-ENODATA if the property does not have a value, |
280 | * %-EPROTO if the property is not an array of numbers, | 365 | * %-EPROTO if the property is not an array of numbers, |
@@ -293,13 +378,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); | |||
293 | * fwnode_property_read_u64_array - return a u64 array property firmware node | 378 | * fwnode_property_read_u64_array - return a u64 array property firmware node |
294 | * @fwnode: Firmware node to get the property of | 379 | * @fwnode: Firmware node to get the property of |
295 | * @propname: Name of the property | 380 | * @propname: Name of the property |
296 | * @val: The values are stored here | 381 | * @val: The values are stored here or %NULL to return the number of values |
297 | * @nval: Size of the @val array | 382 | * @nval: Size of the @val array |
298 | * | 383 | * |
299 | * Read an array of u64 properties with @propname from @fwnode and store them to | 384 | * Read an array of u64 properties with @propname from @fwnode and store them to |
300 | * @val if found. | 385 | * @val if found. |
301 | * | 386 | * |
302 | * Return: %0 if the property was found (success), | 387 | * Return: number of values if @val was %NULL, |
388 | * %0 if the property was found (success), | ||
303 | * %-EINVAL if given arguments are not valid, | 389 | * %-EINVAL if given arguments are not valid, |
304 | * %-ENODATA if the property does not have a value, | 390 | * %-ENODATA if the property does not have a value, |
305 | * %-EPROTO if the property is not an array of numbers, | 391 | * %-EPROTO if the property is not an array of numbers, |
@@ -318,13 +404,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); | |||
318 | * fwnode_property_read_string_array - return string array property of a node | 404 | * fwnode_property_read_string_array - return string array property of a node |
319 | * @fwnode: Firmware node to get the property of | 405 | * @fwnode: Firmware node to get the property of |
320 | * @propname: Name of the property | 406 | * @propname: Name of the property |
321 | * @val: The values are stored here | 407 | * @val: The values are stored here or %NULL to return the number of values |
322 | * @nval: Size of the @val array | 408 | * @nval: Size of the @val array |
323 | * | 409 | * |
324 | * Read an string list property @propname from the given firmware node and store | 410 | * Read an string list property @propname from the given firmware node and store |
325 | * them to @val if found. | 411 | * them to @val if found. |
326 | * | 412 | * |
327 | * Return: %0 if the property was found (success), | 413 | * Return: number of values if @val was %NULL, |
414 | * %0 if the property was found (success), | ||
328 | * %-EINVAL if given arguments are not valid, | 415 | * %-EINVAL if given arguments are not valid, |
329 | * %-ENODATA if the property does not have a value, | 416 | * %-ENODATA if the property does not have a value, |
330 | * %-EPROTO if the property is not an array of strings, | 417 | * %-EPROTO if the property is not an array of strings, |
@@ -336,13 +423,16 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |||
336 | size_t nval) | 423 | size_t nval) |
337 | { | 424 | { |
338 | if (is_of_node(fwnode)) | 425 | if (is_of_node(fwnode)) |
339 | return of_property_read_string_array(of_node(fwnode), propname, | 426 | return val ? |
340 | val, nval); | 427 | of_property_read_string_array(of_node(fwnode), propname, |
428 | val, nval) : | ||
429 | of_property_count_strings(of_node(fwnode), propname); | ||
341 | else if (is_acpi_node(fwnode)) | 430 | else if (is_acpi_node(fwnode)) |
342 | return acpi_dev_prop_read(acpi_node(fwnode), propname, | 431 | return acpi_dev_prop_read(acpi_node(fwnode), propname, |
343 | DEV_PROP_STRING, val, nval); | 432 | DEV_PROP_STRING, val, nval); |
344 | 433 | ||
345 | return -ENXIO; | 434 | return pset_prop_read_array(to_pset(fwnode), propname, |
435 | DEV_PROP_STRING, val, nval); | ||
346 | } | 436 | } |
347 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); | 437 | EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); |
348 | 438 | ||
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 6d492132ad2b..29ba520ac24d 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -637,18 +637,7 @@ static struct pnp_driver tpm_inf_pnp_driver = { | |||
637 | .remove = tpm_inf_pnp_remove | 637 | .remove = tpm_inf_pnp_remove |
638 | }; | 638 | }; |
639 | 639 | ||
640 | static int __init init_inf(void) | 640 | module_pnp_driver(tpm_inf_pnp_driver); |
641 | { | ||
642 | return pnp_register_driver(&tpm_inf_pnp_driver); | ||
643 | } | ||
644 | |||
645 | static void __exit cleanup_inf(void) | ||
646 | { | ||
647 | pnp_unregister_driver(&tpm_inf_pnp_driver); | ||
648 | } | ||
649 | |||
650 | module_init(init_inf); | ||
651 | module_exit(cleanup_inf); | ||
652 | 641 | ||
653 | MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>"); | 642 | MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>"); |
654 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 643 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index a171fef2c2b6..659879a56dba 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -293,5 +293,13 @@ config SH_CPU_FREQ | |||
293 | If unsure, say N. | 293 | If unsure, say N. |
294 | endif | 294 | endif |
295 | 295 | ||
296 | config QORIQ_CPUFREQ | ||
297 | tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" | ||
298 | depends on OF && COMMON_CLK && (PPC_E500MC || ARM) | ||
299 | select CLK_QORIQ | ||
300 | help | ||
301 | This adds the CPUFreq driver support for Freescale QorIQ SoCs | ||
302 | which are capable of changing the CPU's frequency dynamically. | ||
303 | |||
296 | endif | 304 | endif |
297 | endmenu | 305 | endmenu |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 1b06fc4640e2..4f3dbc8cf729 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -108,6 +108,15 @@ config ARM_HIGHBANK_CPUFREQ | |||
108 | 108 | ||
109 | If in doubt, say N. | 109 | If in doubt, say N. |
110 | 110 | ||
111 | config ARM_HISI_ACPU_CPUFREQ | ||
112 | tristate "Hisilicon ACPU CPUfreq driver" | ||
113 | depends on ARCH_HISI && CPUFREQ_DT | ||
114 | select PM_OPP | ||
115 | help | ||
116 | This enables the hisilicon ACPU CPUfreq driver. | ||
117 | |||
118 | If in doubt, say N. | ||
119 | |||
111 | config ARM_IMX6Q_CPUFREQ | 120 | config ARM_IMX6Q_CPUFREQ |
112 | tristate "Freescale i.MX6 cpufreq support" | 121 | tristate "Freescale i.MX6 cpufreq support" |
113 | depends on ARCH_MXC | 122 | depends on ARCH_MXC |
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index 7ea24413cee6..3a0595b41eab 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc | |||
@@ -23,15 +23,6 @@ config CPU_FREQ_MAPLE | |||
23 | This adds support for frequency switching on Maple 970FX | 23 | This adds support for frequency switching on Maple 970FX |
24 | Evaluation Board and compatible boards (IBM JS2x blades). | 24 | Evaluation Board and compatible boards (IBM JS2x blades). |
25 | 25 | ||
26 | config PPC_CORENET_CPUFREQ | ||
27 | tristate "CPU frequency scaling driver for Freescale E500MC SoCs" | ||
28 | depends on PPC_E500MC && OF && COMMON_CLK | ||
29 | select CLK_QORIQ | ||
30 | help | ||
31 | This adds the CPUFreq driver support for Freescale e500mc, | ||
32 | e5500 and e6500 series SoCs which are capable of changing | ||
33 | the CPU's frequency dynamically. | ||
34 | |||
35 | config CPU_FREQ_PMAC | 26 | config CPU_FREQ_PMAC |
36 | bool "Support for Apple PowerBooks" | 27 | bool "Support for Apple PowerBooks" |
37 | depends on ADB_PMU && PPC32 | 28 | depends on ADB_PMU && PPC32 |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 82a1821471fd..cdce92ae2e8b 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -59,6 +59,7 @@ arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o | |||
59 | arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o | 59 | arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o |
60 | obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o | 60 | obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o |
61 | obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o | 61 | obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o |
62 | obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o | ||
62 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o | 63 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o |
63 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o | 64 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o |
64 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o | 65 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o |
@@ -85,7 +86,7 @@ obj-$(CONFIG_CPU_FREQ_CBE) += ppc-cbe-cpufreq.o | |||
85 | ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o | 86 | ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o |
86 | obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o | 87 | obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o |
87 | obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o | 88 | obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o |
88 | obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o | 89 | obj-$(CONFIG_QORIQ_CPUFREQ) += qoriq-cpufreq.o |
89 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o | 90 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o |
90 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o | 91 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o |
91 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o | 92 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o |
diff --git a/drivers/cpufreq/hisi-acpu-cpufreq.c b/drivers/cpufreq/hisi-acpu-cpufreq.c new file mode 100644 index 000000000000..026d5b2224de --- /dev/null +++ b/drivers/cpufreq/hisi-acpu-cpufreq.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Hisilicon Platforms Using ACPU CPUFreq Support | ||
3 | * | ||
4 | * Copyright (c) 2015 Hisilicon Limited. | ||
5 | * Copyright (c) 2015 Linaro Limited. | ||
6 | * | ||
7 | * Leo Yan <leo.yan@linaro.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
14 | * kind, whether express or implied; without even the implied warranty | ||
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <linux/err.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | |||
28 | static int __init hisi_acpu_cpufreq_driver_init(void) | ||
29 | { | ||
30 | struct platform_device *pdev; | ||
31 | |||
32 | if (!of_machine_is_compatible("hisilicon,hi6220")) | ||
33 | return -ENODEV; | ||
34 | |||
35 | pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); | ||
36 | return PTR_ERR_OR_ZERO(pdev); | ||
37 | } | ||
38 | module_init(hisi_acpu_cpufreq_driver_init); | ||
39 | |||
40 | MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>"); | ||
41 | MODULE_DESCRIPTION("Hisilicon acpu cpufreq driver"); | ||
42 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 872c5772c5d3..c5b81beccc8e 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -614,6 +614,19 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) | |||
614 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); | 614 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); |
615 | } | 615 | } |
616 | 616 | ||
617 | static int knl_get_turbo_pstate(void) | ||
618 | { | ||
619 | u64 value; | ||
620 | int nont, ret; | ||
621 | |||
622 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); | ||
623 | nont = core_get_max_pstate(); | ||
624 | ret = (((value) >> 8) & 0xFF); | ||
625 | if (ret <= nont) | ||
626 | ret = nont; | ||
627 | return ret; | ||
628 | } | ||
629 | |||
617 | static struct cpu_defaults core_params = { | 630 | static struct cpu_defaults core_params = { |
618 | .pid_policy = { | 631 | .pid_policy = { |
619 | .sample_rate_ms = 10, | 632 | .sample_rate_ms = 10, |
@@ -651,6 +664,23 @@ static struct cpu_defaults byt_params = { | |||
651 | }, | 664 | }, |
652 | }; | 665 | }; |
653 | 666 | ||
667 | static struct cpu_defaults knl_params = { | ||
668 | .pid_policy = { | ||
669 | .sample_rate_ms = 10, | ||
670 | .deadband = 0, | ||
671 | .setpoint = 97, | ||
672 | .p_gain_pct = 20, | ||
673 | .d_gain_pct = 0, | ||
674 | .i_gain_pct = 0, | ||
675 | }, | ||
676 | .funcs = { | ||
677 | .get_max = core_get_max_pstate, | ||
678 | .get_min = core_get_min_pstate, | ||
679 | .get_turbo = knl_get_turbo_pstate, | ||
680 | .set = core_set_pstate, | ||
681 | }, | ||
682 | }; | ||
683 | |||
654 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | 684 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) |
655 | { | 685 | { |
656 | int max_perf = cpu->pstate.turbo_pstate; | 686 | int max_perf = cpu->pstate.turbo_pstate; |
@@ -865,6 +895,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
865 | ICPU(0x4e, core_params), | 895 | ICPU(0x4e, core_params), |
866 | ICPU(0x4f, core_params), | 896 | ICPU(0x4f, core_params), |
867 | ICPU(0x56, core_params), | 897 | ICPU(0x56, core_params), |
898 | ICPU(0x57, knl_params), | ||
868 | {} | 899 | {} |
869 | }; | 900 | }; |
870 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 901 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
@@ -1024,25 +1055,11 @@ static unsigned int force_load; | |||
1024 | 1055 | ||
1025 | static int intel_pstate_msrs_not_valid(void) | 1056 | static int intel_pstate_msrs_not_valid(void) |
1026 | { | 1057 | { |
1027 | /* Check that all the msr's we are using are valid. */ | ||
1028 | u64 aperf, mperf, tmp; | ||
1029 | |||
1030 | rdmsrl(MSR_IA32_APERF, aperf); | ||
1031 | rdmsrl(MSR_IA32_MPERF, mperf); | ||
1032 | |||
1033 | if (!pstate_funcs.get_max() || | 1058 | if (!pstate_funcs.get_max() || |
1034 | !pstate_funcs.get_min() || | 1059 | !pstate_funcs.get_min() || |
1035 | !pstate_funcs.get_turbo()) | 1060 | !pstate_funcs.get_turbo()) |
1036 | return -ENODEV; | 1061 | return -ENODEV; |
1037 | 1062 | ||
1038 | rdmsrl(MSR_IA32_APERF, tmp); | ||
1039 | if (!(tmp - aperf)) | ||
1040 | return -ENODEV; | ||
1041 | |||
1042 | rdmsrl(MSR_IA32_MPERF, tmp); | ||
1043 | if (!(tmp - mperf)) | ||
1044 | return -ENODEV; | ||
1045 | |||
1046 | return 0; | 1063 | return 0; |
1047 | } | 1064 | } |
1048 | 1065 | ||
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 2dfd4fdb5a52..ebef0d8279c7 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
@@ -34,9 +34,13 @@ | |||
34 | #include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ | 34 | #include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ |
35 | 35 | ||
36 | #define POWERNV_MAX_PSTATES 256 | 36 | #define POWERNV_MAX_PSTATES 256 |
37 | #define PMSR_PSAFE_ENABLE (1UL << 30) | ||
38 | #define PMSR_SPR_EM_DISABLE (1UL << 31) | ||
39 | #define PMSR_MAX(x) ((x >> 32) & 0xFF) | ||
40 | #define PMSR_LP(x) ((x >> 48) & 0xFF) | ||
37 | 41 | ||
38 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; | 42 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; |
39 | static bool rebooting; | 43 | static bool rebooting, throttled; |
40 | 44 | ||
41 | /* | 45 | /* |
42 | * Note: The set of pstates consists of contiguous integers, the | 46 | * Note: The set of pstates consists of contiguous integers, the |
@@ -294,6 +298,44 @@ static inline unsigned int get_nominal_index(void) | |||
294 | return powernv_pstate_info.max - powernv_pstate_info.nominal; | 298 | return powernv_pstate_info.max - powernv_pstate_info.nominal; |
295 | } | 299 | } |
296 | 300 | ||
301 | static void powernv_cpufreq_throttle_check(unsigned int cpu) | ||
302 | { | ||
303 | unsigned long pmsr; | ||
304 | int pmsr_pmax, pmsr_lp; | ||
305 | |||
306 | pmsr = get_pmspr(SPRN_PMSR); | ||
307 | |||
308 | /* Check for Pmax Capping */ | ||
309 | pmsr_pmax = (s8)PMSR_MAX(pmsr); | ||
310 | if (pmsr_pmax != powernv_pstate_info.max) { | ||
311 | throttled = true; | ||
312 | pr_info("CPU %d Pmax is reduced to %d\n", cpu, pmsr_pmax); | ||
313 | pr_info("Max allowed Pstate is capped\n"); | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * Check for Psafe by reading LocalPstate | ||
318 | * or check if Psafe_mode_active is set in PMSR. | ||
319 | */ | ||
320 | pmsr_lp = (s8)PMSR_LP(pmsr); | ||
321 | if ((pmsr_lp < powernv_pstate_info.min) || | ||
322 | (pmsr & PMSR_PSAFE_ENABLE)) { | ||
323 | throttled = true; | ||
324 | pr_info("Pstate set to safe frequency\n"); | ||
325 | } | ||
326 | |||
327 | /* Check if SPR_EM_DISABLE is set in PMSR */ | ||
328 | if (pmsr & PMSR_SPR_EM_DISABLE) { | ||
329 | throttled = true; | ||
330 | pr_info("Frequency Control disabled from OS\n"); | ||
331 | } | ||
332 | |||
333 | if (throttled) { | ||
334 | pr_info("PMSR = %16lx\n", pmsr); | ||
335 | pr_crit("CPU Frequency could be throttled\n"); | ||
336 | } | ||
337 | } | ||
338 | |||
297 | /* | 339 | /* |
298 | * powernv_cpufreq_target_index: Sets the frequency corresponding to | 340 | * powernv_cpufreq_target_index: Sets the frequency corresponding to |
299 | * the cpufreq table entry indexed by new_index on the cpus in the | 341 | * the cpufreq table entry indexed by new_index on the cpus in the |
@@ -307,6 +349,9 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy, | |||
307 | if (unlikely(rebooting) && new_index != get_nominal_index()) | 349 | if (unlikely(rebooting) && new_index != get_nominal_index()) |
308 | return 0; | 350 | return 0; |
309 | 351 | ||
352 | if (!throttled) | ||
353 | powernv_cpufreq_throttle_check(smp_processor_id()); | ||
354 | |||
310 | freq_data.pstate_id = powernv_freqs[new_index].driver_data; | 355 | freq_data.pstate_id = powernv_freqs[new_index].driver_data; |
311 | 356 | ||
312 | /* | 357 | /* |
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 7cb4b766cf94..88b21ae0d6b0 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2013 Freescale Semiconductor, Inc. | 2 | * Copyright 2013 Freescale Semiconductor, Inc. |
3 | * | 3 | * |
4 | * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs. | 4 | * CPU Frequency Scaling driver for Freescale QorIQ SoCs. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,12 +20,13 @@ | |||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
23 | #include <sysdev/fsl_soc.h> | ||
24 | 23 | ||
24 | #if !defined(CONFIG_ARM) | ||
25 | #include <asm/smp.h> /* for get_hard_smp_processor_id() in UP configs */ | 25 | #include <asm/smp.h> /* for get_hard_smp_processor_id() in UP configs */ |
26 | #endif | ||
26 | 27 | ||
27 | /** | 28 | /** |
28 | * struct cpu_data - per CPU data struct | 29 | * struct cpu_data |
29 | * @parent: the parent node of cpu clock | 30 | * @parent: the parent node of cpu clock |
30 | * @table: frequency table | 31 | * @table: frequency table |
31 | */ | 32 | */ |
@@ -69,17 +70,78 @@ static const struct soc_data sdata[] = { | |||
69 | static u32 min_cpufreq; | 70 | static u32 min_cpufreq; |
70 | static const u32 *fmask; | 71 | static const u32 *fmask; |
71 | 72 | ||
72 | static DEFINE_PER_CPU(struct cpu_data *, cpu_data); | 73 | #if defined(CONFIG_ARM) |
74 | static int get_cpu_physical_id(int cpu) | ||
75 | { | ||
76 | return topology_core_id(cpu); | ||
77 | } | ||
78 | #else | ||
79 | static int get_cpu_physical_id(int cpu) | ||
80 | { | ||
81 | return get_hard_smp_processor_id(cpu); | ||
82 | } | ||
83 | #endif | ||
73 | 84 | ||
74 | /* cpumask in a cluster */ | 85 | static u32 get_bus_freq(void) |
75 | static DEFINE_PER_CPU(cpumask_var_t, cpu_mask); | 86 | { |
87 | struct device_node *soc; | ||
88 | u32 sysfreq; | ||
89 | |||
90 | soc = of_find_node_by_type(NULL, "soc"); | ||
91 | if (!soc) | ||
92 | return 0; | ||
93 | |||
94 | if (of_property_read_u32(soc, "bus-frequency", &sysfreq)) | ||
95 | sysfreq = 0; | ||
76 | 96 | ||
77 | #ifndef CONFIG_SMP | 97 | of_node_put(soc); |
78 | static inline const struct cpumask *cpu_core_mask(int cpu) | 98 | |
99 | return sysfreq; | ||
100 | } | ||
101 | |||
102 | static struct device_node *cpu_to_clk_node(int cpu) | ||
79 | { | 103 | { |
80 | return cpumask_of(0); | 104 | struct device_node *np, *clk_np; |
105 | |||
106 | if (!cpu_present(cpu)) | ||
107 | return NULL; | ||
108 | |||
109 | np = of_get_cpu_node(cpu, NULL); | ||
110 | if (!np) | ||
111 | return NULL; | ||
112 | |||
113 | clk_np = of_parse_phandle(np, "clocks", 0); | ||
114 | if (!clk_np) | ||
115 | return NULL; | ||
116 | |||
117 | of_node_put(np); | ||
118 | |||
119 | return clk_np; | ||
120 | } | ||
121 | |||
122 | /* traverse cpu nodes to get cpu mask of sharing clock wire */ | ||
123 | static void set_affected_cpus(struct cpufreq_policy *policy) | ||
124 | { | ||
125 | struct device_node *np, *clk_np; | ||
126 | struct cpumask *dstp = policy->cpus; | ||
127 | int i; | ||
128 | |||
129 | np = cpu_to_clk_node(policy->cpu); | ||
130 | if (!np) | ||
131 | return; | ||
132 | |||
133 | for_each_present_cpu(i) { | ||
134 | clk_np = cpu_to_clk_node(i); | ||
135 | if (!clk_np) | ||
136 | continue; | ||
137 | |||
138 | if (clk_np == np) | ||
139 | cpumask_set_cpu(i, dstp); | ||
140 | |||
141 | of_node_put(clk_np); | ||
142 | } | ||
143 | of_node_put(np); | ||
81 | } | 144 | } |
82 | #endif | ||
83 | 145 | ||
84 | /* reduce the duplicated frequencies in frequency table */ | 146 | /* reduce the duplicated frequencies in frequency table */ |
85 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, | 147 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, |
@@ -107,6 +169,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table, | |||
107 | int i, j, ind; | 169 | int i, j, ind; |
108 | unsigned int freq, max_freq; | 170 | unsigned int freq, max_freq; |
109 | struct cpufreq_frequency_table table; | 171 | struct cpufreq_frequency_table table; |
172 | |||
110 | for (i = 0; i < count - 1; i++) { | 173 | for (i = 0; i < count - 1; i++) { |
111 | max_freq = freq_table[i].frequency; | 174 | max_freq = freq_table[i].frequency; |
112 | ind = i; | 175 | ind = i; |
@@ -131,7 +194,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table, | |||
131 | } | 194 | } |
132 | } | 195 | } |
133 | 196 | ||
134 | static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | 197 | static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) |
135 | { | 198 | { |
136 | struct device_node *np; | 199 | struct device_node *np; |
137 | int i, count, ret; | 200 | int i, count, ret; |
@@ -147,10 +210,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
147 | return -ENODEV; | 210 | return -ENODEV; |
148 | 211 | ||
149 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 212 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
150 | if (!data) { | 213 | if (!data) |
151 | pr_err("%s: no memory\n", __func__); | ||
152 | goto err_np; | 214 | goto err_np; |
153 | } | ||
154 | 215 | ||
155 | policy->clk = of_clk_get(np, 0); | 216 | policy->clk = of_clk_get(np, 0); |
156 | if (IS_ERR(policy->clk)) { | 217 | if (IS_ERR(policy->clk)) { |
@@ -172,7 +233,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
172 | } | 233 | } |
173 | 234 | ||
174 | if (fmask) | 235 | if (fmask) |
175 | mask = fmask[get_hard_smp_processor_id(cpu)]; | 236 | mask = fmask[get_cpu_physical_id(cpu)]; |
176 | else | 237 | else |
177 | mask = 0x0; | 238 | mask = 0x0; |
178 | 239 | ||
@@ -203,13 +264,12 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
203 | data->table = table; | 264 | data->table = table; |
204 | 265 | ||
205 | /* update ->cpus if we have cluster, no harm if not */ | 266 | /* update ->cpus if we have cluster, no harm if not */ |
206 | cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu)); | 267 | set_affected_cpus(policy); |
207 | for_each_cpu(i, per_cpu(cpu_mask, cpu)) | 268 | policy->driver_data = data; |
208 | per_cpu(cpu_data, i) = data; | ||
209 | 269 | ||
210 | /* Minimum transition latency is 12 platform clocks */ | 270 | /* Minimum transition latency is 12 platform clocks */ |
211 | u64temp = 12ULL * NSEC_PER_SEC; | 271 | u64temp = 12ULL * NSEC_PER_SEC; |
212 | do_div(u64temp, fsl_get_sys_freq()); | 272 | do_div(u64temp, get_bus_freq()); |
213 | policy->cpuinfo.transition_latency = u64temp + 1; | 273 | policy->cpuinfo.transition_latency = u64temp + 1; |
214 | 274 | ||
215 | of_node_put(np); | 275 | of_node_put(np); |
@@ -221,7 +281,7 @@ err_nomem1: | |||
221 | err_node: | 281 | err_node: |
222 | of_node_put(data->parent); | 282 | of_node_put(data->parent); |
223 | err_nomem2: | 283 | err_nomem2: |
224 | per_cpu(cpu_data, cpu) = NULL; | 284 | policy->driver_data = NULL; |
225 | kfree(data); | 285 | kfree(data); |
226 | err_np: | 286 | err_np: |
227 | of_node_put(np); | 287 | of_node_put(np); |
@@ -229,43 +289,40 @@ err_np: | |||
229 | return -ENODEV; | 289 | return -ENODEV; |
230 | } | 290 | } |
231 | 291 | ||
232 | static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) | 292 | static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy) |
233 | { | 293 | { |
234 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); | 294 | struct cpu_data *data = policy->driver_data; |
235 | unsigned int cpu; | ||
236 | 295 | ||
237 | of_node_put(data->parent); | 296 | of_node_put(data->parent); |
238 | kfree(data->table); | 297 | kfree(data->table); |
239 | kfree(data); | 298 | kfree(data); |
240 | 299 | policy->driver_data = NULL; | |
241 | for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu)) | ||
242 | per_cpu(cpu_data, cpu) = NULL; | ||
243 | 300 | ||
244 | return 0; | 301 | return 0; |
245 | } | 302 | } |
246 | 303 | ||
247 | static int corenet_cpufreq_target(struct cpufreq_policy *policy, | 304 | static int qoriq_cpufreq_target(struct cpufreq_policy *policy, |
248 | unsigned int index) | 305 | unsigned int index) |
249 | { | 306 | { |
250 | struct clk *parent; | 307 | struct clk *parent; |
251 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); | 308 | struct cpu_data *data = policy->driver_data; |
252 | 309 | ||
253 | parent = of_clk_get(data->parent, data->table[index].driver_data); | 310 | parent = of_clk_get(data->parent, data->table[index].driver_data); |
254 | return clk_set_parent(policy->clk, parent); | 311 | return clk_set_parent(policy->clk, parent); |
255 | } | 312 | } |
256 | 313 | ||
257 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 314 | static struct cpufreq_driver qoriq_cpufreq_driver = { |
258 | .name = "ppc_cpufreq", | 315 | .name = "qoriq_cpufreq", |
259 | .flags = CPUFREQ_CONST_LOOPS, | 316 | .flags = CPUFREQ_CONST_LOOPS, |
260 | .init = corenet_cpufreq_cpu_init, | 317 | .init = qoriq_cpufreq_cpu_init, |
261 | .exit = __exit_p(corenet_cpufreq_cpu_exit), | 318 | .exit = __exit_p(qoriq_cpufreq_cpu_exit), |
262 | .verify = cpufreq_generic_frequency_table_verify, | 319 | .verify = cpufreq_generic_frequency_table_verify, |
263 | .target_index = corenet_cpufreq_target, | 320 | .target_index = qoriq_cpufreq_target, |
264 | .get = cpufreq_generic_get, | 321 | .get = cpufreq_generic_get, |
265 | .attr = cpufreq_generic_attr, | 322 | .attr = cpufreq_generic_attr, |
266 | }; | 323 | }; |
267 | 324 | ||
268 | static const struct of_device_id node_matches[] __initdata = { | 325 | static const struct of_device_id node_matches[] __initconst = { |
269 | { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], }, | 326 | { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], }, |
270 | { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], }, | 327 | { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], }, |
271 | { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, | 328 | { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, |
@@ -275,61 +332,43 @@ static const struct of_device_id node_matches[] __initdata = { | |||
275 | {} | 332 | {} |
276 | }; | 333 | }; |
277 | 334 | ||
278 | static int __init ppc_corenet_cpufreq_init(void) | 335 | static int __init qoriq_cpufreq_init(void) |
279 | { | 336 | { |
280 | int ret; | 337 | int ret; |
281 | struct device_node *np; | 338 | struct device_node *np; |
282 | const struct of_device_id *match; | 339 | const struct of_device_id *match; |
283 | const struct soc_data *data; | 340 | const struct soc_data *data; |
284 | unsigned int cpu; | ||
285 | 341 | ||
286 | np = of_find_matching_node(NULL, node_matches); | 342 | np = of_find_matching_node(NULL, node_matches); |
287 | if (!np) | 343 | if (!np) |
288 | return -ENODEV; | 344 | return -ENODEV; |
289 | 345 | ||
290 | for_each_possible_cpu(cpu) { | ||
291 | if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL)) | ||
292 | goto err_mask; | ||
293 | cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu)); | ||
294 | } | ||
295 | |||
296 | match = of_match_node(node_matches, np); | 346 | match = of_match_node(node_matches, np); |
297 | data = match->data; | 347 | data = match->data; |
298 | if (data) { | 348 | if (data) { |
299 | if (data->flag) | 349 | if (data->flag) |
300 | fmask = data->freq_mask; | 350 | fmask = data->freq_mask; |
301 | min_cpufreq = fsl_get_sys_freq(); | 351 | min_cpufreq = get_bus_freq(); |
302 | } else { | 352 | } else { |
303 | min_cpufreq = fsl_get_sys_freq() / 2; | 353 | min_cpufreq = get_bus_freq() / 2; |
304 | } | 354 | } |
305 | 355 | ||
306 | of_node_put(np); | 356 | of_node_put(np); |
307 | 357 | ||
308 | ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver); | 358 | ret = cpufreq_register_driver(&qoriq_cpufreq_driver); |
309 | if (!ret) | 359 | if (!ret) |
310 | pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n"); | 360 | pr_info("Freescale QorIQ CPU frequency scaling driver\n"); |
311 | 361 | ||
312 | return ret; | 362 | return ret; |
313 | |||
314 | err_mask: | ||
315 | for_each_possible_cpu(cpu) | ||
316 | free_cpumask_var(per_cpu(cpu_mask, cpu)); | ||
317 | |||
318 | return -ENOMEM; | ||
319 | } | 363 | } |
320 | module_init(ppc_corenet_cpufreq_init); | 364 | module_init(qoriq_cpufreq_init); |
321 | 365 | ||
322 | static void __exit ppc_corenet_cpufreq_exit(void) | 366 | static void __exit qoriq_cpufreq_exit(void) |
323 | { | 367 | { |
324 | unsigned int cpu; | 368 | cpufreq_unregister_driver(&qoriq_cpufreq_driver); |
325 | |||
326 | for_each_possible_cpu(cpu) | ||
327 | free_cpumask_var(per_cpu(cpu_mask, cpu)); | ||
328 | |||
329 | cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver); | ||
330 | } | 369 | } |
331 | module_exit(ppc_corenet_cpufreq_exit); | 370 | module_exit(qoriq_cpufreq_exit); |
332 | 371 | ||
333 | MODULE_LICENSE("GPL"); | 372 | MODULE_LICENSE("GPL"); |
334 | MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); | 373 | MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); |
335 | MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs"); | 374 | MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs"); |
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index c5029c1209b4..8c7930b5a65f 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig | |||
@@ -29,15 +29,10 @@ config DT_IDLE_STATES | |||
29 | bool | 29 | bool |
30 | 30 | ||
31 | menu "ARM CPU Idle Drivers" | 31 | menu "ARM CPU Idle Drivers" |
32 | depends on ARM | 32 | depends on ARM || ARM64 |
33 | source "drivers/cpuidle/Kconfig.arm" | 33 | source "drivers/cpuidle/Kconfig.arm" |
34 | endmenu | 34 | endmenu |
35 | 35 | ||
36 | menu "ARM64 CPU Idle Drivers" | ||
37 | depends on ARM64 | ||
38 | source "drivers/cpuidle/Kconfig.arm64" | ||
39 | endmenu | ||
40 | |||
41 | menu "MIPS CPU Idle Drivers" | 36 | menu "MIPS CPU Idle Drivers" |
42 | depends on MIPS | 37 | depends on MIPS |
43 | source "drivers/cpuidle/Kconfig.mips" | 38 | source "drivers/cpuidle/Kconfig.mips" |
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 8e07c9419153..21340e0be73e 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -1,10 +1,20 @@ | |||
1 | # | 1 | # |
2 | # ARM CPU Idle drivers | 2 | # ARM CPU Idle drivers |
3 | # | 3 | # |
4 | config ARM_CPUIDLE | ||
5 | bool "Generic ARM/ARM64 CPU idle Driver" | ||
6 | select DT_IDLE_STATES | ||
7 | help | ||
8 | Select this to enable generic cpuidle driver for ARM. | ||
9 | It provides a generic idle driver whose idle states are configured | ||
10 | at run-time through DT nodes. The CPUidle suspend backend is | ||
11 | initialized by calling the CPU operations init idle hook | ||
12 | provided by architecture code. | ||
13 | |||
4 | config ARM_BIG_LITTLE_CPUIDLE | 14 | config ARM_BIG_LITTLE_CPUIDLE |
5 | bool "Support for ARM big.LITTLE processors" | 15 | bool "Support for ARM big.LITTLE processors" |
6 | depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS | 16 | depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS |
7 | depends on MCPM | 17 | depends on MCPM && !ARM64 |
8 | select ARM_CPU_SUSPEND | 18 | select ARM_CPU_SUSPEND |
9 | select CPU_IDLE_MULTIPLE_DRIVERS | 19 | select CPU_IDLE_MULTIPLE_DRIVERS |
10 | select DT_IDLE_STATES | 20 | select DT_IDLE_STATES |
@@ -16,51 +26,51 @@ config ARM_BIG_LITTLE_CPUIDLE | |||
16 | 26 | ||
17 | config ARM_CLPS711X_CPUIDLE | 27 | config ARM_CLPS711X_CPUIDLE |
18 | bool "CPU Idle Driver for CLPS711X processors" | 28 | bool "CPU Idle Driver for CLPS711X processors" |
19 | depends on ARCH_CLPS711X || COMPILE_TEST | 29 | depends on ARCH_CLPS711X && !ARM64 || COMPILE_TEST |
20 | help | 30 | help |
21 | Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs. | 31 | Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs. |
22 | 32 | ||
23 | config ARM_HIGHBANK_CPUIDLE | 33 | config ARM_HIGHBANK_CPUIDLE |
24 | bool "CPU Idle Driver for Calxeda processors" | 34 | bool "CPU Idle Driver for Calxeda processors" |
25 | depends on ARM_PSCI | 35 | depends on ARM_PSCI && !ARM64 |
26 | select ARM_CPU_SUSPEND | 36 | select ARM_CPU_SUSPEND |
27 | help | 37 | help |
28 | Select this to enable cpuidle on Calxeda processors. | 38 | Select this to enable cpuidle on Calxeda processors. |
29 | 39 | ||
30 | config ARM_KIRKWOOD_CPUIDLE | 40 | config ARM_KIRKWOOD_CPUIDLE |
31 | bool "CPU Idle Driver for Marvell Kirkwood SoCs" | 41 | bool "CPU Idle Driver for Marvell Kirkwood SoCs" |
32 | depends on MACH_KIRKWOOD | 42 | depends on MACH_KIRKWOOD && !ARM64 |
33 | help | 43 | help |
34 | This adds the CPU Idle driver for Marvell Kirkwood SoCs. | 44 | This adds the CPU Idle driver for Marvell Kirkwood SoCs. |
35 | 45 | ||
36 | config ARM_ZYNQ_CPUIDLE | 46 | config ARM_ZYNQ_CPUIDLE |
37 | bool "CPU Idle Driver for Xilinx Zynq processors" | 47 | bool "CPU Idle Driver for Xilinx Zynq processors" |
38 | depends on ARCH_ZYNQ | 48 | depends on ARCH_ZYNQ && !ARM64 |
39 | help | 49 | help |
40 | Select this to enable cpuidle on Xilinx Zynq processors. | 50 | Select this to enable cpuidle on Xilinx Zynq processors. |
41 | 51 | ||
42 | config ARM_U8500_CPUIDLE | 52 | config ARM_U8500_CPUIDLE |
43 | bool "Cpu Idle Driver for the ST-E u8500 processors" | 53 | bool "Cpu Idle Driver for the ST-E u8500 processors" |
44 | depends on ARCH_U8500 | 54 | depends on ARCH_U8500 && !ARM64 |
45 | help | 55 | help |
46 | Select this to enable cpuidle for ST-E u8500 processors | 56 | Select this to enable cpuidle for ST-E u8500 processors |
47 | 57 | ||
48 | config ARM_AT91_CPUIDLE | 58 | config ARM_AT91_CPUIDLE |
49 | bool "Cpu Idle Driver for the AT91 processors" | 59 | bool "Cpu Idle Driver for the AT91 processors" |
50 | default y | 60 | default y |
51 | depends on ARCH_AT91 | 61 | depends on ARCH_AT91 && !ARM64 |
52 | help | 62 | help |
53 | Select this to enable cpuidle for AT91 processors | 63 | Select this to enable cpuidle for AT91 processors |
54 | 64 | ||
55 | config ARM_EXYNOS_CPUIDLE | 65 | config ARM_EXYNOS_CPUIDLE |
56 | bool "Cpu Idle Driver for the Exynos processors" | 66 | bool "Cpu Idle Driver for the Exynos processors" |
57 | depends on ARCH_EXYNOS | 67 | depends on ARCH_EXYNOS && !ARM64 |
58 | select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP | 68 | select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP |
59 | help | 69 | help |
60 | Select this to enable cpuidle for Exynos processors | 70 | Select this to enable cpuidle for Exynos processors |
61 | 71 | ||
62 | config ARM_MVEBU_V7_CPUIDLE | 72 | config ARM_MVEBU_V7_CPUIDLE |
63 | bool "CPU Idle Driver for mvebu v7 family processors" | 73 | bool "CPU Idle Driver for mvebu v7 family processors" |
64 | depends on ARCH_MVEBU | 74 | depends on ARCH_MVEBU && !ARM64 |
65 | help | 75 | help |
66 | Select this to enable cpuidle on Armada 370, 38x and XP processors. | 76 | Select this to enable cpuidle on Armada 370, 38x and XP processors. |
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64 deleted file mode 100644 index 6effb3656735..000000000000 --- a/drivers/cpuidle/Kconfig.arm64 +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | # | ||
2 | # ARM64 CPU Idle drivers | ||
3 | # | ||
4 | |||
5 | config ARM64_CPUIDLE | ||
6 | bool "Generic ARM64 CPU idle Driver" | ||
7 | select DT_IDLE_STATES | ||
8 | help | ||
9 | Select this to enable generic cpuidle driver for ARM64. | ||
10 | It provides a generic idle driver whose idle states are configured | ||
11 | at run-time through DT nodes. The CPUidle suspend backend is | ||
12 | initialized by calling the CPU operations init idle hook | ||
13 | provided by architecture code. | ||
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 4d177b916f75..3ba81b1dffad 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile | |||
@@ -17,16 +17,13 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o | |||
17 | obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o | 17 | obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o |
18 | obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o | 18 | obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o |
19 | obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o | 19 | obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o |
20 | obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o | ||
20 | 21 | ||
21 | ############################################################################### | 22 | ############################################################################### |
22 | # MIPS drivers | 23 | # MIPS drivers |
23 | obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o | 24 | obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o |
24 | 25 | ||
25 | ############################################################################### | 26 | ############################################################################### |
26 | # ARM64 drivers | ||
27 | obj-$(CONFIG_ARM64_CPUIDLE) += cpuidle-arm64.o | ||
28 | |||
29 | ############################################################################### | ||
30 | # POWERPC drivers | 27 | # POWERPC drivers |
31 | obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o | 28 | obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o |
32 | obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o | 29 | obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o |
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm.c index 39a2c62716c3..545069d5fdfb 100644 --- a/drivers/cpuidle/cpuidle-arm64.c +++ b/drivers/cpuidle/cpuidle-arm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ARM64 generic CPU idle driver. | 2 | * ARM/ARM64 generic CPU idle driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2014 ARM Ltd. | 4 | * Copyright (C) 2014 ARM Ltd. |
5 | * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 5 | * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
@@ -9,7 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) "CPUidle arm64: " fmt | 12 | #define pr_fmt(fmt) "CPUidle arm: " fmt |
13 | 13 | ||
14 | #include <linux/cpuidle.h> | 14 | #include <linux/cpuidle.h> |
15 | #include <linux/cpumask.h> | 15 | #include <linux/cpumask.h> |
@@ -17,13 +17,14 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | #include <asm/cpuidle.h> | 22 | #include <asm/cpuidle.h> |
22 | 23 | ||
23 | #include "dt_idle_states.h" | 24 | #include "dt_idle_states.h" |
24 | 25 | ||
25 | /* | 26 | /* |
26 | * arm64_enter_idle_state - Programs CPU to enter the specified state | 27 | * arm_enter_idle_state - Programs CPU to enter the specified state |
27 | * | 28 | * |
28 | * dev: cpuidle device | 29 | * dev: cpuidle device |
29 | * drv: cpuidle driver | 30 | * drv: cpuidle driver |
@@ -32,8 +33,8 @@ | |||
32 | * Called from the CPUidle framework to program the device to the | 33 | * Called from the CPUidle framework to program the device to the |
33 | * specified target state selected by the governor. | 34 | * specified target state selected by the governor. |
34 | */ | 35 | */ |
35 | static int arm64_enter_idle_state(struct cpuidle_device *dev, | 36 | static int arm_enter_idle_state(struct cpuidle_device *dev, |
36 | struct cpuidle_driver *drv, int idx) | 37 | struct cpuidle_driver *drv, int idx) |
37 | { | 38 | { |
38 | int ret; | 39 | int ret; |
39 | 40 | ||
@@ -49,7 +50,7 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev, | |||
49 | * call the CPU ops suspend protocol with idle index as a | 50 | * call the CPU ops suspend protocol with idle index as a |
50 | * parameter. | 51 | * parameter. |
51 | */ | 52 | */ |
52 | ret = cpu_suspend(idx); | 53 | arm_cpuidle_suspend(idx); |
53 | 54 | ||
54 | cpu_pm_exit(); | 55 | cpu_pm_exit(); |
55 | } | 56 | } |
@@ -57,8 +58,8 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev, | |||
57 | return ret ? -1 : idx; | 58 | return ret ? -1 : idx; |
58 | } | 59 | } |
59 | 60 | ||
60 | static struct cpuidle_driver arm64_idle_driver = { | 61 | static struct cpuidle_driver arm_idle_driver = { |
61 | .name = "arm64_idle", | 62 | .name = "arm_idle", |
62 | .owner = THIS_MODULE, | 63 | .owner = THIS_MODULE, |
63 | /* | 64 | /* |
64 | * State at index 0 is standby wfi and considered standard | 65 | * State at index 0 is standby wfi and considered standard |
@@ -68,32 +69,33 @@ static struct cpuidle_driver arm64_idle_driver = { | |||
68 | * handler for idle state index 0. | 69 | * handler for idle state index 0. |
69 | */ | 70 | */ |
70 | .states[0] = { | 71 | .states[0] = { |
71 | .enter = arm64_enter_idle_state, | 72 | .enter = arm_enter_idle_state, |
72 | .exit_latency = 1, | 73 | .exit_latency = 1, |
73 | .target_residency = 1, | 74 | .target_residency = 1, |
74 | .power_usage = UINT_MAX, | 75 | .power_usage = UINT_MAX, |
75 | .name = "WFI", | 76 | .name = "WFI", |
76 | .desc = "ARM64 WFI", | 77 | .desc = "ARM WFI", |
77 | } | 78 | } |
78 | }; | 79 | }; |
79 | 80 | ||
80 | static const struct of_device_id arm64_idle_state_match[] __initconst = { | 81 | static const struct of_device_id arm_idle_state_match[] __initconst = { |
81 | { .compatible = "arm,idle-state", | 82 | { .compatible = "arm,idle-state", |
82 | .data = arm64_enter_idle_state }, | 83 | .data = arm_enter_idle_state }, |
83 | { }, | 84 | { }, |
84 | }; | 85 | }; |
85 | 86 | ||
86 | /* | 87 | /* |
87 | * arm64_idle_init | 88 | * arm_idle_init |
88 | * | 89 | * |
89 | * Registers the arm64 specific cpuidle driver with the cpuidle | 90 | * Registers the arm specific cpuidle driver with the cpuidle |
90 | * framework. It relies on core code to parse the idle states | 91 | * framework. It relies on core code to parse the idle states |
91 | * and initialize them using driver data structures accordingly. | 92 | * and initialize them using driver data structures accordingly. |
92 | */ | 93 | */ |
93 | static int __init arm64_idle_init(void) | 94 | static int __init arm_idle_init(void) |
94 | { | 95 | { |
95 | int cpu, ret; | 96 | int cpu, ret; |
96 | struct cpuidle_driver *drv = &arm64_idle_driver; | 97 | struct cpuidle_driver *drv = &arm_idle_driver; |
98 | struct cpuidle_device *dev; | ||
97 | 99 | ||
98 | /* | 100 | /* |
99 | * Initialize idle states data, starting at index 1. | 101 | * Initialize idle states data, starting at index 1. |
@@ -101,22 +103,61 @@ static int __init arm64_idle_init(void) | |||
101 | * let the driver initialization fail accordingly since there is no | 103 | * let the driver initialization fail accordingly since there is no |
102 | * reason to initialize the idle driver if only wfi is supported. | 104 | * reason to initialize the idle driver if only wfi is supported. |
103 | */ | 105 | */ |
104 | ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1); | 106 | ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); |
105 | if (ret <= 0) | 107 | if (ret <= 0) |
106 | return ret ? : -ENODEV; | 108 | return ret ? : -ENODEV; |
107 | 109 | ||
110 | ret = cpuidle_register_driver(drv); | ||
111 | if (ret) { | ||
112 | pr_err("Failed to register cpuidle driver\n"); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
108 | /* | 116 | /* |
109 | * Call arch CPU operations in order to initialize | 117 | * Call arch CPU operations in order to initialize |
110 | * idle states suspend back-end specific data | 118 | * idle states suspend back-end specific data |
111 | */ | 119 | */ |
112 | for_each_possible_cpu(cpu) { | 120 | for_each_possible_cpu(cpu) { |
113 | ret = cpu_init_idle(cpu); | 121 | ret = arm_cpuidle_init(cpu); |
122 | |||
123 | /* | ||
124 | * Skip the cpuidle device initialization if the reported | ||
125 | * failure is a HW misconfiguration/breakage (-ENXIO). | ||
126 | */ | ||
127 | if (ret == -ENXIO) | ||
128 | continue; | ||
129 | |||
114 | if (ret) { | 130 | if (ret) { |
115 | pr_err("CPU %d failed to init idle CPU ops\n", cpu); | 131 | pr_err("CPU %d failed to init idle CPU ops\n", cpu); |
116 | return ret; | 132 | goto out_fail; |
133 | } | ||
134 | |||
135 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
136 | if (!dev) { | ||
137 | pr_err("Failed to allocate cpuidle device\n"); | ||
138 | goto out_fail; | ||
139 | } | ||
140 | dev->cpu = cpu; | ||
141 | |||
142 | ret = cpuidle_register_device(dev); | ||
143 | if (ret) { | ||
144 | pr_err("Failed to register cpuidle device for CPU %d\n", | ||
145 | cpu); | ||
146 | kfree(dev); | ||
147 | goto out_fail; | ||
117 | } | 148 | } |
118 | } | 149 | } |
119 | 150 | ||
120 | return cpuidle_register(drv, NULL); | 151 | return 0; |
152 | out_fail: | ||
153 | while (--cpu >= 0) { | ||
154 | dev = per_cpu(cpuidle_devices, cpu); | ||
155 | cpuidle_unregister_device(dev); | ||
156 | kfree(dev); | ||
157 | } | ||
158 | |||
159 | cpuidle_unregister_driver(drv); | ||
160 | |||
161 | return ret; | ||
121 | } | 162 | } |
122 | device_initcall(arm64_idle_init); | 163 | device_initcall(arm_idle_init); |
diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c index aae7bfc1ea36..f2446c78d87c 100644 --- a/drivers/cpuidle/cpuidle-at91.c +++ b/drivers/cpuidle/cpuidle-at91.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/cpuidle.h> | 19 | #include <linux/cpuidle.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <asm/proc-fns.h> | ||
23 | #include <asm/cpuidle.h> | 22 | #include <asm/cpuidle.h> |
24 | 23 | ||
25 | #define AT91_MAX_STATES 2 | 24 | #define AT91_MAX_STATES 2 |
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c index 26f5f29fdb03..0c06ea2f50bb 100644 --- a/drivers/cpuidle/cpuidle-exynos.c +++ b/drivers/cpuidle/cpuidle-exynos.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/platform_data/cpuidle-exynos.h> | 20 | #include <linux/platform_data/cpuidle-exynos.h> |
21 | 21 | ||
22 | #include <asm/proc-fns.h> | ||
23 | #include <asm/suspend.h> | 22 | #include <asm/suspend.h> |
24 | #include <asm/cpuidle.h> | 23 | #include <asm/cpuidle.h> |
25 | 24 | ||
diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c index cea0a6c4b1db..d23d8f468c12 100644 --- a/drivers/cpuidle/cpuidle-kirkwood.c +++ b/drivers/cpuidle/cpuidle-kirkwood.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/cpuidle.h> | 21 | #include <linux/cpuidle.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/export.h> | 23 | #include <linux/export.h> |
24 | #include <asm/proc-fns.h> | ||
25 | #include <asm/cpuidle.h> | 24 | #include <asm/cpuidle.h> |
26 | 25 | ||
27 | #define KIRKWOOD_MAX_STATES 2 | 26 | #define KIRKWOOD_MAX_STATES 2 |
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c index 66f81e410f0d..8bf895c0017d 100644 --- a/drivers/cpuidle/cpuidle-ux500.c +++ b/drivers/cpuidle/cpuidle-ux500.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | 20 | ||
21 | #include <asm/cpuidle.h> | 21 | #include <asm/cpuidle.h> |
22 | #include <asm/proc-fns.h> | ||
23 | 22 | ||
24 | static atomic_t master = ATOMIC_INIT(0); | 23 | static atomic_t master = ATOMIC_INIT(0); |
25 | static DEFINE_SPINLOCK(master_lock); | 24 | static DEFINE_SPINLOCK(master_lock); |
diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c index 002b8c9f98f5..543292b1d38e 100644 --- a/drivers/cpuidle/cpuidle-zynq.c +++ b/drivers/cpuidle/cpuidle-zynq.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/cpuidle.h> | 29 | #include <linux/cpuidle.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <asm/proc-fns.h> | ||
32 | #include <asm/cpuidle.h> | 31 | #include <asm/cpuidle.h> |
33 | 32 | ||
34 | #define ZYNQ_MAX_STATES 2 | 33 | #define ZYNQ_MAX_STATES 2 |
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 30b538d8cc90..ca1b362d77e2 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -392,7 +392,6 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type, | |||
392 | /** | 392 | /** |
393 | * _remove_devfreq() - Remove devfreq from the list and release its resources. | 393 | * _remove_devfreq() - Remove devfreq from the list and release its resources. |
394 | * @devfreq: the devfreq struct | 394 | * @devfreq: the devfreq struct |
395 | * @skip: skip calling device_unregister(). | ||
396 | */ | 395 | */ |
397 | static void _remove_devfreq(struct devfreq *devfreq) | 396 | static void _remove_devfreq(struct devfreq *devfreq) |
398 | { | 397 | { |
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index ad8347385f53..7d99d13bacd8 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c | |||
@@ -194,7 +194,7 @@ static int exynos_ppmu_get_event(struct devfreq_event_dev *edev, | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | static struct devfreq_event_ops exynos_ppmu_ops = { | 197 | static const struct devfreq_event_ops exynos_ppmu_ops = { |
198 | .disable = exynos_ppmu_disable, | 198 | .disable = exynos_ppmu_disable, |
199 | .set_event = exynos_ppmu_set_event, | 199 | .set_event = exynos_ppmu_set_event, |
200 | .get_event = exynos_ppmu_get_event, | 200 | .get_event = exynos_ppmu_get_event, |
diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c index 34790961af5a..13a1a6e8108c 100644 --- a/drivers/devfreq/tegra-devfreq.c +++ b/drivers/devfreq/tegra-devfreq.c | |||
@@ -62,7 +62,8 @@ | |||
62 | #define ACTMON_BELOW_WMARK_WINDOW 3 | 62 | #define ACTMON_BELOW_WMARK_WINDOW 3 |
63 | #define ACTMON_BOOST_FREQ_STEP 16000 | 63 | #define ACTMON_BOOST_FREQ_STEP 16000 |
64 | 64 | ||
65 | /* activity counter is incremented every 256 memory transactions, and each | 65 | /* |
66 | * Activity counter is incremented every 256 memory transactions, and each | ||
66 | * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is | 67 | * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is |
67 | * 4 * 256 = 1024. | 68 | * 4 * 256 = 1024. |
68 | */ | 69 | */ |
@@ -85,16 +86,25 @@ | |||
85 | * struct tegra_devfreq_device_config - configuration specific to an ACTMON | 86 | * struct tegra_devfreq_device_config - configuration specific to an ACTMON |
86 | * device | 87 | * device |
87 | * | 88 | * |
88 | * Coefficients and thresholds are in % | 89 | * Coefficients and thresholds are percentages unless otherwise noted |
89 | */ | 90 | */ |
90 | struct tegra_devfreq_device_config { | 91 | struct tegra_devfreq_device_config { |
91 | u32 offset; | 92 | u32 offset; |
92 | u32 irq_mask; | 93 | u32 irq_mask; |
93 | 94 | ||
95 | /* Factors applied to boost_freq every consecutive watermark breach */ | ||
94 | unsigned int boost_up_coeff; | 96 | unsigned int boost_up_coeff; |
95 | unsigned int boost_down_coeff; | 97 | unsigned int boost_down_coeff; |
98 | |||
99 | /* Define the watermark bounds when applied to the current avg */ | ||
96 | unsigned int boost_up_threshold; | 100 | unsigned int boost_up_threshold; |
97 | unsigned int boost_down_threshold; | 101 | unsigned int boost_down_threshold; |
102 | |||
103 | /* | ||
104 | * Threshold of activity (cycles) below which the CPU frequency isn't | ||
105 | * to be taken into account. This is to avoid increasing the EMC | ||
106 | * frequency when the CPU is very busy but not accessing the bus often. | ||
107 | */ | ||
98 | u32 avg_dependency_threshold; | 108 | u32 avg_dependency_threshold; |
99 | }; | 109 | }; |
100 | 110 | ||
@@ -105,7 +115,7 @@ enum tegra_actmon_device { | |||
105 | 115 | ||
106 | static struct tegra_devfreq_device_config actmon_device_configs[] = { | 116 | static struct tegra_devfreq_device_config actmon_device_configs[] = { |
107 | { | 117 | { |
108 | /* MCALL */ | 118 | /* MCALL: All memory accesses (including from the CPUs) */ |
109 | .offset = 0x1c0, | 119 | .offset = 0x1c0, |
110 | .irq_mask = 1 << 26, | 120 | .irq_mask = 1 << 26, |
111 | .boost_up_coeff = 200, | 121 | .boost_up_coeff = 200, |
@@ -114,7 +124,7 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = { | |||
114 | .boost_down_threshold = 40, | 124 | .boost_down_threshold = 40, |
115 | }, | 125 | }, |
116 | { | 126 | { |
117 | /* MCCPU */ | 127 | /* MCCPU: memory accesses from the CPUs */ |
118 | .offset = 0x200, | 128 | .offset = 0x200, |
119 | .irq_mask = 1 << 25, | 129 | .irq_mask = 1 << 25, |
120 | .boost_up_coeff = 800, | 130 | .boost_up_coeff = 800, |
@@ -132,25 +142,29 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = { | |||
132 | */ | 142 | */ |
133 | struct tegra_devfreq_device { | 143 | struct tegra_devfreq_device { |
134 | const struct tegra_devfreq_device_config *config; | 144 | const struct tegra_devfreq_device_config *config; |
145 | void __iomem *regs; | ||
146 | spinlock_t lock; | ||
147 | |||
148 | /* Average event count sampled in the last interrupt */ | ||
149 | u32 avg_count; | ||
135 | 150 | ||
136 | void __iomem *regs; | 151 | /* |
137 | u32 avg_band_freq; | 152 | * Extra frequency to increase the target by due to consecutive |
138 | u32 avg_count; | 153 | * watermark breaches. |
154 | */ | ||
155 | unsigned long boost_freq; | ||
139 | 156 | ||
140 | unsigned long target_freq; | 157 | /* Optimal frequency calculated from the stats for this device */ |
141 | unsigned long boost_freq; | 158 | unsigned long target_freq; |
142 | }; | 159 | }; |
143 | 160 | ||
144 | struct tegra_devfreq { | 161 | struct tegra_devfreq { |
145 | struct devfreq *devfreq; | 162 | struct devfreq *devfreq; |
146 | 163 | ||
147 | struct platform_device *pdev; | ||
148 | struct reset_control *reset; | 164 | struct reset_control *reset; |
149 | struct clk *clock; | 165 | struct clk *clock; |
150 | void __iomem *regs; | 166 | void __iomem *regs; |
151 | 167 | ||
152 | spinlock_t lock; | ||
153 | |||
154 | struct clk *emc_clock; | 168 | struct clk *emc_clock; |
155 | unsigned long max_freq; | 169 | unsigned long max_freq; |
156 | unsigned long cur_freq; | 170 | unsigned long cur_freq; |
@@ -174,19 +188,43 @@ static struct tegra_actmon_emc_ratio actmon_emc_ratios[] = { | |||
174 | { 250000, 100000 }, | 188 | { 250000, 100000 }, |
175 | }; | 189 | }; |
176 | 190 | ||
191 | static u32 actmon_readl(struct tegra_devfreq *tegra, u32 offset) | ||
192 | { | ||
193 | return readl(tegra->regs + offset); | ||
194 | } | ||
195 | |||
196 | static void actmon_writel(struct tegra_devfreq *tegra, u32 val, u32 offset) | ||
197 | { | ||
198 | writel(val, tegra->regs + offset); | ||
199 | } | ||
200 | |||
201 | static u32 device_readl(struct tegra_devfreq_device *dev, u32 offset) | ||
202 | { | ||
203 | return readl(dev->regs + offset); | ||
204 | } | ||
205 | |||
206 | static void device_writel(struct tegra_devfreq_device *dev, u32 val, | ||
207 | u32 offset) | ||
208 | { | ||
209 | writel(val, dev->regs + offset); | ||
210 | } | ||
211 | |||
177 | static unsigned long do_percent(unsigned long val, unsigned int pct) | 212 | static unsigned long do_percent(unsigned long val, unsigned int pct) |
178 | { | 213 | { |
179 | return val * pct / 100; | 214 | return val * pct / 100; |
180 | } | 215 | } |
181 | 216 | ||
182 | static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq_device *dev) | 217 | static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq *tegra, |
218 | struct tegra_devfreq_device *dev) | ||
183 | { | 219 | { |
184 | u32 avg = dev->avg_count; | 220 | u32 avg = dev->avg_count; |
185 | u32 band = dev->avg_band_freq * ACTMON_SAMPLING_PERIOD; | 221 | u32 avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; |
222 | u32 band = avg_band_freq * ACTMON_SAMPLING_PERIOD; | ||
223 | |||
224 | device_writel(dev, avg + band, ACTMON_DEV_AVG_UPPER_WMARK); | ||
186 | 225 | ||
187 | writel(avg + band, dev->regs + ACTMON_DEV_AVG_UPPER_WMARK); | 226 | avg = max(dev->avg_count, band); |
188 | avg = max(avg, band); | 227 | device_writel(dev, avg - band, ACTMON_DEV_AVG_LOWER_WMARK); |
189 | writel(avg - band, dev->regs + ACTMON_DEV_AVG_LOWER_WMARK); | ||
190 | } | 228 | } |
191 | 229 | ||
192 | static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, | 230 | static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, |
@@ -194,96 +232,96 @@ static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, | |||
194 | { | 232 | { |
195 | u32 val = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; | 233 | u32 val = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; |
196 | 234 | ||
197 | writel(do_percent(val, dev->config->boost_up_threshold), | 235 | device_writel(dev, do_percent(val, dev->config->boost_up_threshold), |
198 | dev->regs + ACTMON_DEV_UPPER_WMARK); | 236 | ACTMON_DEV_UPPER_WMARK); |
199 | 237 | ||
200 | writel(do_percent(val, dev->config->boost_down_threshold), | 238 | device_writel(dev, do_percent(val, dev->config->boost_down_threshold), |
201 | dev->regs + ACTMON_DEV_LOWER_WMARK); | 239 | ACTMON_DEV_LOWER_WMARK); |
202 | } | 240 | } |
203 | 241 | ||
204 | static void actmon_write_barrier(struct tegra_devfreq *tegra) | 242 | static void actmon_write_barrier(struct tegra_devfreq *tegra) |
205 | { | 243 | { |
206 | /* ensure the update has reached the ACTMON */ | 244 | /* ensure the update has reached the ACTMON */ |
207 | wmb(); | 245 | wmb(); |
208 | readl(tegra->regs + ACTMON_GLB_STATUS); | 246 | actmon_readl(tegra, ACTMON_GLB_STATUS); |
209 | } | 247 | } |
210 | 248 | ||
211 | static irqreturn_t actmon_isr(int irq, void *data) | 249 | static void actmon_isr_device(struct tegra_devfreq *tegra, |
250 | struct tegra_devfreq_device *dev) | ||
212 | { | 251 | { |
213 | struct tegra_devfreq *tegra = data; | ||
214 | struct tegra_devfreq_device *dev = NULL; | ||
215 | unsigned long flags; | 252 | unsigned long flags; |
216 | u32 val; | 253 | u32 intr_status, dev_ctrl; |
217 | unsigned int i; | ||
218 | |||
219 | val = readl(tegra->regs + ACTMON_GLB_STATUS); | ||
220 | |||
221 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
222 | if (val & tegra->devices[i].config->irq_mask) { | ||
223 | dev = tegra->devices + i; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if (!dev) | ||
229 | return IRQ_NONE; | ||
230 | 254 | ||
231 | spin_lock_irqsave(&tegra->lock, flags); | 255 | spin_lock_irqsave(&dev->lock, flags); |
232 | 256 | ||
233 | dev->avg_count = readl(dev->regs + ACTMON_DEV_AVG_COUNT); | 257 | dev->avg_count = device_readl(dev, ACTMON_DEV_AVG_COUNT); |
234 | tegra_devfreq_update_avg_wmark(dev); | 258 | tegra_devfreq_update_avg_wmark(tegra, dev); |
235 | 259 | ||
236 | val = readl(dev->regs + ACTMON_DEV_INTR_STATUS); | 260 | intr_status = device_readl(dev, ACTMON_DEV_INTR_STATUS); |
237 | if (val & ACTMON_DEV_INTR_CONSECUTIVE_UPPER) { | 261 | dev_ctrl = device_readl(dev, ACTMON_DEV_CTRL); |
238 | val = readl(dev->regs + ACTMON_DEV_CTRL) | | ||
239 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN | | ||
240 | ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
241 | 262 | ||
263 | if (intr_status & ACTMON_DEV_INTR_CONSECUTIVE_UPPER) { | ||
242 | /* | 264 | /* |
243 | * new_boost = min(old_boost * up_coef + step, max_freq) | 265 | * new_boost = min(old_boost * up_coef + step, max_freq) |
244 | */ | 266 | */ |
245 | dev->boost_freq = do_percent(dev->boost_freq, | 267 | dev->boost_freq = do_percent(dev->boost_freq, |
246 | dev->config->boost_up_coeff); | 268 | dev->config->boost_up_coeff); |
247 | dev->boost_freq += ACTMON_BOOST_FREQ_STEP; | 269 | dev->boost_freq += ACTMON_BOOST_FREQ_STEP; |
248 | if (dev->boost_freq >= tegra->max_freq) { | ||
249 | dev->boost_freq = tegra->max_freq; | ||
250 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
251 | } | ||
252 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
253 | } else if (val & ACTMON_DEV_INTR_CONSECUTIVE_LOWER) { | ||
254 | val = readl(dev->regs + ACTMON_DEV_CTRL) | | ||
255 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN | | ||
256 | ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
257 | 270 | ||
271 | dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
272 | |||
273 | if (dev->boost_freq >= tegra->max_freq) | ||
274 | dev->boost_freq = tegra->max_freq; | ||
275 | else | ||
276 | dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
277 | } else if (intr_status & ACTMON_DEV_INTR_CONSECUTIVE_LOWER) { | ||
258 | /* | 278 | /* |
259 | * new_boost = old_boost * down_coef | 279 | * new_boost = old_boost * down_coef |
260 | * or 0 if (old_boost * down_coef < step / 2) | 280 | * or 0 if (old_boost * down_coef < step / 2) |
261 | */ | 281 | */ |
262 | dev->boost_freq = do_percent(dev->boost_freq, | 282 | dev->boost_freq = do_percent(dev->boost_freq, |
263 | dev->config->boost_down_coeff); | 283 | dev->config->boost_down_coeff); |
264 | if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1)) { | 284 | |
285 | dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
286 | |||
287 | if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1)) | ||
265 | dev->boost_freq = 0; | 288 | dev->boost_freq = 0; |
266 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | 289 | else |
267 | } | 290 | dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; |
268 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
269 | } | 291 | } |
270 | 292 | ||
271 | if (dev->config->avg_dependency_threshold) { | 293 | if (dev->config->avg_dependency_threshold) { |
272 | val = readl(dev->regs + ACTMON_DEV_CTRL); | ||
273 | if (dev->avg_count >= dev->config->avg_dependency_threshold) | 294 | if (dev->avg_count >= dev->config->avg_dependency_threshold) |
274 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | 295 | dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; |
275 | else if (dev->boost_freq == 0) | 296 | else if (dev->boost_freq == 0) |
276 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | 297 | dev_ctrl &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; |
277 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
278 | } | 298 | } |
279 | 299 | ||
280 | writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS); | 300 | device_writel(dev, dev_ctrl, ACTMON_DEV_CTRL); |
301 | |||
302 | device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS); | ||
281 | 303 | ||
282 | actmon_write_barrier(tegra); | 304 | actmon_write_barrier(tegra); |
283 | 305 | ||
284 | spin_unlock_irqrestore(&tegra->lock, flags); | 306 | spin_unlock_irqrestore(&dev->lock, flags); |
307 | } | ||
285 | 308 | ||
286 | return IRQ_WAKE_THREAD; | 309 | static irqreturn_t actmon_isr(int irq, void *data) |
310 | { | ||
311 | struct tegra_devfreq *tegra = data; | ||
312 | bool handled = false; | ||
313 | unsigned int i; | ||
314 | u32 val; | ||
315 | |||
316 | val = actmon_readl(tegra, ACTMON_GLB_STATUS); | ||
317 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
318 | if (val & tegra->devices[i].config->irq_mask) { | ||
319 | actmon_isr_device(tegra, tegra->devices + i); | ||
320 | handled = true; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | return handled ? IRQ_WAKE_THREAD : IRQ_NONE; | ||
287 | } | 325 | } |
288 | 326 | ||
289 | static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra, | 327 | static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra, |
@@ -317,7 +355,7 @@ static void actmon_update_target(struct tegra_devfreq *tegra, | |||
317 | static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); | 355 | static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); |
318 | } | 356 | } |
319 | 357 | ||
320 | spin_lock_irqsave(&tegra->lock, flags); | 358 | spin_lock_irqsave(&dev->lock, flags); |
321 | 359 | ||
322 | dev->target_freq = dev->avg_count / ACTMON_SAMPLING_PERIOD; | 360 | dev->target_freq = dev->avg_count / ACTMON_SAMPLING_PERIOD; |
323 | avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold; | 361 | avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold; |
@@ -327,7 +365,7 @@ static void actmon_update_target(struct tegra_devfreq *tegra, | |||
327 | if (dev->avg_count >= dev->config->avg_dependency_threshold) | 365 | if (dev->avg_count >= dev->config->avg_dependency_threshold) |
328 | dev->target_freq = max(dev->target_freq, static_cpu_emc_freq); | 366 | dev->target_freq = max(dev->target_freq, static_cpu_emc_freq); |
329 | 367 | ||
330 | spin_unlock_irqrestore(&tegra->lock, flags); | 368 | spin_unlock_irqrestore(&dev->lock, flags); |
331 | } | 369 | } |
332 | 370 | ||
333 | static irqreturn_t actmon_thread_isr(int irq, void *data) | 371 | static irqreturn_t actmon_thread_isr(int irq, void *data) |
@@ -345,131 +383,110 @@ static int tegra_actmon_rate_notify_cb(struct notifier_block *nb, | |||
345 | unsigned long action, void *ptr) | 383 | unsigned long action, void *ptr) |
346 | { | 384 | { |
347 | struct clk_notifier_data *data = ptr; | 385 | struct clk_notifier_data *data = ptr; |
348 | struct tegra_devfreq *tegra = container_of(nb, struct tegra_devfreq, | 386 | struct tegra_devfreq *tegra; |
349 | rate_change_nb); | 387 | struct tegra_devfreq_device *dev; |
350 | unsigned int i; | 388 | unsigned int i; |
351 | unsigned long flags; | 389 | unsigned long flags; |
352 | 390 | ||
353 | spin_lock_irqsave(&tegra->lock, flags); | 391 | if (action != POST_RATE_CHANGE) |
392 | return NOTIFY_OK; | ||
354 | 393 | ||
355 | switch (action) { | 394 | tegra = container_of(nb, struct tegra_devfreq, rate_change_nb); |
356 | case POST_RATE_CHANGE: | ||
357 | tegra->cur_freq = data->new_rate / KHZ; | ||
358 | 395 | ||
359 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) | 396 | tegra->cur_freq = data->new_rate / KHZ; |
360 | tegra_devfreq_update_wmark(tegra, tegra->devices + i); | ||
361 | 397 | ||
362 | actmon_write_barrier(tegra); | 398 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { |
363 | break; | 399 | dev = &tegra->devices[i]; |
364 | case PRE_RATE_CHANGE: | ||
365 | /* fall through */ | ||
366 | case ABORT_RATE_CHANGE: | ||
367 | break; | ||
368 | }; | ||
369 | 400 | ||
370 | spin_unlock_irqrestore(&tegra->lock, flags); | 401 | spin_lock_irqsave(&dev->lock, flags); |
402 | tegra_devfreq_update_wmark(tegra, dev); | ||
403 | spin_unlock_irqrestore(&dev->lock, flags); | ||
404 | } | ||
405 | |||
406 | actmon_write_barrier(tegra); | ||
371 | 407 | ||
372 | return NOTIFY_OK; | 408 | return NOTIFY_OK; |
373 | } | 409 | } |
374 | 410 | ||
375 | static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, | 411 | static void tegra_actmon_enable_interrupts(struct tegra_devfreq *tegra) |
376 | struct tegra_devfreq_device *dev) | ||
377 | { | 412 | { |
413 | struct tegra_devfreq_device *dev; | ||
378 | u32 val; | 414 | u32 val; |
415 | unsigned int i; | ||
379 | 416 | ||
380 | dev->avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; | 417 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { |
381 | dev->target_freq = tegra->cur_freq; | 418 | dev = &tegra->devices[i]; |
382 | |||
383 | dev->avg_count = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; | ||
384 | writel(dev->avg_count, dev->regs + ACTMON_DEV_INIT_AVG); | ||
385 | |||
386 | tegra_devfreq_update_avg_wmark(dev); | ||
387 | tegra_devfreq_update_wmark(tegra, dev); | ||
388 | |||
389 | writel(ACTMON_COUNT_WEIGHT, dev->regs + ACTMON_DEV_COUNT_WEIGHT); | ||
390 | writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS); | ||
391 | |||
392 | val = 0; | ||
393 | val |= ACTMON_DEV_CTRL_ENB_PERIODIC | | ||
394 | ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN | | ||
395 | ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN; | ||
396 | val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1) | ||
397 | << ACTMON_DEV_CTRL_K_VAL_SHIFT; | ||
398 | val |= (ACTMON_BELOW_WMARK_WINDOW - 1) | ||
399 | << ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT; | ||
400 | val |= (ACTMON_ABOVE_WMARK_WINDOW - 1) | ||
401 | << ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT; | ||
402 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN | | ||
403 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
404 | |||
405 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
406 | 419 | ||
407 | actmon_write_barrier(tegra); | 420 | val = device_readl(dev, ACTMON_DEV_CTRL); |
421 | val |= ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN; | ||
422 | val |= ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN; | ||
423 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
424 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
408 | 425 | ||
409 | val = readl(dev->regs + ACTMON_DEV_CTRL); | 426 | device_writel(dev, val, ACTMON_DEV_CTRL); |
410 | val |= ACTMON_DEV_CTRL_ENB; | 427 | } |
411 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
412 | 428 | ||
413 | actmon_write_barrier(tegra); | 429 | actmon_write_barrier(tegra); |
414 | } | 430 | } |
415 | 431 | ||
416 | static int tegra_devfreq_suspend(struct device *dev) | 432 | static void tegra_actmon_disable_interrupts(struct tegra_devfreq *tegra) |
417 | { | 433 | { |
418 | struct platform_device *pdev; | 434 | struct tegra_devfreq_device *dev; |
419 | struct tegra_devfreq *tegra; | ||
420 | struct tegra_devfreq_device *actmon_dev; | ||
421 | unsigned int i; | ||
422 | u32 val; | 435 | u32 val; |
423 | 436 | unsigned int i; | |
424 | pdev = container_of(dev, struct platform_device, dev); | ||
425 | tegra = platform_get_drvdata(pdev); | ||
426 | 437 | ||
427 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | 438 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { |
428 | actmon_dev = &tegra->devices[i]; | 439 | dev = &tegra->devices[i]; |
429 | |||
430 | val = readl(actmon_dev->regs + ACTMON_DEV_CTRL); | ||
431 | val &= ~ACTMON_DEV_CTRL_ENB; | ||
432 | writel(val, actmon_dev->regs + ACTMON_DEV_CTRL); | ||
433 | 440 | ||
434 | writel(ACTMON_INTR_STATUS_CLEAR, | 441 | val = device_readl(dev, ACTMON_DEV_CTRL); |
435 | actmon_dev->regs + ACTMON_DEV_INTR_STATUS); | 442 | val &= ~ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN; |
443 | val &= ~ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN; | ||
444 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
445 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
436 | 446 | ||
437 | actmon_write_barrier(tegra); | 447 | device_writel(dev, val, ACTMON_DEV_CTRL); |
438 | } | 448 | } |
439 | 449 | ||
440 | return 0; | 450 | actmon_write_barrier(tegra); |
441 | } | 451 | } |
442 | 452 | ||
443 | static int tegra_devfreq_resume(struct device *dev) | 453 | static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, |
454 | struct tegra_devfreq_device *dev) | ||
444 | { | 455 | { |
445 | struct platform_device *pdev; | 456 | u32 val = 0; |
446 | struct tegra_devfreq *tegra; | ||
447 | struct tegra_devfreq_device *actmon_dev; | ||
448 | unsigned int i; | ||
449 | 457 | ||
450 | pdev = container_of(dev, struct platform_device, dev); | 458 | dev->target_freq = tegra->cur_freq; |
451 | tegra = platform_get_drvdata(pdev); | ||
452 | 459 | ||
453 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | 460 | dev->avg_count = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; |
454 | actmon_dev = &tegra->devices[i]; | 461 | device_writel(dev, dev->avg_count, ACTMON_DEV_INIT_AVG); |
455 | 462 | ||
456 | tegra_actmon_configure_device(tegra, actmon_dev); | 463 | tegra_devfreq_update_avg_wmark(tegra, dev); |
457 | } | 464 | tegra_devfreq_update_wmark(tegra, dev); |
458 | 465 | ||
459 | return 0; | 466 | device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT); |
467 | device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS); | ||
468 | |||
469 | val |= ACTMON_DEV_CTRL_ENB_PERIODIC; | ||
470 | val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1) | ||
471 | << ACTMON_DEV_CTRL_K_VAL_SHIFT; | ||
472 | val |= (ACTMON_BELOW_WMARK_WINDOW - 1) | ||
473 | << ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT; | ||
474 | val |= (ACTMON_ABOVE_WMARK_WINDOW - 1) | ||
475 | << ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT; | ||
476 | val |= ACTMON_DEV_CTRL_ENB; | ||
477 | |||
478 | device_writel(dev, val, ACTMON_DEV_CTRL); | ||
479 | |||
480 | actmon_write_barrier(tegra); | ||
460 | } | 481 | } |
461 | 482 | ||
462 | static int tegra_devfreq_target(struct device *dev, unsigned long *freq, | 483 | static int tegra_devfreq_target(struct device *dev, unsigned long *freq, |
463 | u32 flags) | 484 | u32 flags) |
464 | { | 485 | { |
465 | struct platform_device *pdev; | 486 | struct tegra_devfreq *tegra = dev_get_drvdata(dev); |
466 | struct tegra_devfreq *tegra; | ||
467 | struct dev_pm_opp *opp; | 487 | struct dev_pm_opp *opp; |
468 | unsigned long rate = *freq * KHZ; | 488 | unsigned long rate = *freq * KHZ; |
469 | 489 | ||
470 | pdev = container_of(dev, struct platform_device, dev); | ||
471 | tegra = platform_get_drvdata(pdev); | ||
472 | |||
473 | rcu_read_lock(); | 490 | rcu_read_lock(); |
474 | opp = devfreq_recommended_opp(dev, &rate, flags); | 491 | opp = devfreq_recommended_opp(dev, &rate, flags); |
475 | if (IS_ERR(opp)) { | 492 | if (IS_ERR(opp)) { |
@@ -480,10 +497,8 @@ static int tegra_devfreq_target(struct device *dev, unsigned long *freq, | |||
480 | rate = dev_pm_opp_get_freq(opp); | 497 | rate = dev_pm_opp_get_freq(opp); |
481 | rcu_read_unlock(); | 498 | rcu_read_unlock(); |
482 | 499 | ||
483 | /* TODO: Once we have per-user clk constraints, set a floor */ | 500 | clk_set_min_rate(tegra->emc_clock, rate); |
484 | clk_set_rate(tegra->emc_clock, rate); | 501 | clk_set_rate(tegra->emc_clock, 0); |
485 | |||
486 | /* TODO: Set voltage as well */ | ||
487 | 502 | ||
488 | return 0; | 503 | return 0; |
489 | } | 504 | } |
@@ -491,13 +506,9 @@ static int tegra_devfreq_target(struct device *dev, unsigned long *freq, | |||
491 | static int tegra_devfreq_get_dev_status(struct device *dev, | 506 | static int tegra_devfreq_get_dev_status(struct device *dev, |
492 | struct devfreq_dev_status *stat) | 507 | struct devfreq_dev_status *stat) |
493 | { | 508 | { |
494 | struct platform_device *pdev; | 509 | struct tegra_devfreq *tegra = dev_get_drvdata(dev); |
495 | struct tegra_devfreq *tegra; | ||
496 | struct tegra_devfreq_device *actmon_dev; | 510 | struct tegra_devfreq_device *actmon_dev; |
497 | 511 | ||
498 | pdev = container_of(dev, struct platform_device, dev); | ||
499 | tegra = platform_get_drvdata(pdev); | ||
500 | |||
501 | stat->current_frequency = tegra->cur_freq; | 512 | stat->current_frequency = tegra->cur_freq; |
502 | 513 | ||
503 | /* To be used by the tegra governor */ | 514 | /* To be used by the tegra governor */ |
@@ -508,7 +519,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev, | |||
508 | actmon_dev = &tegra->devices[MCALL]; | 519 | actmon_dev = &tegra->devices[MCALL]; |
509 | 520 | ||
510 | /* Number of cycles spent on memory access */ | 521 | /* Number of cycles spent on memory access */ |
511 | stat->busy_time = actmon_dev->avg_count; | 522 | stat->busy_time = device_readl(actmon_dev, ACTMON_DEV_AVG_COUNT); |
512 | 523 | ||
513 | /* The bus can be considered to be saturated way before 100% */ | 524 | /* The bus can be considered to be saturated way before 100% */ |
514 | stat->busy_time *= 100 / BUS_SATURATION_RATIO; | 525 | stat->busy_time *= 100 / BUS_SATURATION_RATIO; |
@@ -516,11 +527,19 @@ static int tegra_devfreq_get_dev_status(struct device *dev, | |||
516 | /* Number of cycles in a sampling period */ | 527 | /* Number of cycles in a sampling period */ |
517 | stat->total_time = ACTMON_SAMPLING_PERIOD * tegra->cur_freq; | 528 | stat->total_time = ACTMON_SAMPLING_PERIOD * tegra->cur_freq; |
518 | 529 | ||
530 | stat->busy_time = min(stat->busy_time, stat->total_time); | ||
531 | |||
519 | return 0; | 532 | return 0; |
520 | } | 533 | } |
521 | 534 | ||
522 | static int tegra_devfreq_get_target(struct devfreq *devfreq, | 535 | static struct devfreq_dev_profile tegra_devfreq_profile = { |
523 | unsigned long *freq) | 536 | .polling_ms = 0, |
537 | .target = tegra_devfreq_target, | ||
538 | .get_dev_status = tegra_devfreq_get_dev_status, | ||
539 | }; | ||
540 | |||
541 | static int tegra_governor_get_target(struct devfreq *devfreq, | ||
542 | unsigned long *freq) | ||
524 | { | 543 | { |
525 | struct devfreq_dev_status stat; | 544 | struct devfreq_dev_status stat; |
526 | struct tegra_devfreq *tegra; | 545 | struct tegra_devfreq *tegra; |
@@ -548,22 +567,43 @@ static int tegra_devfreq_get_target(struct devfreq *devfreq, | |||
548 | return 0; | 567 | return 0; |
549 | } | 568 | } |
550 | 569 | ||
551 | static int tegra_devfreq_event_handler(struct devfreq *devfreq, | 570 | static int tegra_governor_event_handler(struct devfreq *devfreq, |
552 | unsigned int event, void *data) | 571 | unsigned int event, void *data) |
553 | { | 572 | { |
554 | return 0; | 573 | struct tegra_devfreq *tegra; |
574 | int ret = 0; | ||
575 | |||
576 | tegra = dev_get_drvdata(devfreq->dev.parent); | ||
577 | |||
578 | switch (event) { | ||
579 | case DEVFREQ_GOV_START: | ||
580 | devfreq_monitor_start(devfreq); | ||
581 | tegra_actmon_enable_interrupts(tegra); | ||
582 | break; | ||
583 | |||
584 | case DEVFREQ_GOV_STOP: | ||
585 | tegra_actmon_disable_interrupts(tegra); | ||
586 | devfreq_monitor_stop(devfreq); | ||
587 | break; | ||
588 | |||
589 | case DEVFREQ_GOV_SUSPEND: | ||
590 | tegra_actmon_disable_interrupts(tegra); | ||
591 | devfreq_monitor_suspend(devfreq); | ||
592 | break; | ||
593 | |||
594 | case DEVFREQ_GOV_RESUME: | ||
595 | devfreq_monitor_resume(devfreq); | ||
596 | tegra_actmon_enable_interrupts(tegra); | ||
597 | break; | ||
598 | } | ||
599 | |||
600 | return ret; | ||
555 | } | 601 | } |
556 | 602 | ||
557 | static struct devfreq_governor tegra_devfreq_governor = { | 603 | static struct devfreq_governor tegra_devfreq_governor = { |
558 | .name = "tegra", | 604 | .name = "tegra_actmon", |
559 | .get_target_freq = tegra_devfreq_get_target, | 605 | .get_target_freq = tegra_governor_get_target, |
560 | .event_handler = tegra_devfreq_event_handler, | 606 | .event_handler = tegra_governor_event_handler, |
561 | }; | ||
562 | |||
563 | static struct devfreq_dev_profile tegra_devfreq_profile = { | ||
564 | .polling_ms = 0, | ||
565 | .target = tegra_devfreq_target, | ||
566 | .get_dev_status = tegra_devfreq_get_dev_status, | ||
567 | }; | 607 | }; |
568 | 608 | ||
569 | static int tegra_devfreq_probe(struct platform_device *pdev) | 609 | static int tegra_devfreq_probe(struct platform_device *pdev) |
@@ -571,8 +611,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
571 | struct tegra_devfreq *tegra; | 611 | struct tegra_devfreq *tegra; |
572 | struct tegra_devfreq_device *dev; | 612 | struct tegra_devfreq_device *dev; |
573 | struct resource *res; | 613 | struct resource *res; |
574 | unsigned long max_freq; | ||
575 | unsigned int i; | 614 | unsigned int i; |
615 | unsigned long rate; | ||
576 | int irq; | 616 | int irq; |
577 | int err; | 617 | int err; |
578 | 618 | ||
@@ -580,19 +620,11 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
580 | if (!tegra) | 620 | if (!tegra) |
581 | return -ENOMEM; | 621 | return -ENOMEM; |
582 | 622 | ||
583 | spin_lock_init(&tegra->lock); | ||
584 | |||
585 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 623 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
586 | if (!res) { | ||
587 | dev_err(&pdev->dev, "Failed to get regs resource\n"); | ||
588 | return -ENODEV; | ||
589 | } | ||
590 | 624 | ||
591 | tegra->regs = devm_ioremap_resource(&pdev->dev, res); | 625 | tegra->regs = devm_ioremap_resource(&pdev->dev, res); |
592 | if (IS_ERR(tegra->regs)) { | 626 | if (IS_ERR(tegra->regs)) |
593 | dev_err(&pdev->dev, "Failed to get IO memory\n"); | ||
594 | return PTR_ERR(tegra->regs); | 627 | return PTR_ERR(tegra->regs); |
595 | } | ||
596 | 628 | ||
597 | tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); | 629 | tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); |
598 | if (IS_ERR(tegra->reset)) { | 630 | if (IS_ERR(tegra->reset)) { |
@@ -612,11 +644,7 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
612 | return PTR_ERR(tegra->emc_clock); | 644 | return PTR_ERR(tegra->emc_clock); |
613 | } | 645 | } |
614 | 646 | ||
615 | err = of_init_opp_table(&pdev->dev); | 647 | clk_set_rate(tegra->emc_clock, ULONG_MAX); |
616 | if (err) { | ||
617 | dev_err(&pdev->dev, "Failed to init operating point table\n"); | ||
618 | return err; | ||
619 | } | ||
620 | 648 | ||
621 | tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb; | 649 | tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb; |
622 | err = clk_notifier_register(tegra->emc_clock, &tegra->rate_change_nb); | 650 | err = clk_notifier_register(tegra->emc_clock, &tegra->rate_change_nb); |
@@ -630,43 +658,41 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
630 | 658 | ||
631 | err = clk_prepare_enable(tegra->clock); | 659 | err = clk_prepare_enable(tegra->clock); |
632 | if (err) { | 660 | if (err) { |
633 | reset_control_deassert(tegra->reset); | 661 | dev_err(&pdev->dev, |
662 | "Failed to prepare and enable ACTMON clock\n"); | ||
634 | return err; | 663 | return err; |
635 | } | 664 | } |
636 | 665 | ||
637 | reset_control_deassert(tegra->reset); | 666 | reset_control_deassert(tegra->reset); |
638 | 667 | ||
639 | max_freq = clk_round_rate(tegra->emc_clock, ULONG_MAX); | 668 | tegra->max_freq = clk_round_rate(tegra->emc_clock, ULONG_MAX) / KHZ; |
640 | tegra->max_freq = max_freq / KHZ; | ||
641 | |||
642 | clk_set_rate(tegra->emc_clock, max_freq); | ||
643 | |||
644 | tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; | 669 | tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; |
645 | 670 | ||
646 | writel(ACTMON_SAMPLING_PERIOD - 1, | 671 | actmon_writel(tegra, ACTMON_SAMPLING_PERIOD - 1, |
647 | tegra->regs + ACTMON_GLB_PERIOD_CTRL); | 672 | ACTMON_GLB_PERIOD_CTRL); |
648 | 673 | ||
649 | for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { | 674 | for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { |
650 | dev = tegra->devices + i; | 675 | dev = tegra->devices + i; |
651 | dev->config = actmon_device_configs + i; | 676 | dev->config = actmon_device_configs + i; |
652 | dev->regs = tegra->regs + dev->config->offset; | 677 | dev->regs = tegra->regs + dev->config->offset; |
678 | spin_lock_init(&dev->lock); | ||
653 | 679 | ||
654 | tegra_actmon_configure_device(tegra, tegra->devices + i); | 680 | tegra_actmon_configure_device(tegra, dev); |
655 | } | 681 | } |
656 | 682 | ||
657 | err = devfreq_add_governor(&tegra_devfreq_governor); | 683 | for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) { |
658 | if (err) { | 684 | rate = clk_round_rate(tegra->emc_clock, rate); |
659 | dev_err(&pdev->dev, "Failed to add governor\n"); | 685 | dev_pm_opp_add(&pdev->dev, rate, 0); |
660 | return err; | ||
661 | } | 686 | } |
662 | 687 | ||
663 | tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); | ||
664 | tegra->devfreq = devm_devfreq_add_device(&pdev->dev, | ||
665 | &tegra_devfreq_profile, | ||
666 | "tegra", | ||
667 | NULL); | ||
668 | |||
669 | irq = platform_get_irq(pdev, 0); | 688 | irq = platform_get_irq(pdev, 0); |
689 | if (irq <= 0) { | ||
690 | dev_err(&pdev->dev, "Failed to get IRQ\n"); | ||
691 | return -ENODEV; | ||
692 | } | ||
693 | |||
694 | platform_set_drvdata(pdev, tegra); | ||
695 | |||
670 | err = devm_request_threaded_irq(&pdev->dev, irq, actmon_isr, | 696 | err = devm_request_threaded_irq(&pdev->dev, irq, actmon_isr, |
671 | actmon_thread_isr, IRQF_SHARED, | 697 | actmon_thread_isr, IRQF_SHARED, |
672 | "tegra-devfreq", tegra); | 698 | "tegra-devfreq", tegra); |
@@ -675,7 +701,11 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
675 | return err; | 701 | return err; |
676 | } | 702 | } |
677 | 703 | ||
678 | platform_set_drvdata(pdev, tegra); | 704 | tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); |
705 | tegra->devfreq = devm_devfreq_add_device(&pdev->dev, | ||
706 | &tegra_devfreq_profile, | ||
707 | "tegra_actmon", | ||
708 | NULL); | ||
679 | 709 | ||
680 | return 0; | 710 | return 0; |
681 | } | 711 | } |
@@ -683,6 +713,19 @@ static int tegra_devfreq_probe(struct platform_device *pdev) | |||
683 | static int tegra_devfreq_remove(struct platform_device *pdev) | 713 | static int tegra_devfreq_remove(struct platform_device *pdev) |
684 | { | 714 | { |
685 | struct tegra_devfreq *tegra = platform_get_drvdata(pdev); | 715 | struct tegra_devfreq *tegra = platform_get_drvdata(pdev); |
716 | int irq = platform_get_irq(pdev, 0); | ||
717 | u32 val; | ||
718 | unsigned int i; | ||
719 | |||
720 | for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { | ||
721 | val = device_readl(&tegra->devices[i], ACTMON_DEV_CTRL); | ||
722 | val &= ~ACTMON_DEV_CTRL_ENB; | ||
723 | device_writel(&tegra->devices[i], val, ACTMON_DEV_CTRL); | ||
724 | } | ||
725 | |||
726 | actmon_write_barrier(tegra); | ||
727 | |||
728 | devm_free_irq(&pdev->dev, irq, tegra); | ||
686 | 729 | ||
687 | clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb); | 730 | clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb); |
688 | 731 | ||
@@ -691,28 +734,52 @@ static int tegra_devfreq_remove(struct platform_device *pdev) | |||
691 | return 0; | 734 | return 0; |
692 | } | 735 | } |
693 | 736 | ||
694 | static SIMPLE_DEV_PM_OPS(tegra_devfreq_pm_ops, | 737 | static const struct of_device_id tegra_devfreq_of_match[] = { |
695 | tegra_devfreq_suspend, | ||
696 | tegra_devfreq_resume); | ||
697 | |||
698 | static struct of_device_id tegra_devfreq_of_match[] = { | ||
699 | { .compatible = "nvidia,tegra124-actmon" }, | 738 | { .compatible = "nvidia,tegra124-actmon" }, |
700 | { }, | 739 | { }, |
701 | }; | 740 | }; |
702 | 741 | ||
742 | MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match); | ||
743 | |||
703 | static struct platform_driver tegra_devfreq_driver = { | 744 | static struct platform_driver tegra_devfreq_driver = { |
704 | .probe = tegra_devfreq_probe, | 745 | .probe = tegra_devfreq_probe, |
705 | .remove = tegra_devfreq_remove, | 746 | .remove = tegra_devfreq_remove, |
706 | .driver = { | 747 | .driver = { |
707 | .name = "tegra-devfreq", | 748 | .name = "tegra-devfreq", |
708 | .owner = THIS_MODULE, | ||
709 | .of_match_table = tegra_devfreq_of_match, | 749 | .of_match_table = tegra_devfreq_of_match, |
710 | .pm = &tegra_devfreq_pm_ops, | ||
711 | }, | 750 | }, |
712 | }; | 751 | }; |
713 | module_platform_driver(tegra_devfreq_driver); | ||
714 | 752 | ||
715 | MODULE_LICENSE("GPL"); | 753 | static int __init tegra_devfreq_init(void) |
754 | { | ||
755 | int ret = 0; | ||
756 | |||
757 | ret = devfreq_add_governor(&tegra_devfreq_governor); | ||
758 | if (ret) { | ||
759 | pr_err("%s: failed to add governor: %d\n", __func__, ret); | ||
760 | return ret; | ||
761 | } | ||
762 | |||
763 | ret = platform_driver_register(&tegra_devfreq_driver); | ||
764 | if (ret) | ||
765 | devfreq_remove_governor(&tegra_devfreq_governor); | ||
766 | |||
767 | return ret; | ||
768 | } | ||
769 | module_init(tegra_devfreq_init) | ||
770 | |||
771 | static void __exit tegra_devfreq_exit(void) | ||
772 | { | ||
773 | int ret = 0; | ||
774 | |||
775 | platform_driver_unregister(&tegra_devfreq_driver); | ||
776 | |||
777 | ret = devfreq_remove_governor(&tegra_devfreq_governor); | ||
778 | if (ret) | ||
779 | pr_err("%s: failed to remove governor: %d\n", __func__, ret); | ||
780 | } | ||
781 | module_exit(tegra_devfreq_exit) | ||
782 | |||
783 | MODULE_LICENSE("GPL v2"); | ||
716 | MODULE_DESCRIPTION("Tegra devfreq driver"); | 784 | MODULE_DESCRIPTION("Tegra devfreq driver"); |
717 | MODULE_AUTHOR("Tomeu Vizoso <tomeu.vizoso@collabora.com>"); | 785 | MODULE_AUTHOR("Tomeu Vizoso <tomeu.vizoso@collabora.com>"); |
718 | MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match); | ||
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 550a5eafbd38..ab892be26dc2 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h | |||
@@ -17,6 +17,8 @@ | |||
17 | 17 | ||
18 | enum of_gpio_flags; | 18 | enum of_gpio_flags; |
19 | 19 | ||
20 | struct acpi_device; | ||
21 | |||
20 | /** | 22 | /** |
21 | * struct acpi_gpio_info - ACPI GPIO specific information | 23 | * struct acpi_gpio_info - ACPI GPIO specific information |
22 | * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo | 24 | * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo |
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index fa4e2b521f0d..0a80e4aabaed 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -164,7 +164,7 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
164 | /* fast mode by default because of legacy reasons */ | 164 | /* fast mode by default because of legacy reasons */ |
165 | clk_freq = 400000; | 165 | clk_freq = 400000; |
166 | 166 | ||
167 | if (ACPI_COMPANION(&pdev->dev)) { | 167 | if (has_acpi_companion(&pdev->dev)) { |
168 | dw_i2c_acpi_configure(pdev); | 168 | dw_i2c_acpi_configure(pdev); |
169 | } else if (pdev->dev.of_node) { | 169 | } else if (pdev->dev.of_node) { |
170 | of_property_read_u32(pdev->dev.of_node, | 170 | of_property_read_u32(pdev->dev.of_node, |
@@ -284,7 +284,7 @@ static int dw_i2c_remove(struct platform_device *pdev) | |||
284 | pm_runtime_put(&pdev->dev); | 284 | pm_runtime_put(&pdev->dev); |
285 | pm_runtime_disable(&pdev->dev); | 285 | pm_runtime_disable(&pdev->dev); |
286 | 286 | ||
287 | if (ACPI_COMPANION(&pdev->dev)) | 287 | if (has_acpi_companion(&pdev->dev)) |
288 | dw_i2c_acpi_unconfigure(pdev); | 288 | dw_i2c_acpi_unconfigure(pdev); |
289 | 289 | ||
290 | return 0; | 290 | return 0; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 68f687733379..1672e6b12774 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -133,7 +133,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
133 | return AE_OK; | 133 | return AE_OK; |
134 | 134 | ||
135 | memset(&info, 0, sizeof(info)); | 135 | memset(&info, 0, sizeof(info)); |
136 | info.acpi_node.companion = adev; | 136 | info.fwnode = acpi_fwnode_handle(adev); |
137 | info.irq = -1; | 137 | info.irq = -1; |
138 | 138 | ||
139 | INIT_LIST_HEAD(&resource_list); | 139 | INIT_LIST_HEAD(&resource_list); |
@@ -971,7 +971,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | |||
971 | client->dev.bus = &i2c_bus_type; | 971 | client->dev.bus = &i2c_bus_type; |
972 | client->dev.type = &i2c_client_type; | 972 | client->dev.type = &i2c_client_type; |
973 | client->dev.of_node = info->of_node; | 973 | client->dev.of_node = info->of_node; |
974 | ACPI_COMPANION_SET(&client->dev, info->acpi_node.companion); | 974 | client->dev.fwnode = info->fwnode; |
975 | 975 | ||
976 | i2c_dev_set_name(adap, client); | 976 | i2c_dev_set_name(adap, client); |
977 | status = device_register(&client->dev); | 977 | status = device_register(&client->dev); |
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index e5f3db831373..f5f2b62471da 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c | |||
@@ -96,17 +96,5 @@ static struct pnp_driver idepnp_driver = { | |||
96 | .remove = idepnp_remove, | 96 | .remove = idepnp_remove, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static int __init pnpide_init(void) | 99 | module_pnp_driver(idepnp_driver); |
100 | { | ||
101 | return pnp_register_driver(&idepnp_driver); | ||
102 | } | ||
103 | |||
104 | static void __exit pnpide_exit(void) | ||
105 | { | ||
106 | pnp_unregister_driver(&idepnp_driver); | ||
107 | } | ||
108 | |||
109 | module_init(pnpide_init); | ||
110 | module_exit(pnpide_exit); | ||
111 | |||
112 | MODULE_LICENSE("GPL"); | 100 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 5c979d0667a2..2a36a95d95cf 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -218,18 +218,10 @@ static struct cpuidle_state byt_cstates[] = { | |||
218 | .enter = &intel_idle, | 218 | .enter = &intel_idle, |
219 | .enter_freeze = intel_idle_freeze, }, | 219 | .enter_freeze = intel_idle_freeze, }, |
220 | { | 220 | { |
221 | .name = "C1E-BYT", | ||
222 | .desc = "MWAIT 0x01", | ||
223 | .flags = MWAIT2flg(0x01), | ||
224 | .exit_latency = 15, | ||
225 | .target_residency = 30, | ||
226 | .enter = &intel_idle, | ||
227 | .enter_freeze = intel_idle_freeze, }, | ||
228 | { | ||
229 | .name = "C6N-BYT", | 221 | .name = "C6N-BYT", |
230 | .desc = "MWAIT 0x58", | 222 | .desc = "MWAIT 0x58", |
231 | .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, | 223 | .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, |
232 | .exit_latency = 40, | 224 | .exit_latency = 300, |
233 | .target_residency = 275, | 225 | .target_residency = 275, |
234 | .enter = &intel_idle, | 226 | .enter = &intel_idle, |
235 | .enter_freeze = intel_idle_freeze, }, | 227 | .enter_freeze = intel_idle_freeze, }, |
@@ -237,7 +229,7 @@ static struct cpuidle_state byt_cstates[] = { | |||
237 | .name = "C6S-BYT", | 229 | .name = "C6S-BYT", |
238 | .desc = "MWAIT 0x52", | 230 | .desc = "MWAIT 0x52", |
239 | .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, | 231 | .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, |
240 | .exit_latency = 140, | 232 | .exit_latency = 500, |
241 | .target_residency = 560, | 233 | .target_residency = 560, |
242 | .enter = &intel_idle, | 234 | .enter = &intel_idle, |
243 | .enter_freeze = intel_idle_freeze, }, | 235 | .enter_freeze = intel_idle_freeze, }, |
@@ -246,7 +238,7 @@ static struct cpuidle_state byt_cstates[] = { | |||
246 | .desc = "MWAIT 0x60", | 238 | .desc = "MWAIT 0x60", |
247 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 239 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, |
248 | .exit_latency = 1200, | 240 | .exit_latency = 1200, |
249 | .target_residency = 1500, | 241 | .target_residency = 4000, |
250 | .enter = &intel_idle, | 242 | .enter = &intel_idle, |
251 | .enter_freeze = intel_idle_freeze, }, | 243 | .enter_freeze = intel_idle_freeze, }, |
252 | { | 244 | { |
@@ -261,6 +253,51 @@ static struct cpuidle_state byt_cstates[] = { | |||
261 | .enter = NULL } | 253 | .enter = NULL } |
262 | }; | 254 | }; |
263 | 255 | ||
256 | static struct cpuidle_state cht_cstates[] = { | ||
257 | { | ||
258 | .name = "C1-CHT", | ||
259 | .desc = "MWAIT 0x00", | ||
260 | .flags = MWAIT2flg(0x00), | ||
261 | .exit_latency = 1, | ||
262 | .target_residency = 1, | ||
263 | .enter = &intel_idle, | ||
264 | .enter_freeze = intel_idle_freeze, }, | ||
265 | { | ||
266 | .name = "C6N-CHT", | ||
267 | .desc = "MWAIT 0x58", | ||
268 | .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
269 | .exit_latency = 80, | ||
270 | .target_residency = 275, | ||
271 | .enter = &intel_idle, | ||
272 | .enter_freeze = intel_idle_freeze, }, | ||
273 | { | ||
274 | .name = "C6S-CHT", | ||
275 | .desc = "MWAIT 0x52", | ||
276 | .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
277 | .exit_latency = 200, | ||
278 | .target_residency = 560, | ||
279 | .enter = &intel_idle, | ||
280 | .enter_freeze = intel_idle_freeze, }, | ||
281 | { | ||
282 | .name = "C7-CHT", | ||
283 | .desc = "MWAIT 0x60", | ||
284 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
285 | .exit_latency = 1200, | ||
286 | .target_residency = 4000, | ||
287 | .enter = &intel_idle, | ||
288 | .enter_freeze = intel_idle_freeze, }, | ||
289 | { | ||
290 | .name = "C7S-CHT", | ||
291 | .desc = "MWAIT 0x64", | ||
292 | .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
293 | .exit_latency = 10000, | ||
294 | .target_residency = 20000, | ||
295 | .enter = &intel_idle, | ||
296 | .enter_freeze = intel_idle_freeze, }, | ||
297 | { | ||
298 | .enter = NULL } | ||
299 | }; | ||
300 | |||
264 | static struct cpuidle_state ivb_cstates[] = { | 301 | static struct cpuidle_state ivb_cstates[] = { |
265 | { | 302 | { |
266 | .name = "C1-IVB", | 303 | .name = "C1-IVB", |
@@ -747,6 +784,12 @@ static const struct idle_cpu idle_cpu_byt = { | |||
747 | .byt_auto_demotion_disable_flag = true, | 784 | .byt_auto_demotion_disable_flag = true, |
748 | }; | 785 | }; |
749 | 786 | ||
787 | static const struct idle_cpu idle_cpu_cht = { | ||
788 | .state_table = cht_cstates, | ||
789 | .disable_promotion_to_c1e = true, | ||
790 | .byt_auto_demotion_disable_flag = true, | ||
791 | }; | ||
792 | |||
750 | static const struct idle_cpu idle_cpu_ivb = { | 793 | static const struct idle_cpu idle_cpu_ivb = { |
751 | .state_table = ivb_cstates, | 794 | .state_table = ivb_cstates, |
752 | .disable_promotion_to_c1e = true, | 795 | .disable_promotion_to_c1e = true, |
@@ -775,7 +818,7 @@ static const struct idle_cpu idle_cpu_avn = { | |||
775 | #define ICPU(model, cpu) \ | 818 | #define ICPU(model, cpu) \ |
776 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } | 819 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } |
777 | 820 | ||
778 | static const struct x86_cpu_id intel_idle_ids[] = { | 821 | static const struct x86_cpu_id intel_idle_ids[] __initconst = { |
779 | ICPU(0x1a, idle_cpu_nehalem), | 822 | ICPU(0x1a, idle_cpu_nehalem), |
780 | ICPU(0x1e, idle_cpu_nehalem), | 823 | ICPU(0x1e, idle_cpu_nehalem), |
781 | ICPU(0x1f, idle_cpu_nehalem), | 824 | ICPU(0x1f, idle_cpu_nehalem), |
@@ -789,6 +832,7 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
789 | ICPU(0x2d, idle_cpu_snb), | 832 | ICPU(0x2d, idle_cpu_snb), |
790 | ICPU(0x36, idle_cpu_atom), | 833 | ICPU(0x36, idle_cpu_atom), |
791 | ICPU(0x37, idle_cpu_byt), | 834 | ICPU(0x37, idle_cpu_byt), |
835 | ICPU(0x4c, idle_cpu_cht), | ||
792 | ICPU(0x3a, idle_cpu_ivb), | 836 | ICPU(0x3a, idle_cpu_ivb), |
793 | ICPU(0x3e, idle_cpu_ivt), | 837 | ICPU(0x3e, idle_cpu_ivt), |
794 | ICPU(0x3c, idle_cpu_hsw), | 838 | ICPU(0x3c, idle_cpu_hsw), |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2d1e05bdbb53..4fc1f8a7f98e 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -684,7 +684,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf | |||
684 | if (dev_is_pci(dev)) { | 684 | if (dev_is_pci(dev)) { |
685 | pdev = to_pci_dev(dev); | 685 | pdev = to_pci_dev(dev); |
686 | segment = pci_domain_nr(pdev->bus); | 686 | segment = pci_domain_nr(pdev->bus); |
687 | } else if (ACPI_COMPANION(dev)) | 687 | } else if (has_acpi_companion(dev)) |
688 | dev = &ACPI_COMPANION(dev)->dev; | 688 | dev = &ACPI_COMPANION(dev)->dev; |
689 | 689 | ||
690 | rcu_read_lock(); | 690 | rcu_read_lock(); |
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index e80f2c6c5f1a..8d77e1c4a141 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c | |||
@@ -1195,16 +1195,6 @@ static struct pnp_driver ene_driver = { | |||
1195 | .shutdown = ene_shutdown, | 1195 | .shutdown = ene_shutdown, |
1196 | }; | 1196 | }; |
1197 | 1197 | ||
1198 | static int __init ene_init(void) | ||
1199 | { | ||
1200 | return pnp_register_driver(&ene_driver); | ||
1201 | } | ||
1202 | |||
1203 | static void ene_exit(void) | ||
1204 | { | ||
1205 | pnp_unregister_driver(&ene_driver); | ||
1206 | } | ||
1207 | |||
1208 | module_param(sample_period, int, S_IRUGO); | 1198 | module_param(sample_period, int, S_IRUGO); |
1209 | MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); | 1199 | MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); |
1210 | 1200 | ||
@@ -1226,5 +1216,4 @@ MODULE_DESCRIPTION | |||
1226 | MODULE_AUTHOR("Maxim Levitsky"); | 1216 | MODULE_AUTHOR("Maxim Levitsky"); |
1227 | MODULE_LICENSE("GPL"); | 1217 | MODULE_LICENSE("GPL"); |
1228 | 1218 | ||
1229 | module_init(ene_init); | 1219 | module_pnp_driver(ene_driver); |
1230 | module_exit(ene_exit); | ||
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index b5167573240e..5c63c2ec6183 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c | |||
@@ -684,16 +684,6 @@ static struct pnp_driver fintek_driver = { | |||
684 | .shutdown = fintek_shutdown, | 684 | .shutdown = fintek_shutdown, |
685 | }; | 685 | }; |
686 | 686 | ||
687 | static int __init fintek_init(void) | ||
688 | { | ||
689 | return pnp_register_driver(&fintek_driver); | ||
690 | } | ||
691 | |||
692 | static void __exit fintek_exit(void) | ||
693 | { | ||
694 | pnp_unregister_driver(&fintek_driver); | ||
695 | } | ||
696 | |||
697 | module_param(debug, int, S_IRUGO | S_IWUSR); | 687 | module_param(debug, int, S_IRUGO | S_IWUSR); |
698 | MODULE_PARM_DESC(debug, "Enable debugging output"); | 688 | MODULE_PARM_DESC(debug, "Enable debugging output"); |
699 | 689 | ||
@@ -703,5 +693,4 @@ MODULE_DESCRIPTION(FINTEK_DESCRIPTION " driver"); | |||
703 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | 693 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); |
704 | MODULE_LICENSE("GPL"); | 694 | MODULE_LICENSE("GPL"); |
705 | 695 | ||
706 | module_init(fintek_init); | 696 | module_pnp_driver(fintek_driver); |
707 | module_exit(fintek_exit); | ||
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 56abf9120cc2..0f301903aa6f 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c | |||
@@ -1708,21 +1708,10 @@ static struct pnp_driver ite_driver = { | |||
1708 | .shutdown = ite_shutdown, | 1708 | .shutdown = ite_shutdown, |
1709 | }; | 1709 | }; |
1710 | 1710 | ||
1711 | static int __init ite_init(void) | ||
1712 | { | ||
1713 | return pnp_register_driver(&ite_driver); | ||
1714 | } | ||
1715 | |||
1716 | static void __exit ite_exit(void) | ||
1717 | { | ||
1718 | pnp_unregister_driver(&ite_driver); | ||
1719 | } | ||
1720 | |||
1721 | MODULE_DEVICE_TABLE(pnp, ite_ids); | 1711 | MODULE_DEVICE_TABLE(pnp, ite_ids); |
1722 | MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver"); | 1712 | MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver"); |
1723 | 1713 | ||
1724 | MODULE_AUTHOR("Juan J. Garcia de Soria <skandalfo@gmail.com>"); | 1714 | MODULE_AUTHOR("Juan J. Garcia de Soria <skandalfo@gmail.com>"); |
1725 | MODULE_LICENSE("GPL"); | 1715 | MODULE_LICENSE("GPL"); |
1726 | 1716 | ||
1727 | module_init(ite_init); | 1717 | module_pnp_driver(ite_driver); |
1728 | module_exit(ite_exit); | ||
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 9c2c8635ff33..85af7a869167 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c | |||
@@ -1219,16 +1219,6 @@ static struct pnp_driver nvt_driver = { | |||
1219 | .shutdown = nvt_shutdown, | 1219 | .shutdown = nvt_shutdown, |
1220 | }; | 1220 | }; |
1221 | 1221 | ||
1222 | static int __init nvt_init(void) | ||
1223 | { | ||
1224 | return pnp_register_driver(&nvt_driver); | ||
1225 | } | ||
1226 | |||
1227 | static void __exit nvt_exit(void) | ||
1228 | { | ||
1229 | pnp_unregister_driver(&nvt_driver); | ||
1230 | } | ||
1231 | |||
1232 | module_param(debug, int, S_IRUGO | S_IWUSR); | 1222 | module_param(debug, int, S_IRUGO | S_IWUSR); |
1233 | MODULE_PARM_DESC(debug, "Enable debugging output"); | 1223 | MODULE_PARM_DESC(debug, "Enable debugging output"); |
1234 | 1224 | ||
@@ -1238,5 +1228,4 @@ MODULE_DESCRIPTION("Nuvoton W83667HG-A & W83677HG-I CIR driver"); | |||
1238 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | 1228 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); |
1239 | MODULE_LICENSE("GPL"); | 1229 | MODULE_LICENSE("GPL"); |
1240 | 1230 | ||
1241 | module_init(nvt_init); | 1231 | module_pnp_driver(nvt_driver); |
1242 | module_exit(nvt_exit); | ||
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index 66c2f1a01963..aad0b59d41e3 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c | |||
@@ -1175,17 +1175,4 @@ MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>"); | |||
1175 | MODULE_DESCRIPTION("General Instruments SB1000 driver"); | 1175 | MODULE_DESCRIPTION("General Instruments SB1000 driver"); |
1176 | MODULE_LICENSE("GPL"); | 1176 | MODULE_LICENSE("GPL"); |
1177 | 1177 | ||
1178 | static int __init | 1178 | module_pnp_driver(sb1000_driver); |
1179 | sb1000_init(void) | ||
1180 | { | ||
1181 | return pnp_register_driver(&sb1000_driver); | ||
1182 | } | ||
1183 | |||
1184 | static void __exit | ||
1185 | sb1000_exit(void) | ||
1186 | { | ||
1187 | pnp_unregister_driver(&sb1000_driver); | ||
1188 | } | ||
1189 | |||
1190 | module_init(sb1000_init); | ||
1191 | module_exit(sb1000_exit); | ||
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index b9429fbf1cd8..66d6d22c239c 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -624,19 +624,7 @@ static struct pnp_driver gmux_pnp_driver = { | |||
624 | }, | 624 | }, |
625 | }; | 625 | }; |
626 | 626 | ||
627 | static int __init apple_gmux_init(void) | 627 | module_pnp_driver(gmux_pnp_driver); |
628 | { | ||
629 | return pnp_register_driver(&gmux_pnp_driver); | ||
630 | } | ||
631 | |||
632 | static void __exit apple_gmux_exit(void) | ||
633 | { | ||
634 | pnp_unregister_driver(&gmux_pnp_driver); | ||
635 | } | ||
636 | |||
637 | module_init(apple_gmux_init); | ||
638 | module_exit(apple_gmux_exit); | ||
639 | |||
640 | MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>"); | 628 | MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>"); |
641 | MODULE_DESCRIPTION("Apple Gmux Driver"); | 629 | MODULE_DESCRIPTION("Apple Gmux Driver"); |
642 | MODULE_LICENSE("GPL"); | 630 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index c8873b0ca551..3151fd164614 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | 3 | * Bjorn Helgaas <bjorn.helgaas@hp.com> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | extern spinlock_t pnp_lock; | 6 | extern struct mutex pnp_lock; |
7 | extern const struct attribute_group *pnp_dev_groups[]; | 7 | extern const struct attribute_group *pnp_dev_groups[]; |
8 | void *pnp_alloc(long size); | 8 | void *pnp_alloc(long size); |
9 | 9 | ||
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index 874c236ac1a7..31ad9fc3f701 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/mutex.h> | ||
8 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
10 | #include <linux/pnp.h> | 11 | #include <linux/pnp.h> |
@@ -244,10 +245,10 @@ int pnp_add_card(struct pnp_card *card) | |||
244 | } | 245 | } |
245 | 246 | ||
246 | pnp_interface_attach_card(card); | 247 | pnp_interface_attach_card(card); |
247 | spin_lock(&pnp_lock); | 248 | mutex_lock(&pnp_lock); |
248 | list_add_tail(&card->global_list, &pnp_cards); | 249 | list_add_tail(&card->global_list, &pnp_cards); |
249 | list_add_tail(&card->protocol_list, &card->protocol->cards); | 250 | list_add_tail(&card->protocol_list, &card->protocol->cards); |
250 | spin_unlock(&pnp_lock); | 251 | mutex_unlock(&pnp_lock); |
251 | 252 | ||
252 | /* we wait until now to add devices in order to ensure the drivers | 253 | /* we wait until now to add devices in order to ensure the drivers |
253 | * will be able to use all of the related devices on the card | 254 | * will be able to use all of the related devices on the card |
@@ -276,10 +277,10 @@ void pnp_remove_card(struct pnp_card *card) | |||
276 | struct list_head *pos, *temp; | 277 | struct list_head *pos, *temp; |
277 | 278 | ||
278 | device_unregister(&card->dev); | 279 | device_unregister(&card->dev); |
279 | spin_lock(&pnp_lock); | 280 | mutex_lock(&pnp_lock); |
280 | list_del(&card->global_list); | 281 | list_del(&card->global_list); |
281 | list_del(&card->protocol_list); | 282 | list_del(&card->protocol_list); |
282 | spin_unlock(&pnp_lock); | 283 | mutex_unlock(&pnp_lock); |
283 | list_for_each_safe(pos, temp, &card->devices) { | 284 | list_for_each_safe(pos, temp, &card->devices) { |
284 | struct pnp_dev *dev = card_to_pnp_dev(pos); | 285 | struct pnp_dev *dev = card_to_pnp_dev(pos); |
285 | pnp_remove_card_device(dev); | 286 | pnp_remove_card_device(dev); |
@@ -297,10 +298,10 @@ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) | |||
297 | dev->card_link = NULL; | 298 | dev->card_link = NULL; |
298 | dev_set_name(&dev->dev, "%02x:%02x.%02x", | 299 | dev_set_name(&dev->dev, "%02x:%02x.%02x", |
299 | dev->protocol->number, card->number, dev->number); | 300 | dev->protocol->number, card->number, dev->number); |
300 | spin_lock(&pnp_lock); | 301 | mutex_lock(&pnp_lock); |
301 | dev->card = card; | 302 | dev->card = card; |
302 | list_add_tail(&dev->card_list, &card->devices); | 303 | list_add_tail(&dev->card_list, &card->devices); |
303 | spin_unlock(&pnp_lock); | 304 | mutex_unlock(&pnp_lock); |
304 | return 0; | 305 | return 0; |
305 | } | 306 | } |
306 | 307 | ||
@@ -310,10 +311,10 @@ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) | |||
310 | */ | 311 | */ |
311 | void pnp_remove_card_device(struct pnp_dev *dev) | 312 | void pnp_remove_card_device(struct pnp_dev *dev) |
312 | { | 313 | { |
313 | spin_lock(&pnp_lock); | 314 | mutex_lock(&pnp_lock); |
314 | dev->card = NULL; | 315 | dev->card = NULL; |
315 | list_del(&dev->card_list); | 316 | list_del(&dev->card_list); |
316 | spin_unlock(&pnp_lock); | 317 | mutex_unlock(&pnp_lock); |
317 | __pnp_remove_device(dev); | 318 | __pnp_remove_device(dev); |
318 | } | 319 | } |
319 | 320 | ||
@@ -426,9 +427,9 @@ int pnp_register_card_driver(struct pnp_card_driver *drv) | |||
426 | if (error < 0) | 427 | if (error < 0) |
427 | return error; | 428 | return error; |
428 | 429 | ||
429 | spin_lock(&pnp_lock); | 430 | mutex_lock(&pnp_lock); |
430 | list_add_tail(&drv->global_list, &pnp_card_drivers); | 431 | list_add_tail(&drv->global_list, &pnp_card_drivers); |
431 | spin_unlock(&pnp_lock); | 432 | mutex_unlock(&pnp_lock); |
432 | 433 | ||
433 | list_for_each_safe(pos, temp, &pnp_cards) { | 434 | list_for_each_safe(pos, temp, &pnp_cards) { |
434 | struct pnp_card *card = | 435 | struct pnp_card *card = |
@@ -444,9 +445,9 @@ int pnp_register_card_driver(struct pnp_card_driver *drv) | |||
444 | */ | 445 | */ |
445 | void pnp_unregister_card_driver(struct pnp_card_driver *drv) | 446 | void pnp_unregister_card_driver(struct pnp_card_driver *drv) |
446 | { | 447 | { |
447 | spin_lock(&pnp_lock); | 448 | mutex_lock(&pnp_lock); |
448 | list_del(&drv->global_list); | 449 | list_del(&drv->global_list); |
449 | spin_unlock(&pnp_lock); | 450 | mutex_unlock(&pnp_lock); |
450 | pnp_unregister_driver(&drv->link); | 451 | pnp_unregister_driver(&drv->link); |
451 | } | 452 | } |
452 | 453 | ||
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 | ||
20 | static LIST_HEAD(pnp_protocols); | 21 | static LIST_HEAD(pnp_protocols); |
21 | LIST_HEAD(pnp_global); | 22 | LIST_HEAD(pnp_global); |
22 | DEFINE_SPINLOCK(pnp_lock); | 23 | DEFINE_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 | ||
45 | static 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 | */ |
50 | int pnp_register_protocol(struct pnp_protocol *protocol) | 58 | int 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 | */ |
81 | void pnp_unregister_protocol(struct pnp_protocol *protocol) | 96 | void 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 | ||
173 | static 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 | |||
160 | int __pnp_add_device(struct pnp_dev *dev) | 181 | int __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 | ||
204 | void __pnp_remove_device(struct pnp_dev *dev) | 235 | void __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 | ||
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 4e57d3370368..153a493b5413 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -58,22 +58,22 @@ static const struct pnp_device_id *match_device(struct pnp_driver *drv, | |||
58 | 58 | ||
59 | int pnp_device_attach(struct pnp_dev *pnp_dev) | 59 | int pnp_device_attach(struct pnp_dev *pnp_dev) |
60 | { | 60 | { |
61 | spin_lock(&pnp_lock); | 61 | mutex_lock(&pnp_lock); |
62 | if (pnp_dev->status != PNP_READY) { | 62 | if (pnp_dev->status != PNP_READY) { |
63 | spin_unlock(&pnp_lock); | 63 | mutex_unlock(&pnp_lock); |
64 | return -EBUSY; | 64 | return -EBUSY; |
65 | } | 65 | } |
66 | pnp_dev->status = PNP_ATTACHED; | 66 | pnp_dev->status = PNP_ATTACHED; |
67 | spin_unlock(&pnp_lock); | 67 | mutex_unlock(&pnp_lock); |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | void pnp_device_detach(struct pnp_dev *pnp_dev) | 71 | void pnp_device_detach(struct pnp_dev *pnp_dev) |
72 | { | 72 | { |
73 | spin_lock(&pnp_lock); | 73 | mutex_lock(&pnp_lock); |
74 | if (pnp_dev->status == PNP_ATTACHED) | 74 | if (pnp_dev->status == PNP_ATTACHED) |
75 | pnp_dev->status = PNP_READY; | 75 | pnp_dev->status = PNP_READY; |
76 | spin_unlock(&pnp_lock); | 76 | mutex_unlock(&pnp_lock); |
77 | pnp_disable_dev(pnp_dev); | 77 | pnp_disable_dev(pnp_dev); |
78 | } | 78 | } |
79 | 79 | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index d2b780aade89..5153d1d69aee 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -248,6 +248,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
248 | if (!dev) | 248 | if (!dev) |
249 | return -ENOMEM; | 249 | return -ENOMEM; |
250 | 250 | ||
251 | ACPI_COMPANION_SET(&dev->dev, device); | ||
251 | dev->data = device; | 252 | dev->data = device; |
252 | /* .enabled means the device can decode the resources */ | 253 | /* .enabled means the device can decode the resources */ |
253 | dev->active = device->status.enabled; | 254 | dev->active = device->status.enabled; |
@@ -290,11 +291,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
290 | return error; | 291 | return error; |
291 | } | 292 | } |
292 | 293 | ||
293 | error = acpi_bind_one(&dev->dev, device); | ||
294 | |||
295 | num++; | 294 | num++; |
296 | 295 | ||
297 | return error; | 296 | return 0; |
298 | } | 297 | } |
299 | 298 | ||
300 | static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | 299 | static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 63d4033eb683..e03877c4b195 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -1054,7 +1054,7 @@ static const struct rapl_defaults rapl_defaults_atom = { | |||
1054 | .driver_data = (kernel_ulong_t)&_ops, \ | 1054 | .driver_data = (kernel_ulong_t)&_ops, \ |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | static const struct x86_cpu_id rapl_ids[] = { | 1057 | static const struct x86_cpu_id rapl_ids[] __initconst = { |
1058 | RAPL_CPU(0x2a, rapl_defaults_core),/* Sandy Bridge */ | 1058 | RAPL_CPU(0x2a, rapl_defaults_core),/* Sandy Bridge */ |
1059 | RAPL_CPU(0x2d, rapl_defaults_core),/* Sandy Bridge EP */ | 1059 | RAPL_CPU(0x2d, rapl_defaults_core),/* Sandy Bridge EP */ |
1060 | RAPL_CPU(0x37, rapl_defaults_atom),/* Valleyview */ | 1060 | RAPL_CPU(0x37, rapl_defaults_atom),/* Valleyview */ |
@@ -1062,6 +1062,7 @@ static const struct x86_cpu_id rapl_ids[] = { | |||
1062 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ | 1062 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ |
1063 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ | 1063 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ |
1064 | RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ | 1064 | RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ |
1065 | RAPL_CPU(0x4f, rapl_defaults_hsw_server),/* Broadwell servers */ | ||
1065 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ | 1066 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ |
1066 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ | 1067 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ |
1067 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ | 1068 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ |
diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 1e6899bc9429..5815e81b5fc6 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c | |||
@@ -234,18 +234,7 @@ static struct pnp_driver fintek_8250_driver = { | |||
234 | .id_table = fintek_dev_table, | 234 | .id_table = fintek_dev_table, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static int fintek_8250_init(void) | 237 | module_pnp_driver(fintek_8250_driver); |
238 | { | ||
239 | return pnp_register_driver(&fintek_8250_driver); | ||
240 | } | ||
241 | module_init(fintek_8250_init); | ||
242 | |||
243 | static void fintek_8250_exit(void) | ||
244 | { | ||
245 | pnp_unregister_driver(&fintek_8250_driver); | ||
246 | } | ||
247 | module_exit(fintek_8250_exit); | ||
248 | |||
249 | MODULE_DESCRIPTION("Fintek F812164 module"); | 238 | MODULE_DESCRIPTION("Fintek F812164 module"); |
250 | MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>"); | 239 | MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>"); |
251 | MODULE_LICENSE("GPL"); | 240 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 05ee0bf88ce9..3c3fd417ddeb 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #define DRV_VERSION "1.11" | 51 | #define DRV_VERSION "1.11" |
52 | 52 | ||
53 | /* Includes */ | 53 | /* Includes */ |
54 | #include <linux/acpi.h> /* For ACPI support */ | ||
54 | #include <linux/module.h> /* For module specific items */ | 55 | #include <linux/module.h> /* For module specific items */ |
55 | #include <linux/moduleparam.h> /* For new moduleparam's */ | 56 | #include <linux/moduleparam.h> /* For new moduleparam's */ |
56 | #include <linux/types.h> /* For standard types (like size_t) */ | 57 | #include <linux/types.h> /* For standard types (like size_t) */ |
@@ -103,6 +104,8 @@ static struct { /* this is private data for the iTCO_wdt device */ | |||
103 | struct platform_device *dev; | 104 | struct platform_device *dev; |
104 | /* the PCI-device */ | 105 | /* the PCI-device */ |
105 | struct pci_dev *pdev; | 106 | struct pci_dev *pdev; |
107 | /* whether or not the watchdog has been suspended */ | ||
108 | bool suspended; | ||
106 | } iTCO_wdt_private; | 109 | } iTCO_wdt_private; |
107 | 110 | ||
108 | /* module parameters */ | 111 | /* module parameters */ |
@@ -571,12 +574,60 @@ static void iTCO_wdt_shutdown(struct platform_device *dev) | |||
571 | iTCO_wdt_stop(NULL); | 574 | iTCO_wdt_stop(NULL); |
572 | } | 575 | } |
573 | 576 | ||
577 | #ifdef CONFIG_PM_SLEEP | ||
578 | /* | ||
579 | * Suspend-to-idle requires this, because it stops the ticks and timekeeping, so | ||
580 | * the watchdog cannot be pinged while in that state. In ACPI sleep states the | ||
581 | * watchdog is stopped by the platform firmware. | ||
582 | */ | ||
583 | |||
584 | #ifdef CONFIG_ACPI | ||
585 | static inline bool need_suspend(void) | ||
586 | { | ||
587 | return acpi_target_system_state() == ACPI_STATE_S0; | ||
588 | } | ||
589 | #else | ||
590 | static inline bool need_suspend(void) { return true; } | ||
591 | #endif | ||
592 | |||
593 | static int iTCO_wdt_suspend_noirq(struct device *dev) | ||
594 | { | ||
595 | int ret = 0; | ||
596 | |||
597 | iTCO_wdt_private.suspended = false; | ||
598 | if (watchdog_active(&iTCO_wdt_watchdog_dev) && need_suspend()) { | ||
599 | ret = iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); | ||
600 | if (!ret) | ||
601 | iTCO_wdt_private.suspended = true; | ||
602 | } | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | static int iTCO_wdt_resume_noirq(struct device *dev) | ||
607 | { | ||
608 | if (iTCO_wdt_private.suspended) | ||
609 | iTCO_wdt_start(&iTCO_wdt_watchdog_dev); | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static struct dev_pm_ops iTCO_wdt_pm = { | ||
615 | .suspend_noirq = iTCO_wdt_suspend_noirq, | ||
616 | .resume_noirq = iTCO_wdt_resume_noirq, | ||
617 | }; | ||
618 | |||
619 | #define ITCO_WDT_PM_OPS (&iTCO_wdt_pm) | ||
620 | #else | ||
621 | #define ITCO_WDT_PM_OPS NULL | ||
622 | #endif /* CONFIG_PM_SLEEP */ | ||
623 | |||
574 | static struct platform_driver iTCO_wdt_driver = { | 624 | static struct platform_driver iTCO_wdt_driver = { |
575 | .probe = iTCO_wdt_probe, | 625 | .probe = iTCO_wdt_probe, |
576 | .remove = iTCO_wdt_remove, | 626 | .remove = iTCO_wdt_remove, |
577 | .shutdown = iTCO_wdt_shutdown, | 627 | .shutdown = iTCO_wdt_shutdown, |
578 | .driver = { | 628 | .driver = { |
579 | .name = DRV_NAME, | 629 | .name = DRV_NAME, |
630 | .pm = ITCO_WDT_PM_OPS, | ||
580 | }, | 631 | }, |
581 | }; | 632 | }; |
582 | 633 | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 61e32ec1fc4d..8de4fa90e8c4 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -252,6 +252,7 @@ struct acpi_device_pnp { | |||
252 | #define acpi_device_bid(d) ((d)->pnp.bus_id) | 252 | #define acpi_device_bid(d) ((d)->pnp.bus_id) |
253 | #define acpi_device_adr(d) ((d)->pnp.bus_address) | 253 | #define acpi_device_adr(d) ((d)->pnp.bus_address) |
254 | const char *acpi_device_hid(struct acpi_device *device); | 254 | const char *acpi_device_hid(struct acpi_device *device); |
255 | #define acpi_device_uid(d) ((d)->pnp.unique_id) | ||
255 | #define acpi_device_name(d) ((d)->pnp.device_name) | 256 | #define acpi_device_name(d) ((d)->pnp.device_name) |
256 | #define acpi_device_class(d) ((d)->pnp.device_class) | 257 | #define acpi_device_class(d) ((d)->pnp.device_class) |
257 | 258 | ||
@@ -386,7 +387,8 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode) | |||
386 | 387 | ||
387 | static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode) | 388 | static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode) |
388 | { | 389 | { |
389 | return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL; | 390 | return is_acpi_node(fwnode) ? |
391 | container_of(fwnode, struct acpi_device, fwnode) : NULL; | ||
390 | } | 392 | } |
391 | 393 | ||
392 | static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) | 394 | static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f8e8b34dc427..392c74c40056 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -170,6 +170,7 @@ | |||
170 | #define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu) | 170 | #define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu) |
171 | #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) | 171 | #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) |
172 | #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) | 172 | #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) |
173 | #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) | ||
173 | #define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) | 174 | #define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) |
174 | 175 | ||
175 | #define KERNEL_DTB() \ | 176 | #define KERNEL_DTB() \ |
@@ -504,6 +505,7 @@ | |||
504 | CLKSRC_OF_TABLES() \ | 505 | CLKSRC_OF_TABLES() \ |
505 | IOMMU_OF_TABLES() \ | 506 | IOMMU_OF_TABLES() \ |
506 | CPU_METHOD_OF_TABLES() \ | 507 | CPU_METHOD_OF_TABLES() \ |
508 | CPUIDLE_METHOD_OF_TABLES() \ | ||
507 | KERNEL_DTB() \ | 509 | KERNEL_DTB() \ |
508 | IRQCHIP_OF_MATCH_TABLE() \ | 510 | IRQCHIP_OF_MATCH_TABLE() \ |
509 | EARLYCON_OF_TABLES() | 511 | EARLYCON_OF_TABLES() |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 24c7aa8b1d20..dd12127f171c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -53,10 +53,16 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) | |||
53 | return adev ? adev->handle : NULL; | 53 | return adev ? adev->handle : NULL; |
54 | } | 54 | } |
55 | 55 | ||
56 | #define ACPI_COMPANION(dev) ((dev)->acpi_node.companion) | 56 | #define ACPI_COMPANION(dev) acpi_node((dev)->fwnode) |
57 | #define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) | 57 | #define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \ |
58 | acpi_fwnode_handle(adev) : NULL) | ||
58 | #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) | 59 | #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) |
59 | 60 | ||
61 | static inline bool has_acpi_companion(struct device *dev) | ||
62 | { | ||
63 | return is_acpi_node(dev->fwnode); | ||
64 | } | ||
65 | |||
60 | static inline void acpi_preset_companion(struct device *dev, | 66 | static inline void acpi_preset_companion(struct device *dev, |
61 | struct acpi_device *parent, u64 addr) | 67 | struct acpi_device *parent, u64 addr) |
62 | { | 68 | { |
@@ -471,6 +477,11 @@ static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) | |||
471 | return NULL; | 477 | return NULL; |
472 | } | 478 | } |
473 | 479 | ||
480 | static inline bool has_acpi_companion(struct device *dev) | ||
481 | { | ||
482 | return false; | ||
483 | } | ||
484 | |||
474 | static inline const char *acpi_dev_name(struct acpi_device *adev) | 485 | static inline const char *acpi_dev_name(struct acpi_device *adev) |
475 | { | 486 | { |
476 | return NULL; | 487 | return NULL; |
diff --git a/include/linux/devfreq-event.h b/include/linux/devfreq-event.h index 602fbbfcfeed..0a83a1e648b0 100644 --- a/include/linux/devfreq-event.h +++ b/include/linux/devfreq-event.h | |||
@@ -91,7 +91,7 @@ struct devfreq_event_desc { | |||
91 | const char *name; | 91 | const char *name; |
92 | void *driver_data; | 92 | void *driver_data; |
93 | 93 | ||
94 | struct devfreq_event_ops *ops; | 94 | const struct devfreq_event_ops *ops; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | #if defined(CONFIG_PM_DEVFREQ_EVENT) | 97 | #if defined(CONFIG_PM_DEVFREQ_EVENT) |
diff --git a/include/linux/device.h b/include/linux/device.h index f3f2c7e38060..6558af90c8fe 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -38,6 +38,7 @@ struct class; | |||
38 | struct subsys_private; | 38 | struct subsys_private; |
39 | struct bus_type; | 39 | struct bus_type; |
40 | struct device_node; | 40 | struct device_node; |
41 | struct fwnode_handle; | ||
41 | struct iommu_ops; | 42 | struct iommu_ops; |
42 | struct iommu_group; | 43 | struct iommu_group; |
43 | 44 | ||
@@ -650,14 +651,6 @@ struct device_dma_parameters { | |||
650 | unsigned long segment_boundary_mask; | 651 | unsigned long segment_boundary_mask; |
651 | }; | 652 | }; |
652 | 653 | ||
653 | struct acpi_device; | ||
654 | |||
655 | struct acpi_dev_node { | ||
656 | #ifdef CONFIG_ACPI | ||
657 | struct acpi_device *companion; | ||
658 | #endif | ||
659 | }; | ||
660 | |||
661 | /** | 654 | /** |
662 | * struct device - The basic device structure | 655 | * struct device - The basic device structure |
663 | * @parent: The device's "parent" device, the device to which it is attached. | 656 | * @parent: The device's "parent" device, the device to which it is attached. |
@@ -703,7 +696,7 @@ struct acpi_dev_node { | |||
703 | * @cma_area: Contiguous memory area for dma allocations | 696 | * @cma_area: Contiguous memory area for dma allocations |
704 | * @archdata: For arch-specific additions. | 697 | * @archdata: For arch-specific additions. |
705 | * @of_node: Associated device tree node. | 698 | * @of_node: Associated device tree node. |
706 | * @acpi_node: Associated ACPI device node. | 699 | * @fwnode: Associated device node supplied by platform firmware. |
707 | * @devt: For creating the sysfs "dev". | 700 | * @devt: For creating the sysfs "dev". |
708 | * @id: device instance | 701 | * @id: device instance |
709 | * @devres_lock: Spinlock to protect the resource of the device. | 702 | * @devres_lock: Spinlock to protect the resource of the device. |
@@ -779,7 +772,7 @@ struct device { | |||
779 | struct dev_archdata archdata; | 772 | struct dev_archdata archdata; |
780 | 773 | ||
781 | struct device_node *of_node; /* associated device tree node */ | 774 | struct device_node *of_node; /* associated device tree node */ |
782 | struct acpi_dev_node acpi_node; /* associated ACPI device node */ | 775 | struct fwnode_handle *fwnode; /* firmware device node */ |
783 | 776 | ||
784 | dev_t devt; /* dev_t, creates the sysfs "dev" */ | 777 | dev_t devt; /* dev_t, creates the sysfs "dev" */ |
785 | u32 id; /* device instance */ | 778 | u32 id; /* device instance */ |
@@ -954,6 +947,9 @@ extern void unlock_device_hotplug(void); | |||
954 | extern int lock_device_hotplug_sysfs(void); | 947 | extern int lock_device_hotplug_sysfs(void); |
955 | extern int device_offline(struct device *dev); | 948 | extern int device_offline(struct device *dev); |
956 | extern int device_online(struct device *dev); | 949 | extern int device_online(struct device *dev); |
950 | extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); | ||
951 | extern void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); | ||
952 | |||
957 | /* | 953 | /* |
958 | * Root device objects for grouping under /sys/devices | 954 | * Root device objects for grouping under /sys/devices |
959 | */ | 955 | */ |
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h new file mode 100644 index 000000000000..0408545bce42 --- /dev/null +++ b/include/linux/fwnode.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * fwnode.h - Firmware device node object handle type definition. | ||
3 | * | ||
4 | * Copyright (C) 2015, Intel Corporation | ||
5 | * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _LINUX_FWNODE_H_ | ||
13 | #define _LINUX_FWNODE_H_ | ||
14 | |||
15 | enum fwnode_type { | ||
16 | FWNODE_INVALID = 0, | ||
17 | FWNODE_OF, | ||
18 | FWNODE_ACPI, | ||
19 | FWNODE_PDATA, | ||
20 | }; | ||
21 | |||
22 | struct fwnode_handle { | ||
23 | enum fwnode_type type; | ||
24 | struct fwnode_handle *secondary; | ||
25 | }; | ||
26 | |||
27 | #endif | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 898033f41d76..e83a738a3b87 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -278,7 +278,7 @@ static inline int i2c_slave_event(struct i2c_client *client, | |||
278 | * @platform_data: stored in i2c_client.dev.platform_data | 278 | * @platform_data: stored in i2c_client.dev.platform_data |
279 | * @archdata: copied into i2c_client.dev.archdata | 279 | * @archdata: copied into i2c_client.dev.archdata |
280 | * @of_node: pointer to OpenFirmware device node | 280 | * @of_node: pointer to OpenFirmware device node |
281 | * @acpi_node: ACPI device node | 281 | * @fwnode: device node supplied by the platform firmware |
282 | * @irq: stored in i2c_client.irq | 282 | * @irq: stored in i2c_client.irq |
283 | * | 283 | * |
284 | * I2C doesn't actually support hardware probing, although controllers and | 284 | * I2C doesn't actually support hardware probing, although controllers and |
@@ -299,7 +299,7 @@ struct i2c_board_info { | |||
299 | void *platform_data; | 299 | void *platform_data; |
300 | struct dev_archdata *archdata; | 300 | struct dev_archdata *archdata; |
301 | struct device_node *of_node; | 301 | struct device_node *of_node; |
302 | struct acpi_dev_node acpi_node; | 302 | struct fwnode_handle *fwnode; |
303 | int irq; | 303 | int irq; |
304 | }; | 304 | }; |
305 | 305 | ||
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index ae4882ca4a64..58f1e75ba105 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -59,7 +59,7 @@ extern int platform_add_devices(struct platform_device **, int); | |||
59 | 59 | ||
60 | struct platform_device_info { | 60 | struct platform_device_info { |
61 | struct device *parent; | 61 | struct device *parent; |
62 | struct acpi_dev_node acpi_node; | 62 | struct fwnode_handle *fwnode; |
63 | 63 | ||
64 | const char *name; | 64 | const char *name; |
65 | int id; | 65 | int id; |
diff --git a/include/linux/resume-trace.h b/include/linux/pm-trace.h index f31db2368782..ecbde7a5548e 100644 --- a/include/linux/resume-trace.h +++ b/include/linux/pm-trace.h | |||
@@ -1,8 +1,8 @@ | |||
1 | #ifndef RESUME_TRACE_H | 1 | #ifndef PM_TRACE_H |
2 | #define RESUME_TRACE_H | 2 | #define PM_TRACE_H |
3 | 3 | ||
4 | #ifdef CONFIG_PM_TRACE | 4 | #ifdef CONFIG_PM_TRACE |
5 | #include <asm/resume-trace.h> | 5 | #include <asm/pm-trace.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | 7 | ||
8 | extern int pm_trace_enabled; | 8 | extern int pm_trace_enabled; |
@@ -14,7 +14,7 @@ static inline int pm_trace_is_enabled(void) | |||
14 | 14 | ||
15 | struct device; | 15 | struct device; |
16 | extern void set_trace_device(struct device *); | 16 | extern void set_trace_device(struct device *); |
17 | extern void generate_resume_trace(const void *tracedata, unsigned int user); | 17 | extern void generate_pm_trace(const void *tracedata, unsigned int user); |
18 | extern int show_trace_dev_match(char *buf, size_t size); | 18 | extern int show_trace_dev_match(char *buf, size_t size); |
19 | 19 | ||
20 | #define TRACE_DEVICE(dev) do { \ | 20 | #define TRACE_DEVICE(dev) do { \ |
@@ -28,6 +28,7 @@ static inline int pm_trace_is_enabled(void) { return 0; } | |||
28 | 28 | ||
29 | #define TRACE_DEVICE(dev) do { } while (0) | 29 | #define TRACE_DEVICE(dev) do { } while (0) |
30 | #define TRACE_RESUME(dev) do { } while (0) | 30 | #define TRACE_RESUME(dev) do { } while (0) |
31 | #define TRACE_SUSPEND(dev) do { } while (0) | ||
31 | 32 | ||
32 | #endif | 33 | #endif |
33 | 34 | ||
diff --git a/include/linux/pm.h b/include/linux/pm.h index e2f1be6dd9dd..2d29c64f8fb1 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -603,10 +603,18 @@ extern void dev_pm_put_subsys_data(struct device *dev); | |||
603 | * Power domains provide callbacks that are executed during system suspend, | 603 | * Power domains provide callbacks that are executed during system suspend, |
604 | * hibernation, system resume and during runtime PM transitions along with | 604 | * hibernation, system resume and during runtime PM transitions along with |
605 | * subsystem-level and driver-level callbacks. | 605 | * subsystem-level and driver-level callbacks. |
606 | * | ||
607 | * @detach: Called when removing a device from the domain. | ||
608 | * @activate: Called before executing probe routines for bus types and drivers. | ||
609 | * @sync: Called after successful driver probe. | ||
610 | * @dismiss: Called after unsuccessful driver probe and after driver removal. | ||
606 | */ | 611 | */ |
607 | struct dev_pm_domain { | 612 | struct dev_pm_domain { |
608 | struct dev_pm_ops ops; | 613 | struct dev_pm_ops ops; |
609 | void (*detach)(struct device *dev, bool power_off); | 614 | void (*detach)(struct device *dev, bool power_off); |
615 | int (*activate)(struct device *dev); | ||
616 | void (*sync)(struct device *dev); | ||
617 | void (*dismiss)(struct device *dev); | ||
610 | }; | 618 | }; |
611 | 619 | ||
612 | /* | 620 | /* |
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 080e778118ba..681ccb053f72 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -127,7 +127,7 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) | |||
127 | return to_gpd_data(dev->power.subsys_data->domain_data); | 127 | return to_gpd_data(dev->power.subsys_data->domain_data); |
128 | } | 128 | } |
129 | 129 | ||
130 | extern struct generic_pm_domain *dev_to_genpd(struct device *dev); | 130 | extern struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev); |
131 | extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, | 131 | extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, |
132 | struct device *dev, | 132 | struct device *dev, |
133 | struct gpd_timing_data *td); | 133 | struct gpd_timing_data *td); |
@@ -163,9 +163,9 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) | |||
163 | { | 163 | { |
164 | return ERR_PTR(-ENOSYS); | 164 | return ERR_PTR(-ENOSYS); |
165 | } | 165 | } |
166 | static inline struct generic_pm_domain *dev_to_genpd(struct device *dev) | 166 | static inline struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev) |
167 | { | 167 | { |
168 | return ERR_PTR(-ENOSYS); | 168 | return NULL; |
169 | } | 169 | } |
170 | static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, | 170 | static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, |
171 | struct device *dev, | 171 | struct device *dev, |
diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 6512e9cbc6d5..5df733b8f704 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h | |||
@@ -510,4 +510,16 @@ static inline void pnp_unregister_driver(struct pnp_driver *drv) { } | |||
510 | 510 | ||
511 | #endif /* CONFIG_PNP */ | 511 | #endif /* CONFIG_PNP */ |
512 | 512 | ||
513 | /** | ||
514 | * module_pnp_driver() - Helper macro for registering a PnP driver | ||
515 | * @__pnp_driver: pnp_driver struct | ||
516 | * | ||
517 | * Helper macro for PnP drivers which do not do anything special in module | ||
518 | * init/exit. This eliminates a lot of boilerplate. Each module may only | ||
519 | * use this macro once, and calling it replaces module_init() and module_exit() | ||
520 | */ | ||
521 | #define module_pnp_driver(__pnp_driver) \ | ||
522 | module_driver(__pnp_driver, pnp_register_driver, \ | ||
523 | pnp_unregister_driver) | ||
524 | |||
513 | #endif /* _LINUX_PNP_H */ | 525 | #endif /* _LINUX_PNP_H */ |
diff --git a/include/linux/property.h b/include/linux/property.h index a6a3d98bd7e9..de8bdf417a35 100644 --- a/include/linux/property.h +++ b/include/linux/property.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #ifndef _LINUX_PROPERTY_H_ | 13 | #ifndef _LINUX_PROPERTY_H_ |
14 | #define _LINUX_PROPERTY_H_ | 14 | #define _LINUX_PROPERTY_H_ |
15 | 15 | ||
16 | #include <linux/fwnode.h> | ||
16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
17 | 18 | ||
18 | struct device; | 19 | struct device; |
@@ -40,16 +41,6 @@ int device_property_read_string_array(struct device *dev, const char *propname, | |||
40 | int device_property_read_string(struct device *dev, const char *propname, | 41 | int device_property_read_string(struct device *dev, const char *propname, |
41 | const char **val); | 42 | const char **val); |
42 | 43 | ||
43 | enum fwnode_type { | ||
44 | FWNODE_INVALID = 0, | ||
45 | FWNODE_OF, | ||
46 | FWNODE_ACPI, | ||
47 | }; | ||
48 | |||
49 | struct fwnode_handle { | ||
50 | enum fwnode_type type; | ||
51 | }; | ||
52 | |||
53 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); | 44 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); |
54 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, | 45 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, |
55 | const char *propname, u8 *val, | 46 | const char *propname, u8 *val, |
@@ -140,4 +131,37 @@ static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode, | |||
140 | return fwnode_property_read_u64_array(fwnode, propname, val, 1); | 131 | return fwnode_property_read_u64_array(fwnode, propname, val, 1); |
141 | } | 132 | } |
142 | 133 | ||
134 | /** | ||
135 | * struct property_entry - "Built-in" device property representation. | ||
136 | * @name: Name of the property. | ||
137 | * @type: Type of the property. | ||
138 | * @nval: Number of items of type @type making up the value. | ||
139 | * @value: Value of the property (an array of @nval items of type @type). | ||
140 | */ | ||
141 | struct property_entry { | ||
142 | const char *name; | ||
143 | enum dev_prop_type type; | ||
144 | size_t nval; | ||
145 | union { | ||
146 | void *raw_data; | ||
147 | u8 *u8_data; | ||
148 | u16 *u16_data; | ||
149 | u32 *u32_data; | ||
150 | u64 *u64_data; | ||
151 | const char **str; | ||
152 | } value; | ||
153 | }; | ||
154 | |||
155 | /** | ||
156 | * struct property_set - Collection of "built-in" device properties. | ||
157 | * @fwnode: Handle to be pointed to by the fwnode field of struct device. | ||
158 | * @properties: Array of properties terminated with a null entry. | ||
159 | */ | ||
160 | struct property_set { | ||
161 | struct fwnode_handle fwnode; | ||
162 | struct property_entry *properties; | ||
163 | }; | ||
164 | |||
165 | void device_add_property_set(struct device *dev, struct property_set *pset); | ||
166 | |||
143 | #endif /* _LINUX_PROPERTY_H_ */ | 167 | #endif /* _LINUX_PROPERTY_H_ */ |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 9a59d042ea84..86e8157a450f 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | #include <linux/kobject.h> | 12 | #include <linux/kobject.h> |
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/resume-trace.h> | 14 | #include <linux/pm-trace.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index b7d6b3a721b1..8d7a1ef72758 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/ftrace.h> | 28 | #include <linux/ftrace.h> |
29 | #include <trace/events/power.h> | 29 | #include <trace/events/power.h> |
30 | #include <linux/compiler.h> | 30 | #include <linux/compiler.h> |
31 | #include <linux/moduleparam.h> | ||
31 | 32 | ||
32 | #include "power.h" | 33 | #include "power.h" |
33 | 34 | ||
@@ -233,12 +234,20 @@ static bool platform_suspend_again(suspend_state_t state) | |||
233 | suspend_ops->suspend_again() : false; | 234 | suspend_ops->suspend_again() : false; |
234 | } | 235 | } |
235 | 236 | ||
237 | #ifdef CONFIG_PM_DEBUG | ||
238 | static unsigned int pm_test_delay = 5; | ||
239 | module_param(pm_test_delay, uint, 0644); | ||
240 | MODULE_PARM_DESC(pm_test_delay, | ||
241 | "Number of seconds to wait before resuming from suspend test"); | ||
242 | #endif | ||
243 | |||
236 | static int suspend_test(int level) | 244 | static int suspend_test(int level) |
237 | { | 245 | { |
238 | #ifdef CONFIG_PM_DEBUG | 246 | #ifdef CONFIG_PM_DEBUG |
239 | if (pm_test_level == level) { | 247 | if (pm_test_level == level) { |
240 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | 248 | printk(KERN_INFO "suspend debug: Waiting for %d second(s).\n", |
241 | mdelay(5000); | 249 | pm_test_delay); |
250 | mdelay(pm_test_delay * 1000); | ||
242 | return 1; | 251 | return 1; |
243 | } | 252 | } |
244 | #endif /* !CONFIG_PM_DEBUG */ | 253 | #endif /* !CONFIG_PM_DEBUG */ |