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 */ |
