From 40b4c2b4627d41ed00b84a1a45cbcea8602dff9c Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 22 Dec 2009 22:50:33 +0000 Subject: [PATCH] --- yaml --- r: 186462 b: refs/heads/master c: 9ceb38e6b691debe4bf04cb63165c503a8556177 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/cpu-freq/pcc-cpufreq.txt | 207 ------ trunk/Documentation/power/runtime_pm.txt | 93 --- trunk/arch/parisc/include/asm/unistd.h | 3 +- trunk/arch/parisc/kernel/syscall_table.S | 1 + trunk/arch/x86/kernel/cpu/cpufreq/Kconfig | 14 - trunk/arch/x86/kernel/cpu/cpufreq/Makefile | 1 - .../arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | 620 ------------------ trunk/drivers/acpi/processor_core.c | 2 - trunk/drivers/base/power/Makefile | 1 - trunk/drivers/base/power/generic_ops.c | 233 ------- trunk/drivers/gpu/drm/Kconfig | 1 + trunk/drivers/usb/core/devices.c | 69 +- trunk/drivers/virtio/virtio_pci.c | 1 - trunk/fs/ubifs/Kconfig | 1 + trunk/include/linux/pm.h | 51 +- trunk/include/linux/pm_runtime.h | 6 - trunk/lib/Kconfig | 3 + trunk/lib/Makefile | 3 +- trunk/lib/vsprintf.c | 71 +- 20 files changed, 96 insertions(+), 1287 deletions(-) delete mode 100644 trunk/Documentation/cpu-freq/pcc-cpufreq.txt delete mode 100644 trunk/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c delete mode 100644 trunk/drivers/base/power/generic_ops.c diff --git a/[refs] b/[refs] index 26e212fa6be0..9050ca8788c5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5980bb3ee6e733d66eea04c221a140dea15d52de +refs/heads/master: 9ceb38e6b691debe4bf04cb63165c503a8556177 diff --git a/trunk/Documentation/cpu-freq/pcc-cpufreq.txt b/trunk/Documentation/cpu-freq/pcc-cpufreq.txt deleted file mode 100644 index 9e3c3b33514c..000000000000 --- a/trunk/Documentation/cpu-freq/pcc-cpufreq.txt +++ /dev/null @@ -1,207 +0,0 @@ -/* - * pcc-cpufreq.txt - PCC interface documentation - * - * Copyright (C) 2009 Red Hat, Matthew Garrett - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * Nagananda Chumbalkar - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON - * INFRINGEMENT. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - - - Processor Clocking Control Driver - --------------------------------- - -Contents: ---------- -1. Introduction -1.1 PCC interface -1.1.1 Get Average Frequency -1.1.2 Set Desired Frequency -1.2 Platforms affected -2. Driver and /sys details -2.1 scaling_available_frequencies -2.2 cpuinfo_transition_latency -2.3 cpuinfo_cur_freq -2.4 related_cpus -3. Caveats - -1. Introduction: ----------------- -Processor Clocking Control (PCC) is an interface between the platform -firmware and OSPM. It is a mechanism for coordinating processor -performance (ie: frequency) between the platform firmware and the OS. - -The PCC driver (pcc-cpufreq) allows OSPM to take advantage of the PCC -interface. - -OS utilizes the PCC interface to inform platform firmware what frequency the -OS wants for a logical processor. The platform firmware attempts to achieve -the requested frequency. If the request for the target frequency could not be -satisfied by platform firmware, then it usually means that power budget -conditions are in place, and "power capping" is taking place. - -1.1 PCC interface: ------------------- -The complete PCC specification is available here: -http://www.acpica.org/download/Processor-Clocking-Control-v1p0.pdf - -PCC relies on a shared memory region that provides a channel for communication -between the OS and platform firmware. PCC also implements a "doorbell" that -is used by the OS to inform the platform firmware that a command has been -sent. - -The ACPI PCCH() method is used to discover the location of the PCC shared -memory region. The shared memory region header contains the "command" and -"status" interface. PCCH() also contains details on how to access the platform -doorbell. - -The following commands are supported by the PCC interface: -* Get Average Frequency -* Set Desired Frequency - -The ACPI PCCP() method is implemented for each logical processor and is -used to discover the offsets for the input and output buffers in the shared -memory region. - -When PCC mode is enabled, the platform will not expose processor performance -or throttle states (_PSS, _TSS and related ACPI objects) to OSPM. Therefore, -the native P-state driver (such as acpi-cpufreq for Intel, powernow-k8 for -AMD) will not load. - -However, OSPM remains in control of policy. The governor (eg: "ondemand") -computes the required performance for each processor based on server workload. -The PCC driver fills in the command interface, and the input buffer and -communicates the request to the platform firmware. The platform firmware is -responsible for delivering the requested performance. - -Each PCC command is "global" in scope and can affect all the logical CPUs in -the system. Therefore, PCC is capable of performing "group" updates. With PCC -the OS is capable of getting/setting the frequency of all the logical CPUs in -the system with a single call to the BIOS. - -1.1.1 Get Average Frequency: ----------------------------- -This command is used by the OSPM to query the running frequency of the -processor since the last time this command was completed. The output buffer -indicates the average unhalted frequency of the logical processor expressed as -a percentage of the nominal (ie: maximum) CPU frequency. The output buffer -also signifies if the CPU frequency is limited by a power budget condition. - -1.1.2 Set Desired Frequency: ----------------------------- -This command is used by the OSPM to communicate to the platform firmware the -desired frequency for a logical processor. The output buffer is currently -ignored by OSPM. The next invocation of "Get Average Frequency" will inform -OSPM if the desired frequency was achieved or not. - -1.2 Platforms affected: ------------------------ -The PCC driver will load on any system where the platform firmware: -* supports the PCC interface, and the associated PCCH() and PCCP() methods -* assumes responsibility for managing the hardware clocking controls in order -to deliver the requested processor performance - -Currently, certain HP ProLiant platforms implement the PCC interface. On those -platforms PCC is the "default" choice. - -However, it is possible to disable this interface via a BIOS setting. In -such an instance, as is also the case on platforms where the PCC interface -is not implemented, the PCC driver will fail to load silently. - -2. Driver and /sys details: ---------------------------- -When the driver loads, it merely prints the lowest and the highest CPU -frequencies supported by the platform firmware. - -The PCC driver loads with a message such as: -pcc-cpufreq: (v1.00.00) driver loaded with frequency limits: 1600 MHz, 2933 -MHz - -This means that the OPSM can request the CPU to run at any frequency in -between the limits (1600 MHz, and 2933 MHz) specified in the message. - -Internally, there is no need for the driver to convert the "target" frequency -to a corresponding P-state. - -The VERSION number for the driver will be of the format v.xy.ab. -eg: 1.00.02 - ----- -- - | | - | -- this will increase with bug fixes/enhancements to the driver - |-- this is the version of the PCC specification the driver adheres to - - -The following is a brief discussion on some of the fields exported via the -/sys filesystem and how their values are affected by the PCC driver: - -2.1 scaling_available_frequencies: ----------------------------------- -scaling_available_frequencies is not created in /sys. No intermediate -frequencies need to be listed because the BIOS will try to achieve any -frequency, within limits, requested by the governor. A frequency does not have -to be strictly associated with a P-state. - -2.2 cpuinfo_transition_latency: -------------------------------- -The cpuinfo_transition_latency field is 0. The PCC specification does -not include a field to expose this value currently. - -2.3 cpuinfo_cur_freq: ---------------------- -A) Often cpuinfo_cur_freq will show a value different than what is declared -in the scaling_available_frequencies or scaling_cur_freq, or scaling_max_freq. -This is due to "turbo boost" available on recent Intel processors. If certain -conditions are met the BIOS can achieve a slightly higher speed than requested -by OSPM. An example: - -scaling_cur_freq : 2933000 -cpuinfo_cur_freq : 3196000 - -B) There is a round-off error associated with the cpuinfo_cur_freq value. -Since the driver obtains the current frequency as a "percentage" (%) of the -nominal frequency from the BIOS, sometimes, the values displayed by -scaling_cur_freq and cpuinfo_cur_freq may not match. An example: - -scaling_cur_freq : 1600000 -cpuinfo_cur_freq : 1583000 - -In this example, the nominal frequency is 2933 MHz. The driver obtains the -current frequency, cpuinfo_cur_freq, as 54% of the nominal frequency: - - 54% of 2933 MHz = 1583 MHz - -Nominal frequency is the maximum frequency of the processor, and it usually -corresponds to the frequency of the P0 P-state. - -2.4 related_cpus: ------------------ -The related_cpus field is identical to affected_cpus. - -affected_cpus : 4 -related_cpus : 4 - -Currently, the PCC driver does not evaluate _PSD. The platforms that support -PCC do not implement SW_ALL. So OSPM doesn't need to perform any coordination -to ensure that the same frequency is requested of all dependent CPUs. - -3. Caveats: ------------ -The "cpufreq_stats" module in its present form cannot be loaded and -expected to work with the PCC driver. Since the "cpufreq_stats" module -provides information wrt each P-state, it is not applicable to the PCC driver. diff --git a/trunk/Documentation/power/runtime_pm.txt b/trunk/Documentation/power/runtime_pm.txt index ab00eeddecaf..356fd86f4ea8 100644 --- a/trunk/Documentation/power/runtime_pm.txt +++ b/trunk/Documentation/power/runtime_pm.txt @@ -224,12 +224,6 @@ defined in include/linux/pm.h: RPM_SUSPENDED, which means that each device is initially regarded by the PM core as 'suspended', regardless of its real hardware status - unsigned int runtime_auto; - - if set, indicates that the user space has allowed the device driver to - power manage the device at run time via the /sys/devices/.../power/control - interface; it may only be modified with the help of the pm_runtime_allow() - and pm_runtime_forbid() helper functions - All of the above fields are members of the 'power' member of 'struct device'. 4. Run-time PM Device Helper Functions @@ -335,20 +329,6 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: 'power.runtime_error' is set or 'power.disable_depth' is greater than zero) - bool pm_runtime_suspended(struct device *dev); - - return true if the device's runtime PM status is 'suspended', or false - otherwise - - void pm_runtime_allow(struct device *dev); - - set the power.runtime_auto flag for the device and decrease its usage - counter (used by the /sys/devices/.../power/control interface to - effectively allow the device to be power managed at run time) - - void pm_runtime_forbid(struct device *dev); - - unset the power.runtime_auto flag for the device and increase its usage - counter (used by the /sys/devices/.../power/control interface to - effectively prevent the device from being power managed at run time) - It is safe to execute the following helper functions from interrupt context: pm_request_idle() @@ -402,18 +382,6 @@ may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core uses pm_runtime_idle_sync() to invoke the subsystem-level idle callback for the device at that time. -The user space can effectively disallow the driver of the device to power manage -it at run time by changing the value of its /sys/devices/.../power/control -attribute to "on", which causes pm_runtime_forbid() to be called. In principle, -this mechanism may also be used by the driver to effectively turn off the -run-time power management of the device until the user space turns it on. -Namely, during the initialization the driver can make sure that the run-time PM -status of the device is 'active' and call pm_runtime_forbid(). It should be -noted, however, that if the user space has already intentionally changed the -value of /sys/devices/.../power/control to "auto" to allow the driver to power -manage the device at run time, the driver may confuse it by using -pm_runtime_forbid() this way. - 6. Run-time PM and System Sleep Run-time PM and system sleep (i.e., system suspend and hibernation, also known @@ -463,64 +431,3 @@ The PM core always increments the run-time usage counter before calling the ->prepare() callback and decrements it after calling the ->complete() callback. Hence disabling run-time PM temporarily like this will not cause any run-time suspend callbacks to be lost. - -7. Generic subsystem callbacks - -Subsystems may wish to conserve code space by using the set of generic power -management callbacks provided by the PM core, defined in -driver/base/power/generic_ops.c: - - int pm_generic_runtime_idle(struct device *dev); - - invoke the ->runtime_idle() callback provided by the driver of this - device, if defined, and call pm_runtime_suspend() for this device if the - return value is 0 or the callback is not defined - - int pm_generic_runtime_suspend(struct device *dev); - - invoke the ->runtime_suspend() callback provided by the driver of this - device and return its result, or return -EINVAL if not defined - - int pm_generic_runtime_resume(struct device *dev); - - invoke the ->runtime_resume() callback provided by the driver of this - device and return its result, or return -EINVAL if not defined - - int pm_generic_suspend(struct device *dev); - - if the device has not been suspended at run time, invoke the ->suspend() - callback provided by its driver and return its result, or return 0 if not - defined - - int pm_generic_resume(struct device *dev); - - invoke the ->resume() callback provided by the driver of this device and, - if successful, change the device's runtime PM status to 'active' - - int pm_generic_freeze(struct device *dev); - - if the device has not been suspended at run time, invoke the ->freeze() - callback provided by its driver and return its result, or return 0 if not - defined - - int pm_generic_thaw(struct device *dev); - - if the device has not been suspended at run time, invoke the ->thaw() - callback provided by its driver and return its result, or return 0 if not - defined - - int pm_generic_poweroff(struct device *dev); - - if the device has not been suspended at run time, invoke the ->poweroff() - callback provided by its driver and return its result, or return 0 if not - defined - - int pm_generic_restore(struct device *dev); - - invoke the ->restore() callback provided by the driver of this device and, - if successful, change the device's runtime PM status to 'active' - -These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(), -->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(), -or ->restore() callback pointers in the subsystem-level dev_pm_ops structures. - -If a subsystem wishes to use all of them at the same time, it can simply assign -the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its -dev_pm_ops structure pointer. - -Device drivers that wish to use the same function as a system suspend, freeze, -poweroff and run-time suspend callback, and similarly for system resume, thaw, -restore, and run-time resume, can achieve this with the help of the -UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its -last argument to NULL). diff --git a/trunk/arch/parisc/include/asm/unistd.h b/trunk/arch/parisc/include/asm/unistd.h index cda158318c62..ee6363463b72 100644 --- a/trunk/arch/parisc/include/asm/unistd.h +++ b/trunk/arch/parisc/include/asm/unistd.h @@ -811,8 +811,9 @@ #define __NR_pwritev (__NR_Linux + 316) #define __NR_rt_tgsigqueueinfo (__NR_Linux + 317) #define __NR_perf_event_open (__NR_Linux + 318) +#define __NR_recvmmsg (__NR_Linux + 319) -#define __NR_Linux_syscalls (__NR_perf_event_open + 1) +#define __NR_Linux_syscalls (__NR_recvmmsg + 1) #define __IGNORE_select /* newselect */ diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index 01c4fcf8f481..a0c54cf81949 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -417,6 +417,7 @@ ENTRY_COMP(pwritev) ENTRY_COMP(rt_tgsigqueueinfo) ENTRY_SAME(perf_event_open) + ENTRY_COMP(recvmmsg) /* Nothing yet */ diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig index 870e6cc6ad28..f138c6c389b9 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig @@ -10,20 +10,6 @@ if CPU_FREQ comment "CPUFreq processor drivers" -config X86_PCC_CPUFREQ - tristate "Processor Clocking Control interface driver" - depends on ACPI && ACPI_PROCESSOR - help - This driver adds support for the PCC interface. - - For details, take a look at: - . - - To compile this driver as a module, choose M here: the - module will be called pcc-cpufreq. - - If in doubt, say N. - config X86_ACPI_CPUFREQ tristate "ACPI Processor P-States driver" select CPU_FREQ_TABLE diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Makefile b/trunk/arch/x86/kernel/cpu/cpufreq/Makefile index 1840c0a5170b..509296df294d 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/Makefile +++ b/trunk/arch/x86/kernel/cpu/cpufreq/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o -obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o obj-$(CONFIG_X86_LONGHAUL) += longhaul.o diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c deleted file mode 100644 index ff36d2979a90..000000000000 --- a/trunk/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface - * - * Copyright (C) 2009 Red Hat, Matthew Garrett - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * Nagananda Chumbalkar - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON - * INFRINGEMENT. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define PCC_VERSION "1.00.00" -#define POLL_LOOPS 300 - -#define CMD_COMPLETE 0x1 -#define CMD_GET_FREQ 0x0 -#define CMD_SET_FREQ 0x1 - -#define BUF_SZ 4 - -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "pcc-cpufreq", msg) - -struct pcc_register_resource { - u8 descriptor; - u16 length; - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 access_size; - u64 address; -} __attribute__ ((packed)); - -struct pcc_memory_resource { - u8 descriptor; - u16 length; - u8 space_id; - u8 resource_usage; - u8 type_specific; - u64 granularity; - u64 minimum; - u64 maximum; - u64 translation_offset; - u64 address_length; -} __attribute__ ((packed)); - -static struct cpufreq_driver pcc_cpufreq_driver; - -struct pcc_header { - u32 signature; - u16 length; - u8 major; - u8 minor; - u32 features; - u16 command; - u16 status; - u32 latency; - u32 minimum_time; - u32 maximum_time; - u32 nominal; - u32 throttled_frequency; - u32 minimum_frequency; -}; - -static void __iomem *pcch_virt_addr; -static struct pcc_header __iomem *pcch_hdr; - -static DEFINE_SPINLOCK(pcc_lock); - -static struct acpi_generic_address doorbell; - -static u64 doorbell_preserve; -static u64 doorbell_write; - -static u8 OSC_UUID[16] = {0x63, 0x9B, 0x2C, 0x9F, 0x70, 0x91, 0x49, 0x1f, - 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46}; - -struct pcc_cpu { - u32 input_offset; - u32 output_offset; -}; - -static struct pcc_cpu *pcc_cpu_info; - -static int pcc_cpufreq_verify(struct cpufreq_policy *policy) -{ - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - return 0; -} - -static inline void pcc_cmd(void) -{ - u64 doorbell_value; - int i; - - acpi_read(&doorbell_value, &doorbell); - acpi_write((doorbell_value & doorbell_preserve) | doorbell_write, - &doorbell); - - for (i = 0; i < POLL_LOOPS; i++) { - if (ioread16(&pcch_hdr->status) & CMD_COMPLETE) - break; - } -} - -static inline void pcc_clear_mapping(void) -{ - if (pcch_virt_addr) - iounmap(pcch_virt_addr); - pcch_virt_addr = NULL; -} - -static unsigned int pcc_get_freq(unsigned int cpu) -{ - struct pcc_cpu *pcc_cpu_data; - unsigned int curr_freq; - unsigned int freq_limit; - u16 status; - u32 input_buffer; - u32 output_buffer; - - spin_lock(&pcc_lock); - - dprintk("get: get_freq for CPU %d\n", cpu); - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - input_buffer = 0x1; - iowrite32(input_buffer, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - iowrite16(CMD_GET_FREQ, &pcch_hdr->command); - - pcc_cmd(); - - output_buffer = - ioread32(pcch_virt_addr + pcc_cpu_data->output_offset); - - /* Clear the input buffer - we are done with the current command */ - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - - status = ioread16(&pcch_hdr->status); - if (status != CMD_COMPLETE) { - dprintk("get: FAILED: for CPU %d, status is %d\n", - cpu, status); - goto cmd_incomplete; - } - iowrite16(0, &pcch_hdr->status); - curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff)) - / 100) * 1000); - - dprintk("get: SUCCESS: (virtual) output_offset for cpu %d is " - "0x%x, contains a value of: 0x%x. Speed is: %d MHz\n", - cpu, (pcch_virt_addr + pcc_cpu_data->output_offset), - output_buffer, curr_freq); - - freq_limit = (output_buffer >> 8) & 0xff; - if (freq_limit != 0xff) { - dprintk("get: frequency for cpu %d is being temporarily" - " capped at %d\n", cpu, curr_freq); - } - - spin_unlock(&pcc_lock); - return curr_freq; - -cmd_incomplete: - iowrite16(0, &pcch_hdr->status); - spin_unlock(&pcc_lock); - return -EINVAL; -} - -static int pcc_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct pcc_cpu *pcc_cpu_data; - struct cpufreq_freqs freqs; - u16 status; - u32 input_buffer; - int cpu; - - spin_lock(&pcc_lock); - cpu = policy->cpu; - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - dprintk("target: CPU %d should go to target freq: %d " - "(virtual) input_offset is 0x%x\n", - cpu, target_freq, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - - freqs.new = target_freq; - freqs.cpu = cpu; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - input_buffer = 0x1 | (((target_freq * 100) - / (ioread32(&pcch_hdr->nominal) * 1000)) << 8); - iowrite32(input_buffer, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - iowrite16(CMD_SET_FREQ, &pcch_hdr->command); - - pcc_cmd(); - - /* Clear the input buffer - we are done with the current command */ - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - - status = ioread16(&pcch_hdr->status); - if (status != CMD_COMPLETE) { - dprintk("target: FAILED for cpu %d, with status: 0x%x\n", - cpu, status); - goto cmd_incomplete; - } - iowrite16(0, &pcch_hdr->status); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - dprintk("target: was SUCCESSFUL for cpu %d\n", cpu); - spin_unlock(&pcc_lock); - - return 0; - -cmd_incomplete: - iowrite16(0, &pcch_hdr->status); - spin_unlock(&pcc_lock); - return -EINVAL; -} - -static int pcc_get_offset(int cpu) -{ - acpi_status status; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *pccp, *offset; - struct pcc_cpu *pcc_cpu_data; - struct acpi_processor *pr; - int ret = 0; - - pr = per_cpu(processors, cpu); - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer); - if (ACPI_FAILURE(status)) - return -ENODEV; - - pccp = buffer.pointer; - if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) { - ret = -ENODEV; - goto out_free; - }; - - offset = &(pccp->package.elements[0]); - if (!offset || offset->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto out_free; - } - - pcc_cpu_data->input_offset = offset->integer.value; - - offset = &(pccp->package.elements[1]); - if (!offset || offset->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto out_free; - } - - pcc_cpu_data->output_offset = offset->integer.value; - - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ); - - dprintk("pcc_get_offset: for CPU %d: pcc_cpu_data " - "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n", - cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset); -out_free: - kfree(buffer.pointer); - return ret; -} - -static int __init pcc_cpufreq_do_osc(acpi_handle *handle) -{ - acpi_status status; - struct acpi_object_list input; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object in_params[4]; - union acpi_object *out_obj; - u32 capabilities[2]; - u32 errors; - u32 supported; - int ret = 0; - - input.count = 4; - input.pointer = in_params; - input.count = 4; - input.pointer = in_params; - in_params[0].type = ACPI_TYPE_BUFFER; - in_params[0].buffer.length = 16; - in_params[0].buffer.pointer = OSC_UUID; - in_params[1].type = ACPI_TYPE_INTEGER; - in_params[1].integer.value = 1; - in_params[2].type = ACPI_TYPE_INTEGER; - in_params[2].integer.value = 2; - in_params[3].type = ACPI_TYPE_BUFFER; - in_params[3].buffer.length = 8; - in_params[3].buffer.pointer = (u8 *)&capabilities; - - capabilities[0] = OSC_QUERY_ENABLE; - capabilities[1] = 0x1; - - status = acpi_evaluate_object(*handle, "_OSC", &input, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - if (!output.length) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) { - ret = -ENODEV; - goto out_free; - } - - supported = *((u32 *)(out_obj->buffer.pointer + 4)); - if (!(supported & 0x1)) { - ret = -ENODEV; - goto out_free; - } - - kfree(output.pointer); - capabilities[0] = 0x0; - capabilities[1] = 0x1; - - status = acpi_evaluate_object(*handle, "_OSC", &input, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - if (!output.length) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) { - ret = -ENODEV; - goto out_free; - } - - supported = *((u32 *)(out_obj->buffer.pointer + 4)); - if (!(supported & 0x1)) { - ret = -ENODEV; - goto out_free; - } - -out_free: - kfree(output.pointer); - return ret; -} - -static int __init pcc_cpufreq_probe(void) -{ - acpi_status status; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - struct pcc_memory_resource *mem_resource; - struct pcc_register_resource *reg_resource; - union acpi_object *out_obj, *member; - acpi_handle handle, osc_handle; - int ret = 0; - - status = acpi_get_handle(NULL, "\\_SB", &handle); - if (ACPI_FAILURE(status)) - return -ENODEV; - - status = acpi_get_handle(handle, "_OSC", &osc_handle); - if (ACPI_SUCCESS(status)) { - ret = pcc_cpufreq_do_osc(&osc_handle); - if (ret) - dprintk("probe: _OSC evaluation did not succeed\n"); - /* Firmware's use of _OSC is optional */ - ret = 0; - } - - status = acpi_evaluate_object(handle, "PCCH", NULL, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_PACKAGE) { - ret = -ENODEV; - goto out_free; - } - - member = &out_obj->package.elements[0]; - if (member->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - mem_resource = (struct pcc_memory_resource *)member->buffer.pointer; - - dprintk("probe: mem_resource descriptor: 0x%x," - " length: %d, space_id: %d, resource_usage: %d," - " type_specific: %d, granularity: 0x%llx," - " minimum: 0x%llx, maximum: 0x%llx," - " translation_offset: 0x%llx, address_length: 0x%llx\n", - mem_resource->descriptor, mem_resource->length, - mem_resource->space_id, mem_resource->resource_usage, - mem_resource->type_specific, mem_resource->granularity, - mem_resource->minimum, mem_resource->maximum, - mem_resource->translation_offset, - mem_resource->address_length); - - if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { - ret = -ENODEV; - goto out_free; - } - - pcch_virt_addr = ioremap_nocache(mem_resource->minimum, - mem_resource->address_length); - if (pcch_virt_addr == NULL) { - dprintk("probe: could not map shared mem region\n"); - goto out_free; - } - pcch_hdr = pcch_virt_addr; - - dprintk("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr); - dprintk("probe: PCCH header is at physical address: 0x%llx," - " signature: 0x%x, length: %d bytes, major: %d, minor: %d," - " supported features: 0x%x, command field: 0x%x," - " status field: 0x%x, nominal latency: %d us\n", - mem_resource->minimum, ioread32(&pcch_hdr->signature), - ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major), - ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features), - ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status), - ioread32(&pcch_hdr->latency)); - - dprintk("probe: min time between commands: %d us," - " max time between commands: %d us," - " nominal CPU frequency: %d MHz," - " minimum CPU frequency: %d MHz," - " minimum CPU frequency without throttling: %d MHz\n", - ioread32(&pcch_hdr->minimum_time), - ioread32(&pcch_hdr->maximum_time), - ioread32(&pcch_hdr->nominal), - ioread32(&pcch_hdr->throttled_frequency), - ioread32(&pcch_hdr->minimum_frequency)); - - member = &out_obj->package.elements[1]; - if (member->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto pcch_free; - } - - reg_resource = (struct pcc_register_resource *)member->buffer.pointer; - - doorbell.space_id = reg_resource->space_id; - doorbell.bit_width = reg_resource->bit_width; - doorbell.bit_offset = reg_resource->bit_offset; - doorbell.access_width = 64; - doorbell.address = reg_resource->address; - - dprintk("probe: doorbell: space_id is %d, bit_width is %d, " - "bit_offset is %d, access_width is %d, address is 0x%llx\n", - doorbell.space_id, doorbell.bit_width, doorbell.bit_offset, - doorbell.access_width, reg_resource->address); - - member = &out_obj->package.elements[2]; - if (member->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto pcch_free; - } - - doorbell_preserve = member->integer.value; - - member = &out_obj->package.elements[3]; - if (member->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto pcch_free; - } - - doorbell_write = member->integer.value; - - dprintk("probe: doorbell_preserve: 0x%llx," - " doorbell_write: 0x%llx\n", - doorbell_preserve, doorbell_write); - - pcc_cpu_info = alloc_percpu(struct pcc_cpu); - if (!pcc_cpu_info) { - ret = -ENOMEM; - goto pcch_free; - } - - printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency" - " limits: %d MHz, %d MHz\n", PCC_VERSION, - ioread32(&pcch_hdr->minimum_frequency), - ioread32(&pcch_hdr->nominal)); - kfree(output.pointer); - return ret; -pcch_free: - pcc_clear_mapping(); -out_free: - kfree(output.pointer); - return ret; -} - -static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - unsigned int result = 0; - - if (!pcch_virt_addr) { - result = -1; - goto pcch_null; - } - - result = pcc_get_offset(cpu); - if (result) { - dprintk("init: PCCP evaluation failed\n"); - goto free; - } - - policy->max = policy->cpuinfo.max_freq = - ioread32(&pcch_hdr->nominal) * 1000; - policy->min = policy->cpuinfo.min_freq = - ioread32(&pcch_hdr->minimum_frequency) * 1000; - policy->cur = pcc_get_freq(cpu); - - dprintk("init: policy->max is %d, policy->min is %d\n", - policy->max, policy->min); - - return 0; -free: - pcc_clear_mapping(); - free_percpu(pcc_cpu_info); -pcch_null: - return result; -} - -static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy) -{ - return 0; -} - -static struct cpufreq_driver pcc_cpufreq_driver = { - .flags = CPUFREQ_CONST_LOOPS, - .get = pcc_get_freq, - .verify = pcc_cpufreq_verify, - .target = pcc_cpufreq_target, - .init = pcc_cpufreq_cpu_init, - .exit = pcc_cpufreq_cpu_exit, - .name = "pcc-cpufreq", - .owner = THIS_MODULE, -}; - -static int __init pcc_cpufreq_init(void) -{ - int ret; - - if (acpi_disabled) - return 0; - - ret = pcc_cpufreq_probe(); - if (ret) { - dprintk("pcc_cpufreq_init: PCCH evaluation failed\n"); - return ret; - } - - ret = cpufreq_register_driver(&pcc_cpufreq_driver); - - return ret; -} - -static void __exit pcc_cpufreq_exit(void) -{ - cpufreq_unregister_driver(&pcc_cpufreq_driver); - - pcc_clear_mapping(); - - free_percpu(pcc_cpu_info); -} - -MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); -MODULE_VERSION(PCC_VERSION); -MODULE_DESCRIPTION("Processor Clocking Control interface driver"); -MODULE_LICENSE("GPL"); - -late_initcall(pcc_cpufreq_init); -module_exit(pcc_cpufreq_exit); diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index e9b7b402dbfb..9863c98c81ba 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -123,8 +123,6 @@ static const struct file_operations acpi_processor_info_fops = { #endif DEFINE_PER_CPU(struct acpi_processor *, processors); -EXPORT_PER_CPU_SYMBOL(processors); - struct acpi_processor_errata errata __read_mostly; /* -------------------------------------------------------------------------- diff --git a/trunk/drivers/base/power/Makefile b/trunk/drivers/base/power/Makefile index 89de75325cea..3ce3519e8f30 100644 --- a/trunk/drivers/base/power/Makefile +++ b/trunk/drivers/base/power/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_PM) += sysfs.o obj-$(CONFIG_PM_SLEEP) += main.o obj-$(CONFIG_PM_RUNTIME) += runtime.o -obj-$(CONFIG_PM_OPS) += generic_ops.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/trunk/drivers/base/power/generic_ops.c b/trunk/drivers/base/power/generic_ops.c deleted file mode 100644 index 4b29d4981253..000000000000 --- a/trunk/drivers/base/power/generic_ops.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems - * - * Copyright (c) 2010 Rafael J. Wysocki , Novell Inc. - * - * This file is released under the GPLv2. - */ - -#include -#include - -#ifdef CONFIG_PM_RUNTIME -/** - * pm_generic_runtime_idle - Generic runtime idle callback for subsystems. - * @dev: Device to handle. - * - * If PM operations are defined for the @dev's driver and they include - * ->runtime_idle(), execute it and return its error code, if nonzero. - * Otherwise, execute pm_runtime_suspend() for the device and return 0. - */ -int pm_generic_runtime_idle(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm && pm->runtime_idle) { - int ret = pm->runtime_idle(dev); - if (ret) - return ret; - } - - pm_runtime_suspend(dev); - return 0; -} -EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); - -/** - * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. - * @dev: Device to suspend. - * - * If PM operations are defined for the @dev's driver and they include - * ->runtime_suspend(), execute it and return its error code. Otherwise, - * return -EINVAL. - */ -int pm_generic_runtime_suspend(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int ret; - - ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL; - - return ret; -} -EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); - -/** - * pm_generic_runtime_resume - Generic runtime resume callback for subsystems. - * @dev: Device to resume. - * - * If PM operations are defined for the @dev's driver and they include - * ->runtime_resume(), execute it and return its error code. Otherwise, - * return -EINVAL. - */ -int pm_generic_runtime_resume(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int ret; - - ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL; - - return ret; -} -EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); -#endif /* CONFIG_PM_RUNTIME */ - -#ifdef CONFIG_PM_SLEEP -/** - * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. - * @dev: Device to handle. - * @event: PM transition of the system under way. - * - * If the device has not been suspended at run time, execute the - * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and - * return its error code. Otherwise, return zero. - */ -static int __pm_generic_call(struct device *dev, int event) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*callback)(struct device *); - - if (!pm || pm_runtime_suspended(dev)) - return 0; - - switch (event) { - case PM_EVENT_SUSPEND: - callback = pm->suspend; - break; - case PM_EVENT_FREEZE: - callback = pm->freeze; - break; - case PM_EVENT_HIBERNATE: - callback = pm->poweroff; - break; - case PM_EVENT_THAW: - callback = pm->thaw; - break; - default: - callback = NULL; - break; - } - - return callback ? callback(dev) : 0; -} - -/** - * pm_generic_suspend - Generic suspend callback for subsystems. - * @dev: Device to suspend. - */ -int pm_generic_suspend(struct device *dev) -{ - return __pm_generic_call(dev, PM_EVENT_SUSPEND); -} -EXPORT_SYMBOL_GPL(pm_generic_suspend); - -/** - * pm_generic_freeze - Generic freeze callback for subsystems. - * @dev: Device to freeze. - */ -int pm_generic_freeze(struct device *dev) -{ - return __pm_generic_call(dev, PM_EVENT_FREEZE); -} -EXPORT_SYMBOL_GPL(pm_generic_freeze); - -/** - * pm_generic_poweroff - Generic poweroff callback for subsystems. - * @dev: Device to handle. - */ -int pm_generic_poweroff(struct device *dev) -{ - return __pm_generic_call(dev, PM_EVENT_HIBERNATE); -} -EXPORT_SYMBOL_GPL(pm_generic_poweroff); - -/** - * pm_generic_thaw - Generic thaw callback for subsystems. - * @dev: Device to thaw. - */ -int pm_generic_thaw(struct device *dev) -{ - return __pm_generic_call(dev, PM_EVENT_THAW); -} -EXPORT_SYMBOL_GPL(pm_generic_thaw); - -/** - * __pm_generic_resume - Generic resume/restore callback for subsystems. - * @dev: Device to handle. - * @event: PM transition of the system under way. - * - * Execute the resume/resotre callback provided by the @dev's driver, if - * defined. If it returns 0, change the device's runtime PM status to 'active'. - * Return the callback's error code. - */ -static int __pm_generic_resume(struct device *dev, int event) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*callback)(struct device *); - int ret; - - if (!pm) - return 0; - - switch (event) { - case PM_EVENT_RESUME: - callback = pm->resume; - break; - case PM_EVENT_RESTORE: - callback = pm->restore; - break; - default: - callback = NULL; - break; - } - - if (!callback) - return 0; - - ret = callback(dev); - if (!ret) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - - return ret; -} - -/** - * pm_generic_resume - Generic resume callback for subsystems. - * @dev: Device to resume. - */ -int pm_generic_resume(struct device *dev) -{ - return __pm_generic_resume(dev, PM_EVENT_RESUME); -} -EXPORT_SYMBOL_GPL(pm_generic_resume); - -/** - * pm_generic_restore - Generic restore callback for subsystems. - * @dev: Device to restore. - */ -int pm_generic_restore(struct device *dev) -{ - return __pm_generic_resume(dev, PM_EVENT_RESTORE); -} -EXPORT_SYMBOL_GPL(pm_generic_restore); -#endif /* CONFIG_PM_SLEEP */ - -struct dev_pm_ops generic_subsys_pm_ops = { -#ifdef CONFIG_PM_SLEEP - .suspend = pm_generic_suspend, - .resume = pm_generic_resume, - .freeze = pm_generic_freeze, - .thaw = pm_generic_thaw, - .poweroff = pm_generic_poweroff, - .restore = pm_generic_restore, -#endif -#ifdef CONFIG_PM_RUNTIME - .runtime_suspend = pm_generic_runtime_suspend, - .runtime_resume = pm_generic_runtime_resume, - .runtime_idle = pm_generic_runtime_idle, -#endif -}; -EXPORT_SYMBOL_GPL(generic_subsys_pm_ops); diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 305c59003963..3d2ab03f1296 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -9,6 +9,7 @@ menuconfig DRM depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU select I2C select I2C_ALGOBIT + select LIST_SORT help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/trunk/drivers/usb/core/devices.c b/trunk/drivers/usb/core/devices.c index d41811bfef2a..c83c975152a6 100644 --- a/trunk/drivers/usb/core/devices.c +++ b/trunk/drivers/usb/core/devices.c @@ -117,20 +117,13 @@ static const char *format_endpt = * However, these will come from functions that return ptrs to each of them. */ -/* - * Wait for an connect/disconnect event to happen. We initialize - * the event counter with an odd number, and each event will increment - * the event counter by two, so it will always _stay_ odd. That means - * that it will never be zero, so "event 0" will never match a current - * event, and thus 'poll' will always trigger as readable for the first - * time it gets called. - */ -static struct device_connect_event { - atomic_t count; - wait_queue_head_t wait; -} device_event = { - .count = ATOMIC_INIT(1), - .wait = __WAIT_QUEUE_HEAD_INITIALIZER(device_event.wait) +static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); +/* guarded by usbfs_mutex */ +static unsigned int conndiscevcnt; + +/* this struct stores the poll state for /devices pollers */ +struct usb_device_status { + unsigned int lastev; }; struct class_info { @@ -164,8 +157,10 @@ static const struct class_info clas_info[] = void usbfs_conn_disc_event(void) { - atomic_add(2, &device_event.count); - wake_up(&device_event.wait); + mutex_lock(&usbfs_mutex); + conndiscevcnt++; + mutex_unlock(&usbfs_mutex); + wake_up(&deviceconndiscwq); } static const char *class_decode(const int class) @@ -637,16 +632,42 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, static unsigned int usb_device_poll(struct file *file, struct poll_table_struct *wait) { - unsigned int event_count; - - poll_wait(file, &device_event.wait, wait); + struct usb_device_status *st; + unsigned int mask = 0; + + mutex_lock(&usbfs_mutex); + st = file->private_data; + if (!st) { + st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); + if (!st) { + mutex_unlock(&usbfs_mutex); + return POLLIN; + } - event_count = atomic_read(&device_event.count); - if (file->f_version != event_count) { - file->f_version = event_count; - return POLLIN | POLLRDNORM; + st->lastev = conndiscevcnt; + file->private_data = st; + mask = POLLIN; } + if (file->f_mode & FMODE_READ) + poll_wait(file, &deviceconndiscwq, wait); + if (st->lastev != conndiscevcnt) + mask |= POLLIN; + st->lastev = conndiscevcnt; + mutex_unlock(&usbfs_mutex); + return mask; +} + +static int usb_device_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static int usb_device_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + file->private_data = NULL; return 0; } @@ -678,4 +699,6 @@ const struct file_operations usbfs_devices_fops = { .llseek = usb_device_lseek, .read = usb_device_read, .poll = usb_device_poll, + .open = usb_device_open, + .release = usb_device_release, }; diff --git a/trunk/drivers/virtio/virtio_pci.c b/trunk/drivers/virtio/virtio_pci.c index 625447f645d9..1b6573216998 100644 --- a/trunk/drivers/virtio/virtio_pci.c +++ b/trunk/drivers/virtio/virtio_pci.c @@ -649,7 +649,6 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, goto out_req_regions; pci_set_drvdata(pci_dev, vp_dev); - pci_set_master(pci_dev); /* we use the subsystem vendor/device id as the virtio vendor/device * id. this allows us to use the same PCI vendor/device id for all diff --git a/trunk/fs/ubifs/Kconfig b/trunk/fs/ubifs/Kconfig index 830e3f76f442..430c69f39842 100644 --- a/trunk/fs/ubifs/Kconfig +++ b/trunk/fs/ubifs/Kconfig @@ -7,6 +7,7 @@ config UBIFS_FS select CRYPTO if UBIFS_FS_ZLIB select CRYPTO_LZO if UBIFS_FS_LZO select CRYPTO_DEFLATE if UBIFS_FS_ZLIB + select LIST_SORT depends on MTD_UBI help UBIFS is a file system for flash devices which works on top of UBI. diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index 8e258c727971..e80df06ad22a 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -215,59 +215,20 @@ struct dev_pm_ops { int (*runtime_idle)(struct device *dev); }; -#ifdef CONFIG_PM_SLEEP -#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ - .suspend = suspend_fn, \ - .resume = resume_fn, \ - .freeze = suspend_fn, \ - .thaw = resume_fn, \ - .poweroff = suspend_fn, \ - .restore = resume_fn, -#else -#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) -#endif - -#ifdef CONFIG_PM_RUNTIME -#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ - .runtime_suspend = suspend_fn, \ - .runtime_resume = resume_fn, \ - .runtime_idle = idle_fn, -#else -#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) -#endif - /* * Use this if you want to use the same suspend and resume callbacks for suspend * to RAM and hibernation. */ #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ const struct dev_pm_ops name = { \ - SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -} - -/* - * Use this for defining a set of PM operations to be used in all situations - * (sustem suspend, hibernation or runtime PM). - */ -#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ -const struct dev_pm_ops name = { \ - SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ - SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ + .suspend = suspend_fn, \ + .resume = resume_fn, \ + .freeze = suspend_fn, \ + .thaw = resume_fn, \ + .poweroff = suspend_fn, \ + .restore = resume_fn, \ } -/* - * Use this for subsystems (bus types, device types, device classes) that don't - * need any special suspend/resume handling in addition to invoking the PM - * callbacks provided by device drivers supporting both the system sleep PM and - * runtime PM, make the pm member point to generic_subsys_pm_ops. - */ -#ifdef CONFIG_PM_OPS -extern struct dev_pm_ops generic_subsys_pm_ops; -#define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops) -#else -#define GENERIC_SUBSYS_PM_OPS NULL -#endif - /** * PM_EVENT_ messages * diff --git a/trunk/include/linux/pm_runtime.h b/trunk/include/linux/pm_runtime.h index b776db737244..7d773aac5314 100644 --- a/trunk/include/linux/pm_runtime.h +++ b/trunk/include/linux/pm_runtime.h @@ -62,11 +62,6 @@ static inline void device_set_run_wake(struct device *dev, bool enable) dev->power.run_wake = enable; } -static inline bool pm_runtime_suspended(struct device *dev) -{ - return dev->power.runtime_status == RPM_SUSPENDED; -} - #else /* !CONFIG_PM_RUNTIME */ static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } @@ -94,7 +89,6 @@ static inline void pm_runtime_get_noresume(struct device *dev) {} static inline void pm_runtime_put_noidle(struct device *dev) {} static inline bool device_run_wake(struct device *dev) { return false; } static inline void device_set_run_wake(struct device *dev, bool enable) {} -static inline bool pm_runtime_suspended(struct device *dev) { return false; } #endif /* !CONFIG_PM_RUNTIME */ diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index 170d8ca901d8..496d16e1fa2c 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -160,6 +160,9 @@ config TEXTSEARCH_BM config TEXTSEARCH_FSM tristate +config LIST_SORT + boolean + config BTREE boolean diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 2e152aed7198..59e46a014bc6 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - string_helpers.o gcd.o list_sort.o + string_helpers.o gcd.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG @@ -40,6 +40,7 @@ lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o +obj-$(CONFIG_LIST_SORT) += list_sort.o obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o obj-$(CONFIG_BTREE) += btree.o obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o diff --git a/trunk/lib/vsprintf.c b/trunk/lib/vsprintf.c index 0d461c7c14db..af4aaa6c36f3 100644 --- a/trunk/lib/vsprintf.c +++ b/trunk/lib/vsprintf.c @@ -381,8 +381,8 @@ static noinline char *put_dec(char *buf, unsigned long long num) #define PLUS 4 /* show plus */ #define SPACE 8 /* space if plus */ #define LEFT 16 /* left justified */ -#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ -#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ +#define SMALL 32 /* Must be 32 == 0x20 */ +#define SPECIAL 64 /* 0x */ enum format_type { FORMAT_TYPE_NONE, /* Just a string part */ @@ -408,12 +408,12 @@ enum format_type { }; struct printf_spec { - u16 type; - s16 field_width; /* width of output field */ - u8 flags; /* flags to number() */ - u8 base; - s8 precision; /* # of digits/chars */ - u8 qualifier; + enum format_type type; + int flags; /* flags to number() */ + int field_width; /* width of output field */ + int base; + int precision; /* # of digits/chars */ + int qualifier; }; static char *number(char *buf, char *end, unsigned long long num, @@ -597,29 +597,22 @@ static char *resource_string(char *buf, char *end, struct resource *res, #ifndef MEM_RSRC_PRINTK_SIZE #define MEM_RSRC_PRINTK_SIZE 10 #endif - static const struct printf_spec io_spec = { + struct printf_spec hex_spec = { .base = 16, - .field_width = IO_RSRC_PRINTK_SIZE, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; - static const struct printf_spec mem_spec = { - .base = 16, - .field_width = MEM_RSRC_PRINTK_SIZE, - .precision = -1, - .flags = SPECIAL | SMALL | ZEROPAD, - }; - static const struct printf_spec dec_spec = { + struct printf_spec dec_spec = { .base = 10, .precision = -1, .flags = 0, }; - static const struct printf_spec str_spec = { + struct printf_spec str_spec = { .field_width = -1, .precision = 10, .flags = LEFT, }; - static const struct printf_spec flag_spec = { + struct printf_spec flag_spec = { .base = 16, .precision = -1, .flags = SPECIAL | SMALL, @@ -635,31 +628,35 @@ static char *resource_string(char *buf, char *end, struct resource *res, 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; char *p = sym, *pend = sym + sizeof(sym); + int size = -1, addr = 0; int decode = (fmt[0] == 'R') ? 1 : 0; - const struct printf_spec *specp; - *p++ = '['; if (res->flags & IORESOURCE_IO) { - p = string(p, pend, "io ", str_spec); - specp = &io_spec; + size = IO_RSRC_PRINTK_SIZE; + addr = 1; } else if (res->flags & IORESOURCE_MEM) { + size = MEM_RSRC_PRINTK_SIZE; + addr = 1; + } + + *p++ = '['; + if (res->flags & IORESOURCE_IO) + p = string(p, pend, "io ", str_spec); + else if (res->flags & IORESOURCE_MEM) p = string(p, pend, "mem ", str_spec); - specp = &mem_spec; - } else if (res->flags & IORESOURCE_IRQ) { + else if (res->flags & IORESOURCE_IRQ) p = string(p, pend, "irq ", str_spec); - specp = &dec_spec; - } else if (res->flags & IORESOURCE_DMA) { + else if (res->flags & IORESOURCE_DMA) p = string(p, pend, "dma ", str_spec); - specp = &dec_spec; - } else { + else { p = string(p, pend, "??? ", str_spec); - specp = &mem_spec; decode = 0; } - p = number(p, pend, res->start, *specp); + hex_spec.field_width = size; + p = number(p, pend, res->start, addr ? hex_spec : dec_spec); if (res->start != res->end) { *p++ = '-'; - p = number(p, pend, res->end, *specp); + p = number(p, pend, res->end, addr ? hex_spec : dec_spec); } if (decode) { if (res->flags & IORESOURCE_MEM_64) @@ -1336,7 +1333,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) break; case FORMAT_TYPE_NRCHARS: { - u8 qualifier = spec.qualifier; + int qualifier = spec.qualifier; if (qualifier == 'l') { long *ip = va_arg(args, long *); @@ -1622,7 +1619,7 @@ do { \ case FORMAT_TYPE_NRCHARS: { /* skip %n 's argument */ - u8 qualifier = spec.qualifier; + int qualifier = spec.qualifier; void *skip_arg; if (qualifier == 'l') skip_arg = va_arg(args, long *); @@ -1888,9 +1885,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) char *next; char digit; int num = 0; - u8 qualifier; - u8 base; - s16 field_width; + int qualifier, base, field_width; bool is_sign; while (*fmt && *str) { @@ -1968,7 +1963,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) { char *s = (char *)va_arg(args, char *); if (field_width == -1) - field_width = SHORT_MAX; + field_width = INT_MAX; /* first, skip leading white space in buffer */ str = skip_spaces(str);