ACPI and power management updates for 3.12-rc1

1) ACPI-based PCI hotplug (ACPIPHP) subsystem rework and introduction
     of Intel Thunderbolt support on systems that use ACPI for signalling
     Thunderbolt hotplug events.  This also should make ACPIPHP work in
     some cases in which it was known to have problems.  From
     Rafael J Wysocki, Mika Westerberg and Kirill A Shutemov.
 
  2) ACPI core code cleanups and dock station support cleanups from
     Jiang Liu and Rafael J Wysocki.
 
  3) Fixes for locking problems related to ACPI device hotplug from
     Rafael J Wysocki.
 
  4) ACPICA update to version 20130725 includig fixes, cleanups, support
     for more than 256 GPEs per GPE block and a change to make the ACPI
     PM Timer optional (we've seen systems without the PM Timer in the
     field already).  One of the fixes, related to the DeRefOf operator,
     is necessary to prevent some Windows 8 oriented AML from causing
     problems to happen.  From Bob Moore, Lv Zheng, and Jung-uk Kim.
 
  5) Removal of the old and long deprecated /proc/acpi/event interface
     and related driver changes from Thomas Renninger.
 
  6) ACPI and Xen changes to make the reduced hardware sleep work with
     the latter from Ben Guthro.
 
  7) ACPI video driver cleanups and a blacklist of systems that should
     not tell the BIOS that they are compatible with Windows 8 (or ACPI
     backlight and possibly other things will not work on them).  From
     Felipe Contreras.
 
  8) Assorted ACPI fixes and cleanups from Aaron Lu, Hanjun Guo,
     Kuppuswamy Sathyanarayanan, Lan Tianyu, Sachin Kamat, Tang Chen,
     Toshi Kani, and Wei Yongjun.
 
  9) cpufreq ondemand governor target frequency selection change to
     reduce oscillations between min and max frequencies (essentially,
     it causes the governor to choose target frequencies proportional
     to load) from Stratos Karafotis.
 
 10) cpufreq fixes allowing sysfs attributes file permissions to be
     preserved over suspend/resume cycles Srivatsa S Bhat.
 
 11) Removal of Device Tree parsing for CPU device nodes from multiple
     cpufreq drivers that required some changes related to
     of_get_cpu_node() to be made in a few architectures and in the
     driver core.  From Sudeep KarkadaNagesha.
 
 12) cpufreq core fixes and cleanups related to mutual exclusion and
     driver module references from Viresh Kumar, Lukasz Majewski and
     Rafael J Wysocki.
 
 13) Assorted cpufreq fixes and cleanups from Amit Daniel Kachhap,
     Bartlomiej Zolnierkiewicz, Hanjun Guo, Jingoo Han, Joseph Lo,
     Julia Lawall, Li Zhong, Mark Brown, Sascha Hauer, Stephen Boyd,
     Stratos Karafotis, and Viresh Kumar.
 
 14) Fixes to prevent race conditions in coupled cpuidle from happening
     from Colin Cross.
 
 15) cpuidle core fixes and cleanups from Daniel Lezcano and
     Tuukka Tikkanen.
 
 16) Assorted cpuidle fixes and cleanups from Daniel Lezcano,
     Geert Uytterhoeven, Jingoo Han, Julia Lawall, Linus Walleij,
     and Sahara.
 
 17) System sleep tracing changes from Todd E Brandt and Shuah Khan.
 
 18) PNP subsystem conversion to using struct dev_pm_ops for power
     management from Shuah Khan.
 
 /
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iQIcBAABCAAGBQJSJcKhAAoJEKhOf7ml8uNsplIQAJSOshxhkkemvFOuHZ+0YIbh
 R9aufjXeDkMDBi8YtU+tB7ERth1j+0LUSM0NTnP51U7e+7eSGobA9s5jSZQj2l7r
 HFtnSOegLuKAfqwgfSLK91xa1rTFdfW0Kych9G2nuHtBIt6P0Oc59Cb5M0oy6QXs
 nVtaDEuU//tmO71+EF5HnMJHabRTrpvtn/7NbDUpU7LZYpWJrHJFT9xt1rXNab7H
 YRCATPm3kXGRg58Doc3EZE4G3D7DLvq74jWMaI089X/m5Pg1G6upqArypOy6oxdP
 p2FEzYVrb2bi8fakXp7BBeO1gCJTAqIgAkbSSZHLpGhFaeEMmb9/DWPXdm2TjzMV
 c1EEucvsqZWoprXgy12i5Hk814xN8d8nBBLg/UYiRJ44nc/hevXfyE9ZYj6bkseJ
 +GNHmZIa1QYC05nnGli4+W4kHns8EZf/gmvIxnPuco1RN2yMWagrud5/G6Dr9M2B
 hzJV6qauLVzgZso4oe79zv9aVxe/dPHKANLD/sg23WBiJJbJF1ocBlnj2Xlbpqze
 pmMUWGiO/gUiS0fmpW/lAJauza5jFmSCjE4E8R0Gyn0j4YXjmMhdEanaU6J3VuCi
 yVgEzYEth4sowq4AflMMLKYN+WmozDnK7taZRGmT0t+EKRFKLT6EgnNrkQgs1vKl
 oawD9LM4fZ8E0yroOEme
 =CgqW
 -----END PGP SIGNATURE-----

Merge tag 'pm+acpi-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management updates from Rafael Wysocki:

 1) ACPI-based PCI hotplug (ACPIPHP) subsystem rework and introduction
    of Intel Thunderbolt support on systems that use ACPI for signalling
    Thunderbolt hotplug events.  This also should make ACPIPHP work in
    some cases in which it was known to have problems.  From
    Rafael J Wysocki, Mika Westerberg and Kirill A Shutemov.

 2) ACPI core code cleanups and dock station support cleanups from
    Jiang Liu and Rafael J Wysocki.

 3) Fixes for locking problems related to ACPI device hotplug from
    Rafael J Wysocki.

 4) ACPICA update to version 20130725 includig fixes, cleanups, support
    for more than 256 GPEs per GPE block and a change to make the ACPI
    PM Timer optional (we've seen systems without the PM Timer in the
    field already).  One of the fixes, related to the DeRefOf operator,
    is necessary to prevent some Windows 8 oriented AML from causing
    problems to happen.  From Bob Moore, Lv Zheng, and Jung-uk Kim.

 5) Removal of the old and long deprecated /proc/acpi/event interface
    and related driver changes from Thomas Renninger.

 6) ACPI and Xen changes to make the reduced hardware sleep work with
    the latter from Ben Guthro.

 7) ACPI video driver cleanups and a blacklist of systems that should
    not tell the BIOS that they are compatible with Windows 8 (or ACPI
    backlight and possibly other things will not work on them).  From
    Felipe Contreras.

 8) Assorted ACPI fixes and cleanups from Aaron Lu, Hanjun Guo,
    Kuppuswamy Sathyanarayanan, Lan Tianyu, Sachin Kamat, Tang Chen,
    Toshi Kani, and Wei Yongjun.

 9) cpufreq ondemand governor target frequency selection change to
    reduce oscillations between min and max frequencies (essentially,
    it causes the governor to choose target frequencies proportional
    to load) from Stratos Karafotis.

10) cpufreq fixes allowing sysfs attributes file permissions to be
    preserved over suspend/resume cycles Srivatsa S Bhat.

11) Removal of Device Tree parsing for CPU device nodes from multiple
    cpufreq drivers that required some changes related to
    of_get_cpu_node() to be made in a few architectures and in the
    driver core.  From Sudeep KarkadaNagesha.

12) cpufreq core fixes and cleanups related to mutual exclusion and
    driver module references from Viresh Kumar, Lukasz Majewski and
    Rafael J Wysocki.

13) Assorted cpufreq fixes and cleanups from Amit Daniel Kachhap,
    Bartlomiej Zolnierkiewicz, Hanjun Guo, Jingoo Han, Joseph Lo,
    Julia Lawall, Li Zhong, Mark Brown, Sascha Hauer, Stephen Boyd,
    Stratos Karafotis, and Viresh Kumar.

14) Fixes to prevent race conditions in coupled cpuidle from happening
    from Colin Cross.

15) cpuidle core fixes and cleanups from Daniel Lezcano and
    Tuukka Tikkanen.

16) Assorted cpuidle fixes and cleanups from Daniel Lezcano,
    Geert Uytterhoeven, Jingoo Han, Julia Lawall, Linus Walleij,
    and Sahara.

17) System sleep tracing changes from Todd E Brandt and Shuah Khan.

18) PNP subsystem conversion to using struct dev_pm_ops for power
    management from Shuah Khan.

* tag 'pm+acpi-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (217 commits)
  cpufreq: Don't use smp_processor_id() in preemptible context
  cpuidle: coupled: fix race condition between pokes and safe state
  cpuidle: coupled: abort idle if pokes are pending
  cpuidle: coupled: disable interrupts after entering safe state
  ACPI / hotplug: Remove containers synchronously
  driver core / ACPI: Avoid device hot remove locking issues
  cpufreq: governor: Fix typos in comments
  cpufreq: governors: Remove duplicate check of target freq in supported range
  cpufreq: Fix timer/workqueue corruption due to double queueing
  ACPI / EC: Add ASUSTEK L4R to quirk list in order to validate ECDT
  ACPI / thermal: Add check of "_TZD" availability and evaluating result
  cpufreq: imx6q: Fix clock enable balance
  ACPI: blacklist win8 OSI for buggy laptops
  cpufreq: tegra: fix the wrong clock name
  cpuidle: Change struct menu_device field types
  cpuidle: Add a comment warning about possible overflow
  cpuidle: Fix variable domains in get_typical_interval()
  cpuidle: Fix menu_device->intervals type
  cpuidle: CodingStyle: Break up multiple assignments on single line
  cpuidle: Check called function parameter in get_typical_interval()
  ...
This commit is contained in:
Linus Torvalds 2013-09-03 15:59:39 -07:00
commit 40031da445
188 changed files with 3039 additions and 3548 deletions

View File

@ -50,8 +50,6 @@ What shall this struct cpufreq_driver contain?
cpufreq_driver.name - The name of this driver.
cpufreq_driver.owner - THIS_MODULE;
cpufreq_driver.init - A pointer to the per-CPU initialization
function.

View File

@ -235,10 +235,61 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Format: To spoof as Windows 98: ="Microsoft Windows"
acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
acpi_osi="string1" # add string1 -- only one string
acpi_osi="!string2" # remove built-in string2
acpi_osi="string1" # add string1
acpi_osi="!string2" # remove string2
acpi_osi=!* # remove all strings
acpi_osi=! # disable all built-in OS vendor
strings
acpi_osi= # disable all strings
'acpi_osi=!' can be used in combination with single or
multiple 'acpi_osi="string1"' to support specific OS
vendor string(s). Note that such command can only
affect the default state of the OS vendor strings, thus
it cannot affect the default state of the feature group
strings and the current state of the OS vendor strings,
specifying it multiple times through kernel command line
is meaningless. This command is useful when one do not
care about the state of the feature group strings which
should be controlled by the OSPM.
Examples:
1. 'acpi_osi=! acpi_osi="Windows 2000"' is equivalent
to 'acpi_osi="Windows 2000" acpi_osi=!', they all
can make '_OSI("Windows 2000")' TRUE.
'acpi_osi=' cannot be used in combination with other
'acpi_osi=' command lines, the _OSI method will not
exist in the ACPI namespace. NOTE that such command can
only affect the _OSI support state, thus specifying it
multiple times through kernel command line is also
meaningless.
Examples:
1. 'acpi_osi=' can make 'CondRefOf(_OSI, Local1)'
FALSE.
'acpi_osi=!*' can be used in combination with single or
multiple 'acpi_osi="string1"' to support specific
string(s). Note that such command can affect the
current state of both the OS vendor strings and the
feature group strings, thus specifying it multiple times
through kernel command line is meaningful. But it may
still not able to affect the final state of a string if
there are quirks related to this string. This command
is useful when one want to control the state of the
feature group strings to debug BIOS issues related to
the OSPM features.
Examples:
1. 'acpi_osi="Module Device" acpi_osi=!*' can make
'_OSI("Module Device")' FALSE.
2. 'acpi_osi=!* acpi_osi="Module Device"' can make
'_OSI("Module Device")' TRUE.
3. 'acpi_osi=! acpi_osi=!* acpi_osi="Windows 2000"' is
equivalent to
'acpi_osi=!* acpi_osi=! acpi_osi="Windows 2000"'
and
'acpi_osi=!* acpi_osi="Windows 2000" acpi_osi=!',
they all will make '_OSI("Windows 2000")' TRUE.
acpi_pm_good [X86]
Override the pmtimer bug detection: force the kernel
to assume that this machine's pmtimer latches its value

View File

@ -8,8 +8,8 @@ http://acpi4asus.sf.net/
This driver provides support for extra features of ACPI-compatible ASUS laptops.
It may also support some MEDION, JVC or VICTOR laptops (such as MEDION 9675 or
VICTOR XP7210 for example). It makes all the extra buttons generate standard
ACPI events that go through /proc/acpi/events and input events (like keyboards).
VICTOR XP7210 for example). It makes all the extra buttons generate input
events (like keyboards).
On some models adds support for changing the display brightness and output,
switching the LCD backlight on and off, and most importantly, allows you to
blink those fancy LEDs intended for reporting mail and wireless status.
@ -55,8 +55,8 @@ Usage
DSDT) to me.
That's all, now, all the events generated by the hotkeys of your laptop
should be reported in your /proc/acpi/event entry. You can check with
"acpi_listen".
should be reported via netlink events. You can check with
"acpi_genl monitor" (part of the acpica project).
Hotkeys are also reported as input keys (like keyboards) you can check
which key are supported using "xev" under X11.

View File

@ -12,10 +12,10 @@ Fn keys (hotkeys):
------------------
Some models report hotkeys through the SNC or SPIC devices, such events are
reported both through the ACPI subsystem as acpi events and through the INPUT
subsystem. See the logs of acpid or /proc/acpi/event and
/proc/bus/input/devices to find out what those events are and which input
devices are created by the driver. Additionally, loading the driver with the
debug option will report all events in the kernel log.
subsystem. See the logs of /proc/bus/input/devices to find out what those
events are and which input devices are created by the driver.
Additionally, loading the driver with the debug option will report all events
in the kernel log.
The "scancodes" passed to the input system (that can be remapped with udev)
are indexes to the table "sony_laptop_input_keycode_map" in the sony-laptop.c

View File

@ -329,20 +329,6 @@ sysfs notes:
This attribute has poll()/select() support.
hotkey_report_mode:
Returns the state of the procfs ACPI event report mode
filter for hot keys. If it is set to 1 (the default),
all hot key presses are reported both through the input
layer and also as ACPI events through procfs (but not
through netlink). If it is set to 2, hot key presses
are reported only through the input layer.
This attribute is read-only in kernels 2.6.23 or later,
and read-write on earlier kernels.
May return -EPERM (write access locked out by module
parameter) or -EACCES (read-only).
wakeup_reason:
Set to 1 if the system is waking up because the user
requested a bay ejection. Set to 2 if the system is
@ -518,24 +504,21 @@ SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A
Non hotkey ACPI HKEY event map:
-------------------------------
Events that are not propagated by the driver, except for legacy
compatibility purposes when hotkey_report_mode is set to 1:
0x5001 Lid closed
0x5002 Lid opened
0x5009 Tablet swivel: switched to tablet mode
0x500A Tablet swivel: switched to normal mode
0x7000 Radio Switch may have changed state
Events that are never propagated by the driver:
0x2304 System is waking up from suspend to undock
0x2305 System is waking up from suspend to eject bay
0x2404 System is waking up from hibernation to undock
0x2405 System is waking up from hibernation to eject bay
0x5001 Lid closed
0x5002 Lid opened
0x5009 Tablet swivel: switched to tablet mode
0x500A Tablet swivel: switched to normal mode
0x5010 Brightness level changed/control event
0x6000 KEYBOARD: Numlock key pressed
0x6005 KEYBOARD: Fn key pressed (TO BE VERIFIED)
0x7000 Radio Switch may have changed state
Events that are propagated by the driver to userspace:
@ -574,50 +557,6 @@ operating system is to force either an immediate suspend or hibernate
cycle, or a system shutdown. Obviously, something is very wrong if this
happens.
Compatibility notes:
ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never
supported the input layer, and sent events over the procfs ACPI event
interface.
To avoid sending duplicate events over the input layer and the ACPI
event interface, thinkpad-acpi 0.16 implements a module parameter
(hotkey_report_mode), and also a sysfs device attribute with the same
name.
Make no mistake here: userspace is expected to switch to using the input
layer interface of thinkpad-acpi, together with the ACPI netlink event
interface in kernels 2.6.23 and later, or with the ACPI procfs event
interface in kernels 2.6.22 and earlier.
If no hotkey_report_mode module parameter is specified (or it is set to
zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22
and earlier, also allows one to change the hotkey_report_mode through
sysfs. In kernels 2.6.23 and later, where the netlink ACPI event
interface is available, hotkey_report_mode cannot be changed through
sysfs (it is read-only).
If the hotkey_report_mode module parameter is set to 1 or 2, it cannot
be changed later through sysfs (any writes will return -EPERM to signal
that hotkey_report_mode was locked. On 2.6.23 and later, where
hotkey_report_mode cannot be changed at all, writes will return -EACCES).
hotkey_report_mode set to 1 makes the driver export through the procfs
ACPI event interface all hot key presses (which are *also* sent to the
input layer). This is a legacy compatibility behaviour, and it is also
the default mode of operation for the driver.
hotkey_report_mode set to 2 makes the driver filter out the hot key
presses from the procfs ACPI event interface, so these events will only
be sent through the input layer. Userspace that has been updated to use
the thinkpad-acpi input layer interface should set hotkey_report_mode to
2.
Hot key press events are never sent to the ACPI netlink event interface.
Really up-to-date userspace under kernel 2.6.23 and later is to use the
netlink interface and the input layer interface, and don't bother at all
with hotkey_report_mode.
Brightness hotkey notes:

View File

@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
}
}
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
{
return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
}
/**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt_phys: physical address of dt blob

View File

@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
{NULL, },
};
struct cpu_capacity {
unsigned long hwid;
unsigned long capacity;
};
struct cpu_capacity *cpu_capacity;
unsigned long *__cpu_capacity;
#define cpu_capacity(cpu) __cpu_capacity[cpu]
unsigned long middle_capacity = 1;
@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
unsigned long capacity = 0;
int alloc_size, cpu = 0;
alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
__cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
while ((cn = of_find_node_by_type(cn, "cpu"))) {
const u32 *rate, *reg;
for_each_possible_cpu(cpu) {
const u32 *rate;
int len;
if (cpu >= num_possible_cpus())
break;
/* too early to use cpu->of_node */
cn = of_get_cpu_node(cpu, NULL);
if (!cn) {
pr_err("missing device node for CPU %d\n", cpu);
continue;
}
for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
if (of_device_is_compatible(cn, cpu_eff->compatible))
@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
continue;
}
reg = of_get_property(cn, "reg", &len);
if (!reg || len != 4) {
pr_err("%s missing reg property\n", cn->full_name);
continue;
}
capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
/* Save min capacity of the system */
@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
if (capacity > max_capacity)
max_capacity = capacity;
cpu_capacity[cpu].capacity = capacity;
cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
cpu_capacity(cpu) = capacity;
}
if (cpu < num_possible_cpus())
cpu_capacity[cpu].hwid = (unsigned long)(-1);
/* If min and max capacities are equals, we bypass the update of the
* cpu_scale because all CPUs have the same capacity. Otherwise, we
* compute a middle_capacity factor that will ensure that the capacity
@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
* SCHED_POWER_SCALE, which is the default value, but with the
* constraint explained near table_efficiency[].
*/
if (min_capacity == max_capacity)
cpu_capacity[0].hwid = (unsigned long)(-1);
else if (4*max_capacity < (3*(max_capacity + min_capacity)))
if (4*max_capacity < (3*(max_capacity + min_capacity)))
middle_capacity = (min_capacity + max_capacity)
>> (SCHED_POWER_SHIFT+1);
else
@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
* boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
* function returns directly for SMP system.
*/
void update_cpu_power(unsigned int cpu, unsigned long hwid)
void update_cpu_power(unsigned int cpu)
{
unsigned int idx = 0;
/* look for the cpu's hwid in the cpu capacity table */
for (idx = 0; idx < num_possible_cpus(); idx++) {
if (cpu_capacity[idx].hwid == hwid)
break;
if (cpu_capacity[idx].hwid == -1)
return;
}
if (idx == num_possible_cpus())
if (!cpu_capacity(cpu))
return;
set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
cpu, arch_scale_freq_power(NULL, cpu));
@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)
#else
static inline void parse_dt_topology(void) {}
static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
static inline void update_cpu_power(unsigned int cpuid) {}
#endif
/*
@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)
update_siblings_masks(cpuid);
update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
update_cpu_power(cpuid);
printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
cpuid, cpu_topology[cpuid].thread_id,

View File

@ -65,7 +65,7 @@ static struct cpuidle_driver davinci_idle_driver = {
.states[1] = {
.enter = davinci_enter_idle,
.exit_latency = 10,
.target_residency = 100000,
.target_residency = 10000,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "DDR SR",
.desc = "WFI and DDR Self Refresh",

View File

@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev)
{
struct device_node *np;
np = of_find_node_by_path("/cpus/cpu@0");
np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_warn("failed to find cpu0 node\n");
return;
}
cpu_dev->of_node = np;
if (of_init_opp_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;

View File

@ -29,45 +29,40 @@
#include "pmsu.h"
#include "coherency.h"
static struct clk *__init get_cpu_clk(int cpu)
{
struct clk *cpu_clk;
struct device_node *np = of_get_cpu_node(cpu, NULL);
if (WARN(!np, "missing cpu node\n"))
return NULL;
cpu_clk = of_clk_get(np, 0);
if (WARN_ON(IS_ERR(cpu_clk)))
return NULL;
return cpu_clk;
}
void __init set_secondary_cpus_clock(void)
{
int thiscpu;
int thiscpu, cpu;
unsigned long rate;
struct clk *cpu_clk = NULL;
struct device_node *np = NULL;
struct clk *cpu_clk;
thiscpu = smp_processor_id();
for_each_node_by_type(np, "cpu") {
int err;
int cpu;
err = of_property_read_u32(np, "reg", &cpu);
if (WARN_ON(err))
return;
if (cpu == thiscpu) {
cpu_clk = of_clk_get(np, 0);
break;
}
}
if (WARN_ON(IS_ERR(cpu_clk)))
cpu_clk = get_cpu_clk(thiscpu);
if (!cpu_clk)
return;
clk_prepare_enable(cpu_clk);
rate = clk_get_rate(cpu_clk);
/* set all the other CPU clk to the same rate than the boot CPU */
for_each_node_by_type(np, "cpu") {
int err;
int cpu;
err = of_property_read_u32(np, "reg", &cpu);
if (WARN_ON(err))
for_each_possible_cpu(cpu) {
if (cpu == thiscpu)
continue;
cpu_clk = get_cpu_clk(cpu);
if (!cpu_clk)
return;
if (cpu != thiscpu) {
cpu_clk = of_clk_get(np, 0);
clk_set_rate(cpu_clk, rate);
}
clk_set_rate(cpu_clk, rate);
}
}

View File

@ -4,7 +4,6 @@
obj-y := cpu.o devices.o devices-common.o \
id.o usb.o timer.o pm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \

View File

@ -50,9 +50,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
extern void kdump_move_device_tree(void);
/* CPU OF node matching */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */

View File

@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
extern void kdump_move_device_tree(void);
/* CPU OF node matching */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
/* Get the MAC address */
extern const void *of_get_mac_address(struct device_node *np);

View File

@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
extern void kdump_move_device_tree(void);
/* CPU OF node matching */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
/* cache lookup */
struct device_node *of_find_next_cache_node(struct device_node *np);

View File

@ -865,49 +865,10 @@ static int __init prom_reconfig_setup(void)
__initcall(prom_reconfig_setup);
#endif
/* Find the device node for a given logical cpu number, also returns the cpu
* local thread number (index in ibm,interrupt-server#s) if relevant and
* asked for (non NULL)
*/
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
{
int hardid;
struct device_node *np;
hardid = get_hard_smp_processor_id(cpu);
for_each_node_by_type(np, "cpu") {
const u32 *intserv;
unsigned int plen, t;
/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
* fallback to "reg" property and assume no threads
*/
intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
&plen);
if (intserv == NULL) {
const u32 *reg = of_get_property(np, "reg", NULL);
if (reg == NULL)
continue;
if (*reg == hardid) {
if (thread)
*thread = 0;
return np;
}
} else {
plen /= sizeof(u32);
for (t = 0; t < plen; t++) {
if (hardid == intserv[t]) {
if (thread)
*thread = t;
return np;
}
}
}
}
return NULL;
return (int)phys_id == get_hard_smp_processor_id(cpu);
}
EXPORT_SYMBOL(of_get_cpu_node);
#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
static struct debugfs_blob_wrapper flat_dt_blob;

View File

@ -91,13 +91,11 @@ static struct cpuidle_driver cpuidle_driver = {
int __init sh_mobile_setup_cpuidle(void)
{
int ret;
if (sh_mobile_sleep_supported & SUSP_SH_SF)
cpuidle_driver.states[1].disabled = false;
if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
cpuidle_driver.states[2].disabled = false;
return cpuidle_register(&cpuidle_driver);
return cpuidle_register(&cpuidle_driver, NULL);
}

View File

@ -942,35 +942,6 @@ extern int set_tsc_mode(unsigned int val);
extern u16 amd_get_nb_id(int cpu);
struct aperfmperf {
u64 aperf, mperf;
};
static inline void get_aperfmperf(struct aperfmperf *am)
{
WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF));
rdmsrl(MSR_IA32_APERF, am->aperf);
rdmsrl(MSR_IA32_MPERF, am->mperf);
}
#define APERFMPERF_SHIFT 10
static inline
unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
struct aperfmperf *new)
{
u64 aperf = new->aperf - old->aperf;
u64 mperf = new->mperf - old->mperf;
unsigned long ratio = aperf;
mperf >>= APERFMPERF_SHIFT;
if (mperf)
ratio = div64_u64(aperf, mperf);
return ratio;
}
extern unsigned long arch_align_stack(unsigned long sp);
extern void free_init_pages(char *what, unsigned long begin, unsigned long end);

View File

@ -301,6 +301,15 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
return 0;
}
static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b)
{
if (!tboot_enabled())
return 0;
pr_warning("tboot is not able to suspend on platforms with reduced hardware sleep (ACPIv5)");
return -ENODEV;
}
static atomic_t ap_wfs_count;
static int tboot_wait_for_aps(int num_aps)
@ -422,6 +431,7 @@ static __init int tboot_late_init(void)
#endif
acpi_os_set_prepare_sleep(&tboot_sleep);
acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep);
return 0;
}

View File

@ -146,6 +146,7 @@ int __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
u64 start, end;
u32 hotpluggable;
int node, pxm;
if (srat_disabled())
@ -154,7 +155,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
goto out_err_bad_srat;
if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
goto out_err;
if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE;
if (hotpluggable && !save_add_info())
goto out_err;
start = ma->base_address;
@ -174,9 +176,10 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
node_set(node, numa_nodes_parsed);
printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
node, pxm,
(unsigned long long) start, (unsigned long long) end - 1);
pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s\n",
node, pxm,
(unsigned long long) start, (unsigned long long) end - 1,
hotpluggable ? " hotplug" : "");
return 0;
out_err_bad_srat:

View File

@ -210,6 +210,8 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
r = &dev->resource[idx];
if (!r->flags)
continue;
if (r->parent) /* Already allocated */
continue;
if (!r->start || pci_claim_resource(dev, idx) < 0) {
/*
* Something is wrong with the region.
@ -318,6 +320,8 @@ static void pcibios_allocate_dev_rom_resource(struct pci_dev *dev)
r = &dev->resource[PCI_ROM_RESOURCE];
if (!r->flags || !r->start)
return;
if (r->parent) /* Already allocated */
return;
if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) {
r->end -= r->start;

View File

@ -91,24 +91,6 @@ config ACPI_EC_DEBUGFS
Thus this option is a debug option that helps to write ACPI drivers
and can be used to identify ACPI code or EC firmware bugs.
config ACPI_PROC_EVENT
bool "Deprecated /proc/acpi/event support"
depends on PROC_FS
default y
help
A user-space daemon, acpid, typically reads /proc/acpi/event
and handles all ACPI-generated events.
These events are now delivered to user-space either
via the input layer or as netlink events.
This build option enables the old code for legacy
user-space implementation. After some time, this will
be moved under CONFIG_ACPI_PROCFS, and then deleted.
Say Y here to retain the old behaviour. Say N if your
user-space is newer than kernel 2.6.23 (September 2007).
config ACPI_AC
tristate "AC Adapter"
depends on X86

View File

@ -267,7 +267,6 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
msleep(ac_sleep_before_get_state_ms);
acpi_ac_get_state(ac);
acpi_bus_generate_proc_event(device, event, (u32) ac->state);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event,
(u32) ac->state);

View File

@ -452,7 +452,6 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
switch (event) {
case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
acpi_pad_handle_notify(handle);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;

View File

@ -52,7 +52,7 @@ int acpi_create_platform_device(struct acpi_device *adev,
struct platform_device_info pdevinfo;
struct resource_list_entry *rentry;
struct list_head resource_list;
struct resource *resources;
struct resource *resources = NULL;
int count;
/* If the ACPI node already has a physical device attached, skip it. */
@ -61,20 +61,22 @@ int acpi_create_platform_device(struct acpi_device *adev,
INIT_LIST_HEAD(&resource_list);
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
if (count <= 0)
if (count < 0) {
return 0;
} else if (count > 0) {
resources = kmalloc(count * sizeof(struct resource),
GFP_KERNEL);
if (!resources) {
dev_err(&adev->dev, "No memory for resources\n");
acpi_dev_free_resource_list(&resource_list);
return -ENOMEM;
}
count = 0;
list_for_each_entry(rentry, &resource_list, node)
resources[count++] = rentry->res;
resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
if (!resources) {
dev_err(&adev->dev, "No memory for resources\n");
acpi_dev_free_resource_list(&resource_list);
return -ENOMEM;
}
count = 0;
list_for_each_entry(rentry, &resource_list, node)
resources[count++] = rentry->res;
acpi_dev_free_resource_list(&resource_list);
memset(&pdevinfo, 0, sizeof(pdevinfo));
/*

View File

@ -178,14 +178,17 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
return -ENODEV;
cpu_maps_update_begin();
cpu_hotplug_begin();
ret = acpi_map_lsapic(pr->handle, &pr->id);
if (ret)
return ret;
goto out;
ret = arch_register_cpu(pr->id);
if (ret) {
acpi_unmap_lsapic(pr->id);
return ret;
goto out;
}
/*
@ -195,7 +198,11 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
*/
pr_info("CPU%d has been hot-added\n", pr->id);
pr->flags.need_hotplug_init = 1;
return 0;
out:
cpu_hotplug_done();
cpu_maps_update_done();
return ret;
}
#else
static inline int acpi_processor_hotadd_init(struct acpi_processor *pr)
@ -452,11 +459,15 @@ static void acpi_processor_remove(struct acpi_device *device)
per_cpu(processor_device_array, pr->id) = NULL;
per_cpu(processors, pr->id) = NULL;
cpu_maps_update_begin();
cpu_hotplug_begin();
/* Remove the CPU. */
get_online_cpus();
arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id);
put_online_cpus();
cpu_hotplug_done();
cpu_maps_update_done();
try_offline_node(cpu_to_node(pr->id));

View File

@ -138,6 +138,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE);
*/
u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE);
/*
* We keep track of the latest version of Windows that has been requested by
* the BIOS.
*/
u8 ACPI_INIT_GLOBAL(acpi_gbl_osi_data, 0);
/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
struct acpi_table_fadt acpi_gbl_FADT;
@ -285,7 +291,6 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized;
ACPI_EXTERN u8 acpi_gbl_osi_data;
ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces;
ACPI_EXTERN struct acpi_address_range
*acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX];

View File

@ -942,6 +942,9 @@ struct acpi_interface_info {
#define ACPI_OSI_INVALID 0x01
#define ACPI_OSI_DYNAMIC 0x02
#define ACPI_OSI_FEATURE 0x04
#define ACPI_OSI_DEFAULT_INVALID 0x08
#define ACPI_OSI_OPTIONAL_FEATURE (ACPI_OSI_FEATURE | ACPI_OSI_DEFAULT_INVALID | ACPI_OSI_INVALID)
struct acpi_port_info {
char *name;
@ -1030,6 +1033,7 @@ struct acpi_external_list {
u8 type;
u8 flags;
u8 resolved;
u8 emitted;
};
/* Values for Flags field above */

View File

@ -104,8 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
acpi_handle start_object,
u32 max_depth,
u32 flags,
acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
acpi_walk_callback descending_callback,
acpi_walk_callback ascending_callback,
void *context, void **return_value);
struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node

View File

@ -46,6 +46,13 @@
acpi_status acpi_allocate_root_table(u32 initial_table_count);
/*
* tbxfroot - Root pointer utilities
*/
acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length);
/*
* tbfadt - FADT parse/convert/validate
*/

View File

@ -470,6 +470,8 @@ acpi_status acpi_ut_install_interface(acpi_string interface_name);
acpi_status acpi_ut_remove_interface(acpi_string interface_name);
acpi_status acpi_ut_update_interfaces(u8 action);
struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name);
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
@ -616,7 +618,7 @@ int acpi_ut_stricmp(char *string1, char *string2);
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
void acpi_ut_print_string(char *string, u8 max_length);
void acpi_ut_print_string(char *string, u16 max_length);
void ut_convert_backslashes(char *pathname);

View File

@ -125,7 +125,6 @@ acpi_status acpi_ev_gpe_initialize(void)
/* GPE block 0 exists (has both length and address > 0) */
register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2);
gpe_number_max =
(register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
@ -204,16 +203,6 @@ acpi_status acpi_ev_gpe_initialize(void)
goto cleanup;
}
/* Check for Max GPE number out-of-range */
if (gpe_number_max > ACPI_GPE_MAX) {
ACPI_ERROR((AE_INFO,
"Maximum GPE number from FADT is too large: 0x%X",
gpe_number_max));
status = AE_BAD_VALUE;
goto cleanup;
}
cleanup:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(AE_OK);

View File

@ -338,6 +338,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
{
u8 *target;
char *name;
const char *reference_name;
u8 count;
if (!info) {
@ -426,10 +427,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
case ACPI_EXD_REFERENCE:
reference_name = acpi_ut_get_reference_name(obj_desc);
acpi_ex_out_string("Class Name",
ACPI_CAST_PTR(char,
acpi_ut_get_reference_name
(obj_desc)));
ACPI_CAST_PTR(char, reference_name));
acpi_ex_dump_reference_obj(obj_desc);
break;

View File

@ -962,10 +962,17 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
*/
return_desc =
*(operand[0]->reference.where);
if (return_desc) {
acpi_ut_add_reference
(return_desc);
if (!return_desc) {
/*
* Element is NULL, do not allow the dereference.
* This provides compatibility with other ACPI
* implementations.
*/
return_ACPI_STATUS
(AE_AML_UNINITIALIZED_ELEMENT);
}
acpi_ut_add_reference(return_desc);
break;
default:
@ -990,11 +997,40 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
acpi_namespace_node
*)
return_desc);
if (!return_desc) {
break;
}
/*
* June 2013:
* buffer_fields/field_units require additional resolution
*/
switch (return_desc->common.type) {
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
status =
acpi_ex_read_data_from_field
(walk_state, return_desc,
&temp_desc);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
return_desc = temp_desc;
break;
default:
/* Add another reference to the object */
acpi_ut_add_reference
(return_desc);
break;
}
}
/* Add another reference to the object! */
acpi_ut_add_reference(return_desc);
break;
default:

View File

@ -43,6 +43,7 @@
*/
#include <acpi/acpi.h>
#include <linux/acpi.h>
#include "accommon.h"
#define _COMPONENT ACPI_HARDWARE
@ -128,6 +129,14 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
ACPI_FLUSH_CPU_CACHE();
status = acpi_os_prepare_extended_sleep(sleep_state,
acpi_gbl_sleep_type_a,
acpi_gbl_sleep_type_b);
if (ACPI_SKIP(status))
return_ACPI_STATUS(AE_OK);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
/*
* Set the SLP_TYP and SLP_EN bits.
*

View File

@ -100,8 +100,13 @@ acpi_status acpi_get_timer(u32 * ticks)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block);
/* ACPI 5.0A: PM Timer is optional */
if (!acpi_gbl_FADT.xpm_timer_block.address) {
return_ACPI_STATUS(AE_SUPPORT);
}
status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block);
return_ACPI_STATUS(status);
}
@ -148,6 +153,12 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* ACPI 5.0A: PM Timer is optional */
if (!acpi_gbl_FADT.xpm_timer_block.address) {
return_ACPI_STATUS(AE_SUPPORT);
}
/*
* Compute Tick Delta:
* Handle (max one) timer rollovers on 24-bit versus 32-bit timers.

View File

@ -150,6 +150,15 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node,
goto exit;
}
/*
*
* 4) If there is no return value and it is optional, just return
* AE_OK (_WAK).
*/
if (!(*return_object_ptr)) {
goto exit;
}
/*
* For returned Package objects, check the type of all sub-objects.
* Note: Package may have been newly created by call above.
@ -268,7 +277,12 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info,
acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
if (!return_object) {
ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
info->node_flags,
"Expected return object of type %s",
type_buffer));
} else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
info->node_flags,
"Return type mismatch - found %s, expected %s",

View File

@ -156,9 +156,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
* max_depth - Depth to which search is to reach
* flags - Whether to unlock the NS before invoking
* the callback routine
* pre_order_visit - Called during tree pre-order visit
* descending_callback - Called during tree descent
* when an object of "Type" is found
* post_order_visit - Called during tree post-order visit
* ascending_callback - Called during tree ascent
* when an object of "Type" is found
* context - Passed to user function(s) above
* return_value - from the user_function if terminated
@ -185,8 +185,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
acpi_handle start_node,
u32 max_depth,
u32 flags,
acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
acpi_walk_callback descending_callback,
acpi_walk_callback ascending_callback,
void *context, void **return_value)
{
acpi_status status;
@ -255,22 +255,22 @@ acpi_ns_walk_namespace(acpi_object_type type,
}
/*
* Invoke the user function, either pre-order or post-order
* Invoke the user function, either descending, ascending,
* or both.
*/
if (!node_previously_visited) {
if (pre_order_visit) {
if (descending_callback) {
status =
pre_order_visit(child_node, level,
context,
return_value);
descending_callback(child_node,
level, context,
return_value);
}
} else {
if (post_order_visit) {
if (ascending_callback) {
status =
post_order_visit(child_node, level,
context,
return_value);
ascending_callback(child_node,
level, context,
return_value);
}
}

View File

@ -533,9 +533,9 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
* PARAMETERS: type - acpi_object_type to search for
* start_object - Handle in namespace where search begins
* max_depth - Depth to which search is to reach
* pre_order_visit - Called during tree pre-order visit
* descending_callback - Called during tree descent
* when an object of "Type" is found
* post_order_visit - Called during tree post-order visit
* ascending_callback - Called during tree ascent
* when an object of "Type" is found
* context - Passed to user function(s) above
* return_value - Location where return value of
@ -563,8 +563,8 @@ acpi_status
acpi_walk_namespace(acpi_object_type type,
acpi_handle start_object,
u32 max_depth,
acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
acpi_walk_callback descending_callback,
acpi_walk_callback ascending_callback,
void *context, void **return_value)
{
acpi_status status;
@ -574,7 +574,7 @@ acpi_walk_namespace(acpi_object_type type,
/* Parameter validation */
if ((type > ACPI_TYPE_LOCAL_MAX) ||
(!max_depth) || (!pre_order_visit && !post_order_visit)) {
(!max_depth) || (!descending_callback && !ascending_callback)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@ -606,9 +606,9 @@ acpi_walk_namespace(acpi_object_type type,
}
status = acpi_ns_walk_namespace(type, start_object, max_depth,
ACPI_NS_WALK_UNLOCK, pre_order_visit,
post_order_visit, context,
return_value);
ACPI_NS_WALK_UNLOCK,
descending_callback, ascending_callback,
context, return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

View File

@ -158,6 +158,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
{
acpi_status status;
struct acpi_namespace_node *node;
char *node_name;
/* Parameter validation */
@ -202,7 +203,8 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
/* Just copy the ACPI name from the Node and zero terminate it */
ACPI_MOVE_NAME(buffer->pointer, acpi_ut_get_node_name(node));
node_name = acpi_ut_get_node_name(node);
ACPI_MOVE_NAME(buffer->pointer, node_name);
((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
status = AE_OK;
@ -379,9 +381,14 @@ acpi_get_object_info(acpi_handle handle,
* Get extra info for ACPI Device/Processor objects only:
* Run the _STA, _ADR and, sx_w, and _sx_d methods.
*
* Note: none of these methods are required, so they may or may
* Notes: none of these methods are required, so they may or may
* not be present for this device. The Info->Valid bitfield is used
* to indicate which methods were found and run successfully.
*
* For _STA, if the method does not exist, then (as per the ACPI
* specification), the returned current_status flags will indicate
* that the device is present/functional/enabled. Otherwise, the
* current_status flags reflect the value returned from _STA.
*/
/* Execute the Device._STA method */

View File

@ -117,7 +117,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
ACPI_FADT_OFFSET(pm_timer_block),
ACPI_FADT_OFFSET(pm_timer_length),
ACPI_PM_TIMER_WIDTH,
ACPI_FADT_REQUIRED},
ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */
{"Gpe0Block",
ACPI_FADT_OFFSET(xgpe0_block),
@ -574,7 +574,7 @@ static void acpi_tb_validate_fadt(void)
if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
/*
* Field is required (Pm1a_event, Pm1a_control, pm_timer).
* Field is required (Pm1a_event, Pm1a_control).
* Both the address and length must be non-zero.
*/
if (!address64->address || !length) {

View File

@ -48,11 +48,6 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME("tbxfroot")
/* Local prototypes */
static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_rsdp
@ -64,8 +59,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
* DESCRIPTION: Validate the RSDP (ptr)
*
******************************************************************************/
static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
{
/*
@ -74,7 +68,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* Note: Sometimes there exists more than one RSDP in memory; the valid
* RSDP has a valid checksum, all others have an invalid checksum.
*/
if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
if (ACPI_STRNCMP((char *)rsdp->signature, ACPI_SIG_RSDP,
sizeof(ACPI_SIG_RSDP) - 1) != 0) {
/* Nope, BAD Signature */
@ -231,7 +225,7 @@ acpi_status acpi_find_root_pointer(acpi_size *table_address)
* DESCRIPTION: Search a block of memory for the RSDP signature
*
******************************************************************************/
static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length)
{
acpi_status status;
u8 *mem_rover;

View File

@ -239,7 +239,8 @@ acpi_ut_evaluate_numeric_object(char *object_name,
* RETURN: Status
*
* DESCRIPTION: Executes _STA for selected device and stores results in
* *Flags.
* *Flags. If _STA does not exist, then the device is assumed
* to be present/functional/enabled (as per the ACPI spec).
*
* NOTE: Internal function, no parameter validation
*
@ -257,6 +258,11 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
ACPI_BTYPE_INTEGER, &obj_desc);
if (ACPI_FAILURE(status)) {
if (AE_NOT_FOUND == status) {
/*
* if _STA does not exist, then (as per the ACPI specification),
* the returned flags will indicate that the device is present,
* functional, and enabled.
*/
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"_STA on %4.4s was not found, assuming device is present\n",
acpi_ut_get_node_name(device_node)));

View File

@ -336,7 +336,6 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
acpi_gbl_osi_data = 0;
acpi_gbl_osi_mutex = NULL;
acpi_gbl_reg_methods_executed = FALSE;

View File

@ -77,21 +77,20 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = {
/* Feature Group Strings */
{"Extended Address Space Descriptor", NULL, 0, 0}
{"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
/*
* All "optional" feature group strings (features that are implemented
* by the host) should be dynamically added by the host via
* acpi_install_interface and should not be manually added here.
*
* Examples of optional feature group strings:
*
* "Module Device"
* "Processor Device"
* "3.0 Thermal Model"
* "3.0 _SCP Extensions"
* "Processor Aggregator Device"
* by the host) should be dynamically modified to VALID by the host via
* acpi_install_interface or acpi_update_interfaces. Such optional feature
* group strings are set as INVALID by default here.
*/
{"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
{"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
{"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
{"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
{"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
};
/*******************************************************************************
@ -158,11 +157,20 @@ acpi_status acpi_ut_interface_terminate(void)
while (next_interface) {
acpi_gbl_supported_interfaces = next_interface->next;
/* Only interfaces added at runtime can be freed */
if (next_interface->flags & ACPI_OSI_DYNAMIC) {
/* Only interfaces added at runtime can be freed */
ACPI_FREE(next_interface->name);
ACPI_FREE(next_interface);
} else {
/* Interface is in static list. Reset it to invalid or valid. */
if (next_interface->flags & ACPI_OSI_DEFAULT_INVALID) {
next_interface->flags |= ACPI_OSI_INVALID;
} else {
next_interface->flags &= ~ACPI_OSI_INVALID;
}
}
next_interface = acpi_gbl_supported_interfaces;
@ -276,6 +284,49 @@ acpi_status acpi_ut_remove_interface(acpi_string interface_name)
return (AE_NOT_EXIST);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_update_interfaces
*
* PARAMETERS: action - Actions to be performed during the
* update
*
* RETURN: Status
*
* DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
* strings or/and feature group strings.
* Caller MUST hold acpi_gbl_osi_mutex
*
******************************************************************************/
acpi_status acpi_ut_update_interfaces(u8 action)
{
struct acpi_interface_info *next_interface;
next_interface = acpi_gbl_supported_interfaces;
while (next_interface) {
if (((next_interface->flags & ACPI_OSI_FEATURE) &&
(action & ACPI_FEATURE_STRINGS)) ||
(!(next_interface->flags & ACPI_OSI_FEATURE) &&
(action & ACPI_VENDOR_STRINGS))) {
if (action & ACPI_DISABLE_INTERFACES) {
/* Mark the interfaces as invalid */
next_interface->flags |= ACPI_OSI_INVALID;
} else {
/* Mark the interfaces as valid */
next_interface->flags &= ~ACPI_OSI_INVALID;
}
}
next_interface = next_interface->next;
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_get_interface

View File

@ -333,7 +333,8 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
* FUNCTION: acpi_ut_print_string
*
* PARAMETERS: string - Null terminated ASCII string
* max_length - Maximum output length
* max_length - Maximum output length. Used to constrain the
* length of strings during debug output only.
*
* RETURN: None
*
@ -342,7 +343,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
*
******************************************************************************/
void acpi_ut_print_string(char *string, u8 max_length)
void acpi_ut_print_string(char *string, u16 max_length)
{
u32 i;

View File

@ -387,6 +387,34 @@ acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
/*****************************************************************************
*
* FUNCTION: acpi_update_interfaces
*
* PARAMETERS: action - Actions to be performed during the
* update
*
* RETURN: Status
*
* DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
* string or/and feature group strings.
*
****************************************************************************/
acpi_status acpi_update_interfaces(u8 action)
{
acpi_status status;
status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
if (ACPI_FAILURE(status)) {
return (status);
}
status = acpi_ut_update_interfaces(action);
acpi_os_release_mutex(acpi_gbl_osi_mutex);
return (status);
}
/*****************************************************************************
*
* FUNCTION: acpi_check_address_range
@ -402,6 +430,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
* ASL operation region address ranges.
*
****************************************************************************/
u32
acpi_check_address_range(acpi_adr_space_type space_id,
acpi_physical_address address,

View File

@ -527,18 +527,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
static int acpi_battery_set_alarm(struct acpi_battery *battery)
{
acpi_status status = 0;
union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
if (!acpi_battery_present(battery) ||
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
return -ENODEV;
arg0.integer.value = battery->alarm;
mutex_lock(&battery->lock);
status = acpi_evaluate_object(battery->device->handle, "_BTP",
&arg_list, NULL);
status = acpi_execute_simple_method(battery->device->handle, "_BTP",
battery->alarm);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status))
@ -550,12 +546,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
acpi_status status = AE_OK;
acpi_handle handle = NULL;
/* See if alarms are supported, and if so, set default */
status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
if (ACPI_FAILURE(status)) {
if (!acpi_has_method(battery->device->handle, "_BTP")) {
clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
return 0;
}
@ -1036,8 +1028,6 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
if (event == ACPI_BATTERY_NOTIFY_INFO)
acpi_battery_refresh(battery);
acpi_battery_update(battery);
acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event,
acpi_battery_present(battery));
@ -1068,7 +1058,7 @@ static int acpi_battery_add(struct acpi_device *device)
{
int result = 0;
struct acpi_battery *battery = NULL;
acpi_handle handle;
if (!device)
return -EINVAL;
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@ -1080,8 +1070,7 @@ static int acpi_battery_add(struct acpi_device *device)
device->driver_data = battery;
mutex_init(&battery->lock);
mutex_init(&battery->sysfs_lock);
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
"_BIX", &handle)))
if (acpi_has_method(battery->device->handle, "_BIX"))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
result = acpi_battery_update(battery);
if (result)

View File

@ -192,6 +192,12 @@ static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
acpi_osi_setup("!Windows 2009");
return 0;
}
static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
{
printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
acpi_osi_setup("!Windows 2012");
return 0;
}
static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
{
@ -267,6 +273,30 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ASUS Zenbook Prime UX31A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "Dell Inspiron 15R SE",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "Lenovo ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
},
},
/*
* BIOS invocation of _OSI(Linux) is almost always a BIOS bug.

View File

@ -89,27 +89,6 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
Device Management
-------------------------------------------------------------------------- */
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
{
acpi_status status;
if (!device)
return -EINVAL;
/* TBD: Support fixed-feature devices */
status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
if (ACPI_FAILURE(status) || !*device) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
handle));
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL(acpi_bus_get_device);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta)
{
@ -345,104 +324,6 @@ static void acpi_bus_osc_support(void)
/* do we need to check other returned cap? Sounds no */
}
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROC_EVENT
static DEFINE_SPINLOCK(acpi_bus_event_lock);
LIST_HEAD(acpi_bus_event_list);
DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
extern int event_is_open;
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
{
struct acpi_bus_event *event;
unsigned long flags;
/* drop event on the floor if no one's listening */
if (!event_is_open)
return 0;
event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
if (!event)
return -ENOMEM;
strcpy(event->device_class, device_class);
strcpy(event->bus_id, bus_id);
event->type = type;
event->data = data;
spin_lock_irqsave(&acpi_bus_event_lock, flags);
list_add_tail(&event->node, &acpi_bus_event_list);
spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
wake_up_interruptible(&acpi_bus_event_queue);
return 0;
}
EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
{
if (!device)
return -EINVAL;
return acpi_bus_generate_proc_event4(device->pnp.device_class,
device->pnp.bus_id, type, data);
}
EXPORT_SYMBOL(acpi_bus_generate_proc_event);
int acpi_bus_receive_event(struct acpi_bus_event *event)
{
unsigned long flags;
struct acpi_bus_event *entry = NULL;
DECLARE_WAITQUEUE(wait, current);
if (!event)
return -EINVAL;
if (list_empty(&acpi_bus_event_list)) {
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&acpi_bus_event_queue, &wait);
if (list_empty(&acpi_bus_event_list))
schedule();
remove_wait_queue(&acpi_bus_event_queue, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
}
spin_lock_irqsave(&acpi_bus_event_lock, flags);
if (!list_empty(&acpi_bus_event_list)) {
entry = list_entry(acpi_bus_event_list.next,
struct acpi_bus_event, node);
list_del(&entry->node);
}
spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
if (!entry)
return -ENODEV;
memcpy(event, entry, sizeof(struct acpi_bus_event));
kfree(entry);
return 0;
}
#endif /* CONFIG_ACPI_PROC_EVENT */
/* --------------------------------------------------------------------------
Notification Handling
-------------------------------------------------------------------------- */
@ -499,19 +380,6 @@ static void acpi_bus_check_scope(acpi_handle handle)
*/
}
static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
int register_acpi_bus_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
void unregister_acpi_bus_notifier(struct notifier_block *nb)
{
blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
/**
* acpi_bus_notify
* ---------------
@ -525,9 +393,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n",
type, handle));
blocking_notifier_call_chain(&acpi_bus_notify_list,
type, (void *)handle);
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
@ -593,8 +458,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
static int __init acpi_bus_init_irq(void)
{
acpi_status status;
union acpi_object arg = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg };
char *message = NULL;
@ -623,9 +486,7 @@ static int __init acpi_bus_init_irq(void)
printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
arg.integer.value = acpi_irq_model;
status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
return -ENODEV;
@ -715,7 +576,6 @@ static int __init acpi_bus_init(void)
{
int result;
acpi_status status;
extern acpi_status acpi_os_initialize1(void);
acpi_os_initialize1();

View File

@ -303,8 +303,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
pm_wakeup_event(&device->dev, 0);
}
acpi_bus_generate_proc_event(device, event, ++button->pushed);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,

View File

@ -159,26 +159,29 @@ int acpi_device_set_power(struct acpi_device *device, int state)
int result = 0;
bool cut_power = false;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
if (!device || !device->flags.power_manageable
|| (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL;
/* Make sure this is a valid target state */
if (state == device->power.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n",
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n",
device->pnp.bus_id,
acpi_power_state_string(state)));
return 0;
}
if (!device->power.states[state].flags.valid) {
printk(KERN_WARNING PREFIX "Device does not support %s\n",
acpi_power_state_string(state));
dev_warn(&device->dev, "Power state %s not supported\n",
acpi_power_state_string(state));
return -ENODEV;
}
if (device->parent && (state < device->parent->power.state)) {
printk(KERN_WARNING PREFIX
"Cannot set device to a higher-powered"
" state than parent\n");
dev_warn(&device->dev,
"Cannot transition to power state %s for parent in %s\n",
acpi_power_state_string(state),
acpi_power_state_string(device->parent->power.state));
return -ENODEV;
}
@ -191,8 +194,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
if (state < device->power.state && state != ACPI_STATE_D0
&& device->power.state >= ACPI_STATE_D3_HOT) {
printk(KERN_WARNING PREFIX
"Cannot transition to non-D0 state from D3\n");
dev_warn(&device->dev,
"Cannot transition to non-D0 state from D3\n");
return -ENODEV;
}
@ -219,10 +222,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
end:
if (result) {
printk(KERN_WARNING PREFIX
"Device [%s] failed to transition to %s\n",
device->pnp.bus_id,
acpi_power_state_string(state));
dev_warn(&device->dev, "Failed to change power state to %s\n",
acpi_power_state_string(state));
} else {
device->power.state = state;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@ -244,13 +245,6 @@ int acpi_bus_set_power(acpi_handle handle, int state)
if (result)
return result;
if (!device->flags.power_manageable) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Device [%s] is not power manageable\n",
dev_name(&device->dev)));
return -ENODEV;
}
return acpi_device_set_power(device, state);
}
EXPORT_SYMBOL(acpi_bus_set_power);

View File

@ -51,8 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
" the driver to wait for userspace to write the undock sysfs file "
" before undocking");
static struct atomic_notifier_head dock_notifier_list;
static const struct acpi_device_id dock_device_ids[] = {
{"LNXDOCK", 0},
{"", 0},
@ -63,8 +61,6 @@ struct dock_station {
acpi_handle handle;
unsigned long last_dock_time;
u32 flags;
spinlock_t dd_lock;
struct mutex hp_lock;
struct list_head dependent_devices;
struct list_head sibling;
@ -91,6 +87,12 @@ struct dock_dependent_device {
#define DOCK_EVENT 3
#define UNDOCK_EVENT 2
enum dock_callback_type {
DOCK_CALL_HANDLER,
DOCK_CALL_FIXUP,
DOCK_CALL_UEVENT,
};
/*****************************************************************************
* Dock Dependent device functions *
*****************************************************************************/
@ -101,7 +103,7 @@ struct dock_dependent_device {
*
* Add the dependent device to the dock's dependent device list.
*/
static int
static int __init
add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
{
struct dock_dependent_device *dd;
@ -112,14 +114,21 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
dd->handle = handle;
INIT_LIST_HEAD(&dd->list);
spin_lock(&ds->dd_lock);
list_add_tail(&dd->list, &ds->dependent_devices);
spin_unlock(&ds->dd_lock);
return 0;
}
static void remove_dock_dependent_devices(struct dock_station *ds)
{
struct dock_dependent_device *dd, *aux;
list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) {
list_del(&dd->list);
kfree(dd);
}
}
/**
* dock_init_hotplug - Initialize a hotplug device on a docking station.
* @dd: Dock-dependent device.
@ -135,19 +144,16 @@ static int dock_init_hotplug(struct dock_dependent_device *dd,
int ret = 0;
mutex_lock(&hotplug_lock);
if (dd->hp_context) {
if (WARN_ON(dd->hp_context)) {
ret = -EEXIST;
} else {
dd->hp_refcount = 1;
dd->hp_ops = ops;
dd->hp_context = context;
dd->hp_release = release;
if (init)
init(context);
}
if (!WARN_ON(ret) && init)
init(context);
mutex_unlock(&hotplug_lock);
return ret;
}
@ -162,27 +168,22 @@ static int dock_init_hotplug(struct dock_dependent_device *dd,
*/
static void dock_release_hotplug(struct dock_dependent_device *dd)
{
void (*release)(void *) = NULL;
void *context = NULL;
mutex_lock(&hotplug_lock);
if (dd->hp_context && !--dd->hp_refcount) {
void (*release)(void *) = dd->hp_release;
void *context = dd->hp_context;
dd->hp_ops = NULL;
context = dd->hp_context;
dd->hp_context = NULL;
release = dd->hp_release;
dd->hp_release = NULL;
if (release)
release(context);
}
if (release && context)
release(context);
mutex_unlock(&hotplug_lock);
}
static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
bool uevent)
enum dock_callback_type cb_type)
{
acpi_notify_handler cb = NULL;
bool run = false;
@ -192,8 +193,18 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
if (dd->hp_context) {
run = true;
dd->hp_refcount++;
if (dd->hp_ops)
cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler;
if (dd->hp_ops) {
switch (cb_type) {
case DOCK_CALL_FIXUP:
cb = dd->hp_ops->fixup;
break;
case DOCK_CALL_UEVENT:
cb = dd->hp_ops->uevent;
break;
default:
cb = dd->hp_ops->handler;
}
}
}
mutex_unlock(&hotplug_lock);
@ -220,63 +231,17 @@ find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
{
struct dock_dependent_device *dd;
spin_lock(&ds->dd_lock);
list_for_each_entry(dd, &ds->dependent_devices, list) {
if (handle == dd->handle) {
spin_unlock(&ds->dd_lock);
list_for_each_entry(dd, &ds->dependent_devices, list)
if (handle == dd->handle)
return dd;
}
}
spin_unlock(&ds->dd_lock);
return NULL;
}
/*****************************************************************************
* Dock functions *
*****************************************************************************/
/**
* is_dock - see if a device is a dock station
* @handle: acpi handle of the device
*
* If an acpi object has a _DCK method, then it is by definition a dock
* station, so return true.
*/
static int is_dock(acpi_handle handle)
{
acpi_status status;
acpi_handle tmp;
status = acpi_get_handle(handle, "_DCK", &tmp);
if (ACPI_FAILURE(status))
return 0;
return 1;
}
static int is_ejectable(acpi_handle handle)
{
acpi_status status;
acpi_handle tmp;
status = acpi_get_handle(handle, "_EJ0", &tmp);
if (ACPI_FAILURE(status))
return 0;
return 1;
}
static int is_ata(acpi_handle handle)
{
acpi_handle tmp;
if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
return 1;
return 0;
}
static int is_battery(acpi_handle handle)
static int __init is_battery(acpi_handle handle)
{
struct acpi_device_info *info;
int ret = 1;
@ -292,17 +257,13 @@ static int is_battery(acpi_handle handle)
return ret;
}
static int is_ejectable_bay(acpi_handle handle)
/* Check whether ACPI object is an ejectable battery or disk bay */
static bool __init is_ejectable_bay(acpi_handle handle)
{
acpi_handle phandle;
if (acpi_has_method(handle, "_EJ0") && is_battery(handle))
return true;
if (!is_ejectable(handle))
return 0;
if (is_battery(handle) || is_ata(handle))
return 1;
if (!acpi_get_parent(handle, &phandle) && is_ata(phandle))
return 1;
return 0;
return acpi_bay_match(handle);
}
/**
@ -320,7 +281,7 @@ int is_dock_device(acpi_handle handle)
if (!dock_station_count)
return 0;
if (is_dock(handle))
if (acpi_dock_match(handle))
return 1;
list_for_each_entry(dock_station, &dock_stations, sibling)
@ -359,10 +320,8 @@ static int dock_present(struct dock_station *ds)
* handle if one does not exist already. This should cause
* acpi to scan for drivers for the given devices, and call
* matching driver's add routine.
*
* Returns a pointer to the acpi_device corresponding to the handle.
*/
static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
static void dock_create_acpi_device(acpi_handle handle)
{
struct acpi_device *device;
int ret;
@ -375,10 +334,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
ret = acpi_bus_scan(handle);
if (ret)
pr_debug("error adding bus, %x\n", -ret);
acpi_bus_get_device(handle, &device);
}
return device;
}
/**
@ -397,9 +353,29 @@ static void dock_remove_acpi_device(acpi_handle handle)
}
/**
* hotplug_dock_devices - insert or remove devices on the dock station
* hot_remove_dock_devices - Remove dock station devices.
* @ds: Dock station.
*/
static void hot_remove_dock_devices(struct dock_station *ds)
{
struct dock_dependent_device *dd;
/*
* Walk the list in reverse order so that devices that have been added
* last are removed first (in case there are some indirect dependencies
* between them).
*/
list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);
list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
dock_remove_acpi_device(dd->handle);
}
/**
* hotplug_dock_devices - Insert devices on a dock station.
* @ds: the dock station
* @event: either bus check or eject request
* @event: either bus check or device check request
*
* Some devices on the dock station need to have drivers called
* to perform hotplug operations after a dock event has occurred.
@ -410,27 +386,21 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
{
struct dock_dependent_device *dd;
mutex_lock(&ds->hp_lock);
/* Call driver specific post-dock fixups. */
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, DOCK_CALL_FIXUP);
/* Call driver specific hotplug functions. */
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);
/*
* First call driver specific hotplug functions
* Now make sure that an acpi_device is created for each dependent
* device. That will cause scan handlers to be attached to device
* objects or acpi_drivers to be stopped/started if they are present.
*/
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, false);
/*
* Now make sure that an acpi_device is created for each
* dependent device, or removed if this is an eject request.
* This will cause acpi_drivers to be stopped/started if they
* exist
*/
list_for_each_entry(dd, &ds->dependent_devices, list) {
if (event == ACPI_NOTIFY_EJECT_REQUEST)
dock_remove_acpi_device(dd->handle);
else
dock_create_acpi_device(dd->handle);
}
mutex_unlock(&ds->hp_lock);
dock_create_acpi_device(dd->handle);
}
static void dock_event(struct dock_station *ds, u32 event, int num)
@ -453,43 +423,12 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, true);
dock_hotplug_event(dd, event, DOCK_CALL_UEVENT);
if (num != DOCK_EVENT)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}
/**
* eject_dock - respond to a dock eject request
* @ds: the dock station
*
* This is called after _DCK is called, to execute the dock station's
* _EJ0 method.
*/
static void eject_dock(struct dock_station *ds)
{
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status;
acpi_handle tmp;
/* all dock devices should have _EJ0, but check anyway */
status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
if (ACPI_FAILURE(status)) {
pr_debug("No _EJ0 support for dock device\n");
return;
}
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 1;
status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status))
pr_debug("Failed to evaluate _EJ0!\n");
}
/**
* handle_dock - handle a dock event
* @ds: the dock station
@ -550,27 +489,6 @@ static inline void complete_undock(struct dock_station *ds)
ds->flags &= ~(DOCK_UNDOCKING);
}
static void dock_lock(struct dock_station *ds, int lock)
{
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status;
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = !!lock;
status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
if (lock)
acpi_handle_warn(ds->handle,
"Locking device failed (0x%x)\n", status);
else
acpi_handle_warn(ds->handle,
"Unlocking device failed (0x%x)\n", status);
}
}
/**
* dock_in_progress - see if we are in the middle of handling a dock event
* @ds: the dock station
@ -587,37 +505,6 @@ static int dock_in_progress(struct dock_station *ds)
return 0;
}
/**
* register_dock_notifier - add yourself to the dock notifier list
* @nb: the callers notifier block
*
* If a driver wishes to be notified about dock events, they can
* use this function to put a notifier block on the dock notifier list.
* this notifier call chain will be called after a dock event, but
* before hotplugging any new devices.
*/
int register_dock_notifier(struct notifier_block *nb)
{
if (!dock_station_count)
return -ENODEV;
return atomic_notifier_chain_register(&dock_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(register_dock_notifier);
/**
* unregister_dock_notifier - remove yourself from the dock notifier list
* @nb: the callers notifier block
*/
void unregister_dock_notifier(struct notifier_block *nb)
{
if (!dock_station_count)
return;
atomic_notifier_chain_unregister(&dock_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_dock_notifier);
/**
* register_hotplug_dock_device - register a hotplug function
* @handle: the handle of the device
@ -703,10 +590,10 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
*/
dock_event(ds, event, UNDOCK_EVENT);
hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
hot_remove_dock_devices(ds);
undock(ds);
dock_lock(ds, 0);
eject_dock(ds);
acpi_evaluate_lck(ds->handle, 0);
acpi_evaluate_ej0(ds->handle);
if (dock_present(ds)) {
acpi_handle_err(ds->handle, "Unable to undock!\n");
return -EBUSY;
@ -717,18 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
/**
* dock_notify - act upon an acpi dock notification
* @handle: the dock station handle
* @ds: dock station
* @event: the acpi event
* @data: our driver data struct
*
* If we are notified to dock, then check to see if the dock is
* present and then dock. Notify all drivers of the dock event,
* and then hotplug and devices that may need hotplugging.
*/
static void dock_notify(acpi_handle handle, u32 event, void *data)
static void dock_notify(struct dock_station *ds, u32 event)
{
struct dock_station *ds = data;
struct acpi_device *tmp;
acpi_handle handle = ds->handle;
struct acpi_device *ad;
int surprise_removal = 0;
/*
@ -751,8 +637,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
&tmp)) {
if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) {
begin_dock(ds);
dock(ds);
if (!dock_present(ds)) {
@ -760,12 +645,10 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
complete_dock(ds);
break;
}
atomic_notifier_call_chain(&dock_notifier_list,
event, NULL);
hotplug_dock_devices(ds, event);
complete_dock(ds);
dock_event(ds, event, DOCK_EVENT);
dock_lock(ds, 1);
acpi_evaluate_lck(ds->handle, 1);
acpi_update_all_gpes();
break;
}
@ -789,9 +672,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
}
struct dock_data {
acpi_handle handle;
unsigned long event;
struct dock_station *ds;
u32 event;
};
static void acpi_dock_deferred_cb(void *context)
@ -799,52 +681,31 @@ static void acpi_dock_deferred_cb(void *context)
struct dock_data *data = context;
acpi_scan_lock_acquire();
dock_notify(data->handle, data->event, data->ds);
dock_notify(data->ds, data->event);
acpi_scan_lock_release();
kfree(data);
}
static int acpi_dock_notifier_call(struct notifier_block *this,
unsigned long event, void *data)
static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
{
struct dock_station *dock_station;
acpi_handle handle = data;
struct dock_data *dd;
if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
&& event != ACPI_NOTIFY_EJECT_REQUEST)
return 0;
return;
acpi_scan_lock_acquire();
dd = kmalloc(sizeof(*dd), GFP_KERNEL);
if (dd) {
acpi_status status;
list_for_each_entry(dock_station, &dock_stations, sibling) {
if (dock_station->handle == handle) {
struct dock_data *dd;
acpi_status status;
dd = kmalloc(sizeof(*dd), GFP_KERNEL);
if (!dd)
break;
dd->handle = handle;
dd->event = event;
dd->ds = dock_station;
status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
dd);
if (ACPI_FAILURE(status))
kfree(dd);
break;
}
dd->ds = data;
dd->event = event;
status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
if (ACPI_FAILURE(status))
kfree(dd);
}
acpi_scan_lock_release();
return 0;
}
static struct notifier_block dock_acpi_notifier = {
.notifier_call = acpi_dock_notifier_call,
};
/**
* find_dock_devices - find devices on the dock station
* @handle: the handle of the device we are examining
@ -856,29 +717,16 @@ static struct notifier_block dock_acpi_notifier = {
* check to see if an object has an _EJD method. If it does, then it
* will see if it is dependent on the dock station.
*/
static acpi_status
find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
void *context, void **rv)
{
acpi_status status;
acpi_handle tmp, parent;
struct dock_station *ds = context;
acpi_handle ejd = NULL;
status = acpi_bus_get_ejd(handle, &tmp);
if (ACPI_FAILURE(status)) {
/* try the parent device as well */
status = acpi_get_parent(handle, &parent);
if (ACPI_FAILURE(status))
goto fdd_out;
/* see if parent is dependent on dock */
status = acpi_bus_get_ejd(parent, &tmp);
if (ACPI_FAILURE(status))
goto fdd_out;
}
if (tmp == ds->handle)
acpi_bus_get_ejd(handle, &ejd);
if (ejd == ds->handle)
add_dock_dependent_device(ds, handle);
fdd_out:
return AE_OK;
}
@ -988,13 +836,13 @@ static struct attribute_group dock_attribute_group = {
*/
static int __init dock_add(acpi_handle handle)
{
int ret, id;
struct dock_station ds, *dock_station;
struct dock_station *dock_station, ds = { NULL, };
struct platform_device *dd;
acpi_status status;
int ret;
id = dock_station_count;
memset(&ds, 0, sizeof(ds));
dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
dd = platform_device_register_data(NULL, "dock", dock_station_count,
&ds, sizeof(ds));
if (IS_ERR(dd))
return PTR_ERR(dd);
@ -1004,18 +852,15 @@ static int __init dock_add(acpi_handle handle)
dock_station->dock_device = dd;
dock_station->last_dock_time = jiffies - HZ;
mutex_init(&dock_station->hp_lock);
spin_lock_init(&dock_station->dd_lock);
INIT_LIST_HEAD(&dock_station->sibling);
ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
INIT_LIST_HEAD(&dock_station->dependent_devices);
/* we want the dock device to send uevents */
dev_set_uevent_suppress(&dd->dev, 0);
if (is_dock(handle))
if (acpi_dock_match(handle))
dock_station->flags |= DOCK_IS_DOCK;
if (is_ata(handle))
if (acpi_ata_match(handle))
dock_station->flags |= DOCK_IS_ATA;
if (is_battery(handle))
dock_station->flags |= DOCK_IS_BAT;
@ -1034,11 +879,19 @@ static int __init dock_add(acpi_handle handle)
if (ret)
goto err_rmgroup;
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
dock_notify_handler, dock_station);
if (ACPI_FAILURE(status)) {
ret = -ENODEV;
goto err_rmgroup;
}
dock_station_count++;
list_add(&dock_station->sibling, &dock_stations);
return 0;
err_rmgroup:
remove_dock_dependent_devices(dock_station);
sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
err_unregister:
platform_device_unregister(dd);
@ -1055,10 +908,10 @@ err_unregister:
*
* This is called by acpi_walk_namespace to look for dock stations and bays.
*/
static __init acpi_status
static acpi_status __init
find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
{
if (is_dock(handle) || is_ejectable_bay(handle))
if (acpi_dock_match(handle) || is_ejectable_bay(handle))
dock_add(handle);
return AE_OK;
@ -1078,7 +931,6 @@ void __init acpi_dock_init(void)
return;
}
register_acpi_bus_notifier(&dock_acpi_notifier);
pr_info(PREFIX "%s: %d docks/bays found\n",
ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
}

View File

@ -948,7 +948,7 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)
return 0;
}
static struct dmi_system_id __initdata ec_dmi_table[] = {
static struct dmi_system_id ec_dmi_table[] __initdata = {
{
ec_skip_dsdt_scan, "Compal JFL92", {
DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
@ -987,6 +987,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
ec_skip_dsdt_scan, "HP Folio 13", {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
{
ec_validate_ecdt, "ASUS hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL},
{},
};
@ -1049,10 +1053,8 @@ int __init acpi_ec_ecdt_probe(void)
* which needs it, has fake EC._INI method, so use it as flag.
* Keep boot_ec struct as it will be needed soon.
*/
acpi_handle dummy;
if (!dmi_name_in_vendors("ASUS") ||
ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI",
&dummy)))
!acpi_has_method(boot_ec->handle, "_INI"))
return -ENODEV;
}
install:

View File

@ -21,100 +21,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("event");
#ifdef CONFIG_ACPI_PROC_EVENT
/* Global vars for handling event proc entry */
static DEFINE_SPINLOCK(acpi_system_event_lock);
int event_is_open = 0;
extern struct list_head acpi_bus_event_list;
extern wait_queue_head_t acpi_bus_event_queue;
static int acpi_system_open_event(struct inode *inode, struct file *file)
{
spin_lock_irq(&acpi_system_event_lock);
if (event_is_open)
goto out_busy;
event_is_open = 1;
spin_unlock_irq(&acpi_system_event_lock);
return 0;
out_busy:
spin_unlock_irq(&acpi_system_event_lock);
return -EBUSY;
}
static ssize_t
acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
loff_t * ppos)
{
int result = 0;
struct acpi_bus_event event;
static char str[ACPI_MAX_STRING];
static int chars_remaining = 0;
static char *ptr;
if (!chars_remaining) {
memset(&event, 0, sizeof(struct acpi_bus_event));
if ((file->f_flags & O_NONBLOCK)
&& (list_empty(&acpi_bus_event_list)))
return -EAGAIN;
result = acpi_bus_receive_event(&event);
if (result)
return result;
chars_remaining = sprintf(str, "%s %s %08x %08x\n",
event.device_class ? event.
device_class : "<unknown>",
event.bus_id ? event.
bus_id : "<unknown>", event.type,
event.data);
ptr = str;
}
if (chars_remaining < count) {
count = chars_remaining;
}
if (copy_to_user(buffer, ptr, count))
return -EFAULT;
*ppos += count;
chars_remaining -= count;
ptr += count;
return count;
}
static int acpi_system_close_event(struct inode *inode, struct file *file)
{
spin_lock_irq(&acpi_system_event_lock);
event_is_open = 0;
spin_unlock_irq(&acpi_system_event_lock);
return 0;
}
static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait)
{
poll_wait(file, &acpi_bus_event_queue, wait);
if (!list_empty(&acpi_bus_event_list))
return POLLIN | POLLRDNORM;
return 0;
}
static const struct file_operations acpi_system_event_ops = {
.owner = THIS_MODULE,
.open = acpi_system_open_event,
.read = acpi_system_read_event,
.release = acpi_system_close_event,
.poll = acpi_system_poll_event,
.llseek = default_llseek,
};
#endif /* CONFIG_ACPI_PROC_EVENT */
/* ACPI notifier chain */
static BLOCKING_NOTIFIER_HEAD(acpi_chain_head);
@ -280,9 +186,6 @@ static int acpi_event_genetlink_init(void)
static int __init acpi_event_init(void)
{
#ifdef CONFIG_ACPI_PROC_EVENT
struct proc_dir_entry *entry;
#endif
int error = 0;
if (acpi_disabled)
@ -293,15 +196,6 @@ static int __init acpi_event_init(void)
if (error)
printk(KERN_WARNING PREFIX
"Failed to create genetlink family for ACPI event\n");
#ifdef CONFIG_ACPI_PROC_EVENT
/* 'event' [R] */
entry = proc_create("event", S_IRUSR, acpi_root_dir,
&acpi_system_event_ops);
if (!entry)
return -ENODEV;
#endif
return 0;
}

View File

@ -93,7 +93,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
if (result)
return result;
*state = (acpi_state == ACPI_STATE_D3 ? 0 :
*state = (acpi_state == ACPI_STATE_D3_COLD ? 0 :
(acpi_state == ACPI_STATE_D0 ? 1 : -1));
return 0;
}
@ -108,7 +108,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
return -EINVAL;
result = acpi_bus_set_power(device->handle,
state ? ACPI_STATE_D0 : ACPI_STATE_D3);
state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
return result;
}

View File

@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
}
EXPORT_SYMBOL_GPL(acpi_find_child);
static void acpi_physnode_link_name(char *buf, unsigned int node_id)
{
if (node_id > 0)
snprintf(buf, PHYSICAL_NODE_NAME_SIZE,
PHYSICAL_NODE_STRING "%u", node_id);
else
strcpy(buf, PHYSICAL_NODE_STRING);
}
int acpi_bind_one(struct device *dev, acpi_handle handle)
{
struct acpi_device *acpi_dev;
@ -216,8 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
/* Sanity check. */
if (pn->dev == dev) {
mutex_unlock(&acpi_dev->physical_node_lock);
dev_warn(dev, "Already associated with ACPI node\n");
goto err_free;
kfree(physical_node);
if (ACPI_HANDLE(dev) != handle)
goto err;
put_device(dev);
return 0;
}
if (pn->node_id == node_id) {
physnode_list = &pn->node;
@ -230,20 +246,23 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
list_add(&physical_node->node, physnode_list);
acpi_dev->physical_node_count++;
mutex_unlock(&acpi_dev->physical_node_lock);
if (!ACPI_HANDLE(dev))
ACPI_HANDLE_SET(dev, acpi_dev->handle);
if (!physical_node->node_id)
strcpy(physical_node_name, PHYSICAL_NODE_STRING);
else
sprintf(physical_node_name,
"physical_node%d", physical_node->node_id);
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
physical_node_name);
physical_node_name);
if (retval)
dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",
physical_node_name, retval);
retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
"firmware_node");
"firmware_node");
if (retval)
dev_err(dev, "Failed to create link firmware_node (%d)\n",
retval);
mutex_unlock(&acpi_dev->physical_node_lock);
if (acpi_dev->wakeup.flags.valid)
device_set_wakeup_capable(dev, true);
@ -254,11 +273,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
ACPI_HANDLE_SET(dev, NULL);
put_device(dev);
return retval;
err_free:
mutex_unlock(&acpi_dev->physical_node_lock);
kfree(physical_node);
goto err;
}
EXPORT_SYMBOL_GPL(acpi_bind_one);
@ -267,48 +281,37 @@ int acpi_unbind_one(struct device *dev)
struct acpi_device_physical_node *entry;
struct acpi_device *acpi_dev;
acpi_status status;
struct list_head *node, *next;
if (!ACPI_HANDLE(dev))
return 0;
status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev);
if (ACPI_FAILURE(status))
goto err;
if (ACPI_FAILURE(status)) {
dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__);
return -EINVAL;
}
mutex_lock(&acpi_dev->physical_node_lock);
list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
entry = list_entry(node, struct acpi_device_physical_node,
node);
if (entry->dev != dev)
continue;
list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
if (entry->dev == dev) {
char physnode_name[PHYSICAL_NODE_NAME_SIZE];
list_del(node);
list_del(&entry->node);
acpi_dev->physical_node_count--;
acpi_dev->physical_node_count--;
acpi_physnode_link_name(physnode_name, entry->node_id);
sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
sysfs_remove_link(&dev->kobj, "firmware_node");
ACPI_HANDLE_SET(dev, NULL);
/* acpi_bind_one() increase refcnt by one. */
put_device(dev);
kfree(entry);
break;
}
if (!entry->node_id)
strcpy(physical_node_name, PHYSICAL_NODE_STRING);
else
sprintf(physical_node_name,
"physical_node%d", entry->node_id);
sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
sysfs_remove_link(&dev->kobj, "firmware_node");
ACPI_HANDLE_SET(dev, NULL);
/* acpi_bind_one increase refcnt by one */
put_device(dev);
kfree(entry);
}
mutex_unlock(&acpi_dev->physical_node_lock);
return 0;
err:
dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
return -EINVAL;
}
EXPORT_SYMBOL_GPL(acpi_unbind_one);

View File

@ -23,6 +23,7 @@
#define PREFIX "ACPI: "
acpi_status acpi_os_initialize1(void);
int init_acpi_device_notify(void);
int acpi_scan_init(void);
#ifdef CONFIG_ACPI_PCI_SLOT

View File

@ -159,7 +159,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
* distance than the others.
* Do some quick checks here and only use the SLIT if it passes.
*/
static __init int slit_valid(struct acpi_table_slit *slit)
static int __init slit_valid(struct acpi_table_slit *slit)
{
int i, j;
int d = slit->locality_count;

View File

@ -52,6 +52,7 @@
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/processor.h>
#include "internal.h"
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME("osl");
@ -79,6 +80,8 @@ extern char line_buf[80];
static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
u32 pm1b_ctrl);
static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a,
u32 val_b);
static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
@ -140,7 +143,8 @@ static struct osi_linux {
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
} osi_linux = {0, 0, 0};
unsigned int default_disabling:1;
} osi_linux = {0, 0, 0, 0};
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
@ -563,10 +567,6 @@ static const char * const table_sigs[] = {
ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
/* Non-fatal errors: Affected tables/files are ignored */
#define INVALID_TABLE(x, path, name) \
{ pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; }
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
/* Must not increase 10 or needs code modification below */
@ -593,9 +593,11 @@ void __init acpi_initrd_override(void *data, size_t size)
data += offset;
size -= offset;
if (file.size < sizeof(struct acpi_table_header))
INVALID_TABLE("Table smaller than ACPI header",
cpio_path, file.name);
if (file.size < sizeof(struct acpi_table_header)) {
pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n",
cpio_path, file.name);
continue;
}
table = file.data;
@ -603,15 +605,21 @@ void __init acpi_initrd_override(void *data, size_t size)
if (!memcmp(table->signature, table_sigs[sig], 4))
break;
if (!table_sigs[sig])
INVALID_TABLE("Unknown signature",
cpio_path, file.name);
if (file.size != table->length)
INVALID_TABLE("File length does not match table length",
cpio_path, file.name);
if (acpi_table_checksum(file.data, table->length))
INVALID_TABLE("Bad table checksum",
cpio_path, file.name);
if (!table_sigs[sig]) {
pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n",
cpio_path, file.name);
continue;
}
if (file.size != table->length) {
pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n",
cpio_path, file.name);
continue;
}
if (acpi_table_checksum(file.data, table->length)) {
pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n",
cpio_path, file.name);
continue;
}
pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
table->signature, cpio_path, file.name, table->length);
@ -1351,8 +1359,8 @@ struct osi_setup_entry {
bool enable;
};
static struct osi_setup_entry __initdata
osi_setup_entries[OSI_STRING_ENTRIES_MAX] = {
static struct osi_setup_entry
osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
{"Module Device", true},
{"Processor Device", true},
{"3.0 _SCP Extensions", true},
@ -1376,6 +1384,17 @@ void __init acpi_osi_setup(char *str)
if (*str == '!') {
str++;
if (*str == '\0') {
osi_linux.default_disabling = 1;
return;
} else if (*str == '*') {
acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
osi->enable = false;
}
return;
}
enable = false;
}
@ -1441,6 +1460,13 @@ static void __init acpi_osi_setup_late(void)
int i;
acpi_status status;
if (osi_linux.default_disabling) {
status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
if (ACPI_SUCCESS(status))
printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
}
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
str = osi->string;
@ -1779,6 +1805,28 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
__acpi_os_prepare_sleep = func;
}
acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
u32 val_b)
{
int rc = 0;
if (__acpi_os_prepare_extended_sleep)
rc = __acpi_os_prepare_extended_sleep(sleep_state,
val_a, val_b);
if (rc < 0)
return AE_ERROR;
else if (rc > 0)
return AE_CTRL_SKIP;
return AE_OK;
}
void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
u32 val_a, u32 val_b))
{
__acpi_os_prepare_extended_sleep = func;
}
void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
void (*func)(struct work_struct *work))
{

View File

@ -159,12 +159,16 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
}
void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle)
void acpi_pci_slot_enumerate(struct pci_bus *bus)
{
mutex_lock(&slot_list_lock);
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
register_slot, NULL, bus, NULL);
mutex_unlock(&slot_list_lock);
acpi_handle handle = ACPI_HANDLE(bus->bridge);
if (handle) {
mutex_lock(&slot_list_lock);
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
register_slot, NULL, bus, NULL);
mutex_unlock(&slot_list_lock);
}
}
void acpi_pci_slot_remove(struct pci_bus *bus)

View File

@ -637,9 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
}
/* Execute _PSW */
arg_list.count = 1;
in_arg[0].integer.value = enable;
status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
status = acpi_execute_simple_method(dev->handle, "_PSW", enable);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
printk(KERN_ERR PREFIX "_PSW execution failed\n");
dev->wakeup.flags.valid = 0;
@ -786,7 +784,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
}
}
*state = ACPI_STATE_D3;
*state = ACPI_STATE_D3_COLD;
return 0;
}

View File

@ -28,7 +28,7 @@ static int __init set_no_mwait(const struct dmi_system_id *id)
return 0;
}
static struct dmi_system_id __initdata processor_idle_dmi_table[] = {
static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
{
set_no_mwait, "Extensa 5220", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),

View File

@ -91,21 +91,17 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
acpi_processor_ppc_has_changed(pr, 1);
if (saved == pr->performance_platform_limit)
break;
acpi_bus_generate_proc_event(device, event,
pr->performance_platform_limit);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event,
pr->performance_platform_limit);
break;
case ACPI_PROCESSOR_NOTIFY_POWER:
acpi_processor_cst_has_changed(pr);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
case ACPI_PROCESSOR_NOTIFY_THROTTLING:
acpi_processor_tstate_has_changed(pr);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
@ -179,7 +175,9 @@ static int __acpi_processor_start(struct acpi_device *device)
acpi_processor_load_module(pr);
#endif
acpi_processor_get_throttling_info(pr);
acpi_processor_get_limit_info(pr);
if (pr->flags.throttling)
pr->flags.limit = 1;
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
acpi_processor_power_init(pr);

View File

@ -164,17 +164,12 @@ static void acpi_processor_ppc_ost(acpi_handle handle, int status)
{.type = ACPI_TYPE_INTEGER,},
};
struct acpi_object_list arg_list = {2, params};
acpi_handle temp;
params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
params[1].integer.value = status;
/* when there is no _OST , skip it */
if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp)))
return;
acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
return;
if (acpi_has_method(handle, "_OST")) {
params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
params[1].integer.value = status;
acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
}
}
int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
@ -468,14 +463,11 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
int acpi_processor_get_performance_info(struct acpi_processor *pr)
{
int result = 0;
acpi_status status = AE_OK;
acpi_handle handle = NULL;
if (!pr || !pr->performance || !pr->handle)
return -EINVAL;
status = acpi_get_handle(pr->handle, "_PCT", &handle);
if (ACPI_FAILURE(status)) {
if (!acpi_has_method(pr->handle, "_PCT")) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"ACPI-based processor performance control unavailable\n"));
return -ENODEV;
@ -501,7 +493,7 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr)
*/
update_bios:
#ifdef CONFIG_X86
if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
if (acpi_has_method(pr->handle, "_PPC")) {
if(boot_cpu_has(X86_FEATURE_EST))
printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
"frequency support\n");

View File

@ -186,18 +186,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
#endif
int acpi_processor_get_limit_info(struct acpi_processor *pr)
{
if (!pr)
return -EINVAL;
if (pr->flags.throttling)
pr->flags.limit = 1;
return 0;
}
/* thermal coolign device callbacks */
static int acpi_processor_max_state(struct acpi_processor *pr)
{

View File

@ -505,14 +505,12 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
void *preproc_data)
{
struct res_proc_context c;
acpi_handle not_used;
acpi_status status;
if (!adev || !adev->handle || !list_empty(list))
return -EINVAL;
status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, &not_used);
if (ACPI_FAILURE(status))
if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
return 0;
c.list = list;

View File

@ -873,14 +873,9 @@ static void acpi_sbs_callback(void *context)
u8 saved_charger_state = sbs->charger_present;
u8 saved_battery_state;
acpi_ac_get_present(sbs);
if (sbs->charger_present != saved_charger_state) {
#ifdef CONFIG_ACPI_PROC_EVENT
acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
ACPI_SBS_NOTIFY_STATUS,
sbs->charger_present);
#endif
if (sbs->charger_present != saved_charger_state)
kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
}
if (sbs->manager_present) {
for (id = 0; id < MAX_SBS_BAT; ++id) {
if (!(sbs->batteries_supported & (1 << id)))
@ -890,12 +885,6 @@ static void acpi_sbs_callback(void *context)
acpi_battery_read(bat);
if (saved_battery_state == bat->present)
continue;
#ifdef CONFIG_ACPI_PROC_EVENT
acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
bat->name,
ACPI_SBS_NOTIFY_STATUS,
bat->present);
#endif
kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
}
}

View File

@ -193,9 +193,6 @@ static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl,
static int acpi_scan_hot_remove(struct acpi_device *device)
{
acpi_handle handle = device->handle;
acpi_handle not_used;
struct acpi_object_list arg_list;
union acpi_object arg;
struct device *errdev;
acpi_status status;
unsigned long long sta;
@ -258,32 +255,15 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
put_device(&device->dev);
device = NULL;
if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &not_used))) {
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 0;
acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
}
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 1;
acpi_evaluate_lck(handle, 0);
/*
* TBD: _EJD support.
*/
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status)) {
if (status == AE_NOT_FOUND) {
return -ENODEV;
} else {
acpi_handle_warn(handle, "Eject failed (0x%x)\n",
status);
return -EIO;
}
}
status = acpi_evaluate_ej0(handle);
if (status == AE_NOT_FOUND)
return -ENODEV;
else if (ACPI_FAILURE(status))
return -EIO;
/*
* Verify if eject was indeed successful. If not, log an error
@ -307,6 +287,7 @@ static void acpi_bus_device_eject(void *context)
struct acpi_device *device = NULL;
struct acpi_scan_handler *handler;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
int error;
mutex_lock(&acpi_scan_lock);
@ -321,17 +302,13 @@ static void acpi_bus_device_eject(void *context)
}
acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
if (handler->hotplug.mode == AHM_CONTAINER) {
device->flags.eject_pending = true;
if (handler->hotplug.mode == AHM_CONTAINER)
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
} else {
int error;
get_device(&device->dev);
error = acpi_scan_hot_remove(device);
if (error)
goto err_out;
}
get_device(&device->dev);
error = acpi_scan_hot_remove(device);
if (error)
goto err_out;
out:
mutex_unlock(&acpi_scan_lock);
@ -516,7 +493,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
struct acpi_eject_event *ej_event;
acpi_object_type not_used;
acpi_status status;
u32 ost_source;
int ret;
if (!count || buf[0] != '1')
@ -530,43 +506,28 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
return -ENODEV;
mutex_lock(&acpi_scan_lock);
if (acpi_device->flags.eject_pending) {
/* ACPI eject notification event. */
ost_source = ACPI_NOTIFY_EJECT_REQUEST;
acpi_device->flags.eject_pending = 0;
} else {
/* Eject initiated by user space. */
ost_source = ACPI_OST_EC_OSPM_EJECT;
}
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
if (!ej_event) {
ret = -ENOMEM;
goto err_out;
}
acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source,
acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
ej_event->device = acpi_device;
ej_event->event = ost_source;
ej_event->event = ACPI_OST_EC_OSPM_EJECT;
get_device(&acpi_device->dev);
status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
if (ACPI_FAILURE(status)) {
put_device(&acpi_device->dev);
kfree(ej_event);
ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
goto err_out;
}
ret = count;
if (ACPI_SUCCESS(status))
return count;
out:
mutex_unlock(&acpi_scan_lock);
return ret;
put_device(&acpi_device->dev);
kfree(ej_event);
ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
err_out:
acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source,
acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
goto out;
return ret;
}
static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
@ -654,7 +615,6 @@ static int acpi_device_setup_files(struct acpi_device *dev)
{
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
acpi_status status;
acpi_handle temp;
unsigned long long sun;
int result = 0;
@ -680,8 +640,7 @@ static int acpi_device_setup_files(struct acpi_device *dev)
/*
* If device has _STR, 'description' file is created
*/
status = acpi_get_handle(dev->handle, "_STR", &temp);
if (ACPI_SUCCESS(status)) {
if (acpi_has_method(dev->handle, "_STR")) {
status = acpi_evaluate_object(dev->handle, "_STR",
NULL, &buffer);
if (ACPI_FAILURE(status))
@ -711,8 +670,7 @@ static int acpi_device_setup_files(struct acpi_device *dev)
* If device has _EJ0, 'eject' file is created that is used to trigger
* hot-removal function from userland.
*/
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status)) {
if (acpi_has_method(dev->handle, "_EJ0")) {
result = device_create_file(&dev->dev, &dev_attr_eject);
if (result)
return result;
@ -734,9 +692,6 @@ end:
static void acpi_device_remove_files(struct acpi_device *dev)
{
acpi_status status;
acpi_handle temp;
if (dev->flags.power_manageable) {
device_remove_file(&dev->dev, &dev_attr_power_state);
if (dev->power.flags.power_resources)
@ -747,20 +702,17 @@ static void acpi_device_remove_files(struct acpi_device *dev)
/*
* If device has _STR, remove 'description' file
*/
status = acpi_get_handle(dev->handle, "_STR", &temp);
if (ACPI_SUCCESS(status)) {
if (acpi_has_method(dev->handle, "_STR")) {
kfree(dev->pnp.str_obj);
device_remove_file(&dev->dev, &dev_attr_description);
}
/*
* If device has _EJ0, remove 'eject' file.
*/
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
if (acpi_has_method(dev->handle, "_EJ0"))
device_remove_file(&dev->dev, &dev_attr_eject);
status = acpi_get_handle(dev->handle, "_SUN", &temp);
if (ACPI_SUCCESS(status))
if (acpi_has_method(dev->handle, "_SUN"))
device_remove_file(&dev->dev, &dev_attr_sun);
if (dev->pnp.unique_id)
@ -999,6 +951,28 @@ struct bus_type acpi_bus_type = {
.uevent = acpi_device_uevent,
};
static void acpi_bus_data_handler(acpi_handle handle, void *context)
{
/* Intentionally empty. */
}
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
{
acpi_status status;
if (!device)
return -EINVAL;
status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
if (ACPI_FAILURE(status) || !*device) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
handle));
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL_GPL(acpi_bus_get_device);
int acpi_device_add(struct acpi_device *device,
void (*release)(struct device *))
{
@ -1210,14 +1184,6 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
}
EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
void acpi_bus_data_handler(acpi_handle handle, void *context)
{
/* TBD */
return;
}
static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
struct acpi_device_wakeup *wakeup)
{
@ -1336,13 +1302,10 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
{
acpi_handle temp;
acpi_status status = 0;
int err;
/* Presence of _PRW indicates wake capable */
status = acpi_get_handle(device->handle, "_PRW", &temp);
if (ACPI_FAILURE(status))
if (!acpi_has_method(device->handle, "_PRW"))
return;
err = acpi_bus_extract_wakeup_device_power_package(device->handle,
@ -1372,7 +1335,6 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
struct acpi_device_power_state *ps = &device->power.states[state];
char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' };
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_handle handle;
acpi_status status;
INIT_LIST_HEAD(&ps->resources);
@ -1395,8 +1357,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
/* Evaluate "_PSx" to see if we can do explicit sets */
pathname[2] = 'S';
status = acpi_get_handle(device->handle, pathname, &handle);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, pathname))
ps->flags.explicit_set = 1;
/*
@ -1415,28 +1376,21 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
static void acpi_bus_get_power_flags(struct acpi_device *device)
{
acpi_status status;
acpi_handle handle;
u32 i;
/* Presence of _PS0|_PR0 indicates 'power manageable' */
status = acpi_get_handle(device->handle, "_PS0", &handle);
if (ACPI_FAILURE(status)) {
status = acpi_get_handle(device->handle, "_PR0", &handle);
if (ACPI_FAILURE(status))
return;
}
if (!acpi_has_method(device->handle, "_PS0") &&
!acpi_has_method(device->handle, "_PR0"))
return;
device->flags.power_manageable = 1;
/*
* Power Management Flags
*/
status = acpi_get_handle(device->handle, "_PSC", &handle);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, "_PSC"))
device->power.flags.explicit_get = 1;
status = acpi_get_handle(device->handle, "_IRC", &handle);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, "_IRC"))
device->power.flags.inrush_current = 1;
/*
@ -1450,8 +1404,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
/* Set defaults for D0 and D3 states (always valid) */
device->power.states[ACPI_STATE_D0].flags.valid = 1;
device->power.states[ACPI_STATE_D0].power = 100;
device->power.states[ACPI_STATE_D3].flags.valid = 1;
device->power.states[ACPI_STATE_D3].power = 0;
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
device->power.states[ACPI_STATE_D3_COLD].power = 0;
/* Set D3cold's explicit_set flag if _PS3 exists. */
if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
@ -1470,28 +1424,18 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
static void acpi_bus_get_flags(struct acpi_device *device)
{
acpi_status status = AE_OK;
acpi_handle temp = NULL;
/* Presence of _STA indicates 'dynamic_status' */
status = acpi_get_handle(device->handle, "_STA", &temp);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, "_STA"))
device->flags.dynamic_status = 1;
/* Presence of _RMV indicates 'removable' */
status = acpi_get_handle(device->handle, "_RMV", &temp);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, "_RMV"))
device->flags.removable = 1;
/* Presence of _EJD|_EJ0 indicates 'ejectable' */
status = acpi_get_handle(device->handle, "_EJD", &temp);
if (ACPI_SUCCESS(status))
if (acpi_has_method(device->handle, "_EJD") ||
acpi_has_method(device->handle, "_EJ0"))
device->flags.ejectable = 1;
else {
status = acpi_get_handle(device->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
device->flags.ejectable = 1;
}
}
static void acpi_device_get_busid(struct acpi_device *device)
@ -1532,47 +1476,46 @@ static void acpi_device_get_busid(struct acpi_device *device)
}
}
/*
* acpi_ata_match - see if an acpi object is an ATA device
*
* If an acpi object has one of the ACPI ATA methods defined,
* then we can safely call it an ATA device.
*/
bool acpi_ata_match(acpi_handle handle)
{
return acpi_has_method(handle, "_GTF") ||
acpi_has_method(handle, "_GTM") ||
acpi_has_method(handle, "_STM") ||
acpi_has_method(handle, "_SDD");
}
/*
* acpi_bay_match - see if an acpi object is an ejectable driver bay
*
* If an acpi object is ejectable and has one of the ACPI ATA methods defined,
* then we can safely call it an ejectable drive bay
*/
static int acpi_bay_match(acpi_handle handle)
bool acpi_bay_match(acpi_handle handle)
{
acpi_status status;
acpi_handle tmp;
acpi_handle phandle;
status = acpi_get_handle(handle, "_EJ0", &tmp);
if (ACPI_FAILURE(status))
return -ENODEV;
if (!acpi_has_method(handle, "_EJ0"))
return false;
if (acpi_ata_match(handle))
return true;
if (ACPI_FAILURE(acpi_get_parent(handle, &phandle)))
return false;
if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
return 0;
if (acpi_get_parent(handle, &phandle))
return -ENODEV;
if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) ||
(ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp))))
return 0;
return -ENODEV;
return acpi_ata_match(phandle);
}
/*
* acpi_dock_match - see if an acpi object has a _DCK method
*/
static int acpi_dock_match(acpi_handle handle)
bool acpi_dock_match(acpi_handle handle)
{
acpi_handle tmp;
return acpi_get_handle(handle, "_DCK", &tmp);
return acpi_has_method(handle, "_DCK");
}
const char *acpi_device_hid(struct acpi_device *device)
@ -1610,34 +1553,26 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id)
* lacks the SMBUS01 HID and the methods do not have the necessary "_"
* prefix. Work around this.
*/
static int acpi_ibm_smbus_match(acpi_handle handle)
static bool acpi_ibm_smbus_match(acpi_handle handle)
{
acpi_handle h_dummy;
struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
int result;
char node_name[ACPI_PATH_SEGMENT_LENGTH];
struct acpi_buffer path = { sizeof(node_name), node_name };
if (!dmi_name_in_vendors("IBM"))
return -ENODEV;
return false;
/* Look for SMBS object */
result = acpi_get_name(handle, ACPI_SINGLE_NAME, &path);
if (result)
return result;
if (strcmp("SMBS", path.pointer)) {
result = -ENODEV;
goto out;
}
if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &path)) ||
strcmp("SMBS", path.pointer))
return false;
/* Does it have the necessary (but misnamed) methods? */
result = -ENODEV;
if (ACPI_SUCCESS(acpi_get_handle(handle, "SBI", &h_dummy)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "SBR", &h_dummy)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "SBW", &h_dummy)))
result = 0;
out:
kfree(path.pointer);
return result;
if (acpi_has_method(handle, "SBI") &&
acpi_has_method(handle, "SBR") &&
acpi_has_method(handle, "SBW"))
return true;
return false;
}
static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
@ -1685,11 +1620,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
*/
if (acpi_is_video_device(handle))
acpi_add_id(pnp, ACPI_VIDEO_HID);
else if (ACPI_SUCCESS(acpi_bay_match(handle)))
else if (acpi_bay_match(handle))
acpi_add_id(pnp, ACPI_BAY_HID);
else if (ACPI_SUCCESS(acpi_dock_match(handle)))
else if (acpi_dock_match(handle))
acpi_add_id(pnp, ACPI_DOCK_HID);
else if (!acpi_ibm_smbus_match(handle))
else if (acpi_ibm_smbus_match(handle))
acpi_add_id(pnp, ACPI_SMBUS_IBM_HID);
else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) {
acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
@ -1900,7 +1835,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
struct acpi_device *device = NULL;
int type;
unsigned long long sta;
acpi_status status;
int result;
acpi_bus_get_device(handle, &device);
@ -1921,10 +1855,8 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
!(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
struct acpi_device_wakeup wakeup;
acpi_handle temp;
status = acpi_get_handle(handle, "_PRW", &temp);
if (ACPI_SUCCESS(status)) {
if (acpi_has_method(handle, "_PRW")) {
acpi_bus_extract_wakeup_device_power_package(handle,
&wakeup);
acpi_power_resources_list_free(&wakeup.resources);

View File

@ -31,12 +31,9 @@ static u8 sleep_states[ACPI_S_STATE_COUNT];
static void acpi_sleep_tts_switch(u32 acpi_state)
{
union acpi_object in_arg = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &in_arg };
acpi_status status = AE_OK;
acpi_status status;
in_arg.integer.value = acpi_state;
status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL);
status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
/*
* OS can't evaluate the _TTS object correctly. Some warning
@ -141,7 +138,7 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d)
return 0;
}
static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
{
.callback = init_old_suspend_ordering,
.ident = "Abit KN9 (nForce4 variant)",
@ -423,10 +420,21 @@ static void acpi_pm_finish(void)
}
/**
* acpi_pm_end - Finish up suspend sequence.
* acpi_pm_start - Start system PM transition.
*/
static void acpi_pm_start(u32 acpi_state)
{
acpi_target_sleep_state = acpi_state;
acpi_sleep_tts_switch(acpi_target_sleep_state);
acpi_scan_lock_acquire();
}
/**
* acpi_pm_end - Finish up system PM transition.
*/
static void acpi_pm_end(void)
{
acpi_scan_lock_release();
/*
* This is necessary in case acpi_pm_finish() is not called during a
* failing transition to a sleep state.
@ -454,21 +462,19 @@ static u32 acpi_suspend_states[] = {
static int acpi_suspend_begin(suspend_state_t pm_state)
{
u32 acpi_state = acpi_suspend_states[pm_state];
int error = 0;
int error;
error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();
if (error)
return error;
if (sleep_states[acpi_state]) {
acpi_target_sleep_state = acpi_state;
acpi_sleep_tts_switch(acpi_target_sleep_state);
} else {
printk(KERN_ERR "ACPI does not support this state: %d\n",
pm_state);
error = -ENOSYS;
if (!sleep_states[acpi_state]) {
pr_err("ACPI does not support sleep state S%u\n", acpi_state);
return -ENOSYS;
}
return error;
acpi_pm_start(acpi_state);
return 0;
}
/**
@ -634,10 +640,8 @@ static int acpi_hibernation_begin(void)
int error;
error = nvs_nosave ? 0 : suspend_nvs_alloc();
if (!error) {
acpi_target_sleep_state = ACPI_STATE_S4;
acpi_sleep_tts_switch(acpi_target_sleep_state);
}
if (!error)
acpi_pm_start(ACPI_STATE_S4);
return error;
}
@ -716,8 +720,10 @@ static int acpi_hibernation_begin_old(void)
if (!error) {
if (!nvs_nosave)
error = suspend_nvs_alloc();
if (!error)
if (!error) {
acpi_target_sleep_state = ACPI_STATE_S4;
acpi_scan_lock_acquire();
}
}
return error;
}

View File

@ -50,11 +50,6 @@
#define ACPI_THERMAL_CLASS "thermal_zone"
#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
#define ACPI_THERMAL_FILE_STATE "state"
#define ACPI_THERMAL_FILE_TEMPERATURE "temperature"
#define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points"
#define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode"
#define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency"
#define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
#define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81
#define ACPI_THERMAL_NOTIFY_DEVICES 0x82
@ -190,7 +185,6 @@ struct acpi_thermal {
struct thermal_zone_device *thermal_zone;
int tz_enabled;
int kelvin_offset;
struct mutex lock;
};
/* --------------------------------------------------------------------------
@ -239,26 +233,16 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
{
acpi_status status = AE_OK;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
acpi_handle handle = NULL;
if (!tz)
return -EINVAL;
status = acpi_get_handle(tz->device->handle, "_SCP", &handle);
if (ACPI_FAILURE(status)) {
if (!acpi_has_method(tz->device->handle, "_SCP")) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
return -ENODEV;
}
arg0.integer.value = mode;
status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
if (ACPI_FAILURE(status))
} else if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle,
"_SCP", mode))) {
return -ENODEV;
}
return 0;
}
@ -491,14 +475,14 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
break;
}
if (flag & ACPI_TRIPS_DEVICES) {
memset(&devices, 0, sizeof(struct acpi_handle_list));
if ((flag & ACPI_TRIPS_DEVICES)
&& acpi_has_method(tz->device->handle, "_TZD")) {
memset(&devices, 0, sizeof(devices));
status = acpi_evaluate_reference(tz->device->handle, "_TZD",
NULL, &devices);
if (memcmp(&tz->devices, &devices,
sizeof(struct acpi_handle_list))) {
memcpy(&tz->devices, &devices,
sizeof(struct acpi_handle_list));
if (ACPI_SUCCESS(status)
&& memcmp(&tz->devices, &devices, sizeof(devices))) {
tz->devices = devices;
ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
}
}
@ -769,7 +753,6 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip,
else
return 0;
acpi_bus_generate_proc_event(tz->device, type, 1);
acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
dev_name(&tz->device->dev), type, 1);
@ -850,12 +833,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
if (ACPI_SUCCESS(status) && (dev == device)) {
if (bind)
result = thermal_zone_bind_cooling_device
(thermal, -1, cdev,
THERMAL_NO_LIMIT,
(thermal, THERMAL_TRIPS_NONE,
cdev, THERMAL_NO_LIMIT,
THERMAL_NO_LIMIT);
else
result = thermal_zone_unbind_cooling_device
(thermal, -1, cdev);
(thermal, THERMAL_TRIPS_NONE,
cdev);
if (result)
goto failed;
}
@ -980,14 +964,12 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
case ACPI_THERMAL_NOTIFY_THRESHOLDS:
acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
acpi_thermal_check(tz);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
case ACPI_THERMAL_NOTIFY_DEVICES:
acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
acpi_thermal_check(tz);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
@ -1101,8 +1083,6 @@ static int acpi_thermal_add(struct acpi_device *device)
strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
device->driver_data = tz;
mutex_init(&tz->lock);
result = acpi_thermal_get_info(tz);
if (result)
@ -1135,7 +1115,6 @@ static int acpi_thermal_remove(struct acpi_device *device)
tz = acpi_driver_data(device);
acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock);
kfree(tz);
return 0;
}

View File

@ -495,3 +495,73 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
kfree(buffer.pointer);
}
EXPORT_SYMBOL(acpi_handle_printk);
/**
* acpi_has_method: Check whether @handle has a method named @name
* @handle: ACPI device handle
* @name: name of object or method
*
* Check whether @handle has a method named @name.
*/
bool acpi_has_method(acpi_handle handle, char *name)
{
acpi_handle tmp;
return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp));
}
EXPORT_SYMBOL(acpi_has_method);
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
u64 arg)
{
union acpi_object obj = { .type = ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, };
obj.integer.value = arg;
return acpi_evaluate_object(handle, method, &arg_list, NULL);
}
EXPORT_SYMBOL(acpi_execute_simple_method);
/**
* acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
* @handle: ACPI device handle
*
* Evaluate device's _EJ0 method for hotplug operations.
*/
acpi_status acpi_evaluate_ej0(acpi_handle handle)
{
acpi_status status;
status = acpi_execute_simple_method(handle, "_EJ0", 1);
if (status == AE_NOT_FOUND)
acpi_handle_warn(handle, "No _EJ0 support for device\n");
else if (ACPI_FAILURE(status))
acpi_handle_warn(handle, "Eject failed (0x%x)\n", status);
return status;
}
/**
* acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device
* @handle: ACPI device handle
* @lock: lock device if non-zero, otherwise unlock device
*
* Evaluate device's _LCK method if present to lock/unlock device
*/
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
{
acpi_status status;
status = acpi_execute_simple_method(handle, "_LCK", !!lock);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
if (lock)
acpi_handle_warn(handle,
"Locking device failed (0x%x)\n", status);
else
acpi_handle_warn(handle,
"Unlocking device failed (0x%x)\n", status);
}
return status;
}

View File

@ -1,5 +1,5 @@
/*
* video.c - ACPI Video Driver ($Revision:$)
* video.c - ACPI Video Driver
*
* Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
* Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
@ -88,7 +88,7 @@ module_param(allow_duplicates, bool, 0644);
static bool use_bios_initial_backlight = 1;
module_param(use_bios_initial_backlight, bool, 0644);
static int register_count = 0;
static int register_count;
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
@ -118,26 +118,26 @@ struct acpi_video_bus_flags {
};
struct acpi_video_bus_cap {
u8 _DOS:1; /*Enable/Disable output switching */
u8 _DOD:1; /*Enumerate all devices attached to display adapter */
u8 _ROM:1; /*Get ROM Data */
u8 _GPD:1; /*Get POST Device */
u8 _SPD:1; /*Set POST Device */
u8 _VPO:1; /*Video POST Options */
u8 _DOS:1; /* Enable/Disable output switching */
u8 _DOD:1; /* Enumerate all devices attached to display adapter */
u8 _ROM:1; /* Get ROM Data */
u8 _GPD:1; /* Get POST Device */
u8 _SPD:1; /* Set POST Device */
u8 _VPO:1; /* Video POST Options */
u8 reserved:2;
};
struct acpi_video_device_attrib {
u32 display_index:4; /* A zero-based instance of the Display */
u32 display_port_attachment:4; /*This field differentiates the display type */
u32 display_type:4; /*Describe the specific type in use */
u32 vendor_specific:4; /*Chipset Vendor Specific */
u32 bios_can_detect:1; /*BIOS can detect the device */
u32 depend_on_vga:1; /*Non-VGA output device whose power is related to
u32 display_port_attachment:4; /* This field differentiates the display type */
u32 display_type:4; /* Describe the specific type in use */
u32 vendor_specific:4; /* Chipset Vendor Specific */
u32 bios_can_detect:1; /* BIOS can detect the device */
u32 depend_on_vga:1; /* Non-VGA output device whose power is related to
the VGA device. */
u32 pipe_id:3; /*For VGA multiple-head devices. */
u32 reserved:10; /*Must be 0 */
u32 device_id_scheme:1; /*Device ID Scheme */
u32 pipe_id:3; /* For VGA multiple-head devices. */
u32 reserved:10; /* Must be 0 */
u32 device_id_scheme:1; /* Device ID Scheme */
};
struct acpi_video_enumerated_device {
@ -174,19 +174,17 @@ struct acpi_video_device_flags {
};
struct acpi_video_device_cap {
u8 _ADR:1; /*Return the unique ID */
u8 _BCL:1; /*Query list of brightness control levels supported */
u8 _BCM:1; /*Set the brightness level */
u8 _ADR:1; /* Return the unique ID */
u8 _BCL:1; /* Query list of brightness control levels supported */
u8 _BCM:1; /* Set the brightness level */
u8 _BQC:1; /* Get current brightness level */
u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
u8 _DDC:1; /*Return the EDID for this device */
u8 _DDC:1; /* Return the EDID for this device */
};
struct acpi_video_brightness_flags {
u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/
u8 _BCL_use_index:1; /* levels in _BCL are index values */
u8 _BCM_use_index:1; /* input of _BCM is an index value */
u8 _BCL_reversed:1; /* _BCL package is in a reversed order */
u8 _BQC_use_index:1; /* _BQC returns an index value */
};
@ -231,21 +229,22 @@ static int acpi_video_get_next_level(struct acpi_video_device *device,
static int acpi_video_switch_brightness(struct acpi_video_device *device,
int event);
/*backlight device sysfs support*/
/* backlight device sysfs support */
static int acpi_video_get_brightness(struct backlight_device *bd)
{
unsigned long long cur_level;
int i;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
struct acpi_video_device *vd = bl_get_data(bd);
if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))
return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level)
/* The first two entries are special - see page 575
of the ACPI spec 3.0 */
return i-2;
/*
* The first two entries are special - see page 575
* of the ACPI spec 3.0
*/
return i - 2;
}
return 0;
}
@ -253,8 +252,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
static int acpi_video_set_brightness(struct backlight_device *bd)
{
int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
struct acpi_video_device *vd = bl_get_data(bd);
return acpi_video_device_lcd_set_level(vd,
vd->brightness->levels[request_level]);
@ -302,11 +300,11 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st
struct acpi_video_device *video = acpi_driver_data(device);
int level;
if ( state >= video->brightness->count - 2)
if (state >= video->brightness->count - 2)
return -EINVAL;
state = video->brightness->count - state;
level = video->brightness->levels[state -1];
level = video->brightness->levels[state - 1];
return acpi_video_device_lcd_set_level(video, level);
}
@ -316,9 +314,11 @@ static const struct thermal_cooling_device_ops video_cooling_ops = {
.set_cur_state = video_set_cur_state,
};
/* --------------------------------------------------------------------------
Video Management
-------------------------------------------------------------------------- */
/*
* --------------------------------------------------------------------------
* Video Management
* --------------------------------------------------------------------------
*/
static int
acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
@ -345,7 +345,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
return 0;
err:
err:
kfree(buffer.pointer);
return status;
@ -355,14 +355,10 @@ static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
int status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
int state;
arg0.integer.value = level;
status = acpi_evaluate_object(device->dev->handle, "_BCM",
&args, NULL);
status = acpi_execute_simple_method(device->dev->handle,
"_BCM", level);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
return -EIO;
@ -546,7 +542,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
if (device->brightness->levels[i] == *level) {
device->brightness->curr = *level;
return 0;
}
}
/*
* BQC returned an invalid level.
* Stop using it.
@ -556,7 +552,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
buf));
device->cap._BQC = device->cap._BCQ = 0;
} else {
/* Fixme:
/*
* Fixme:
* should we return an error or ignore this failure?
* dev->brightness->curr is a cached value which stores
* the correct current backlight level in most cases.
@ -615,8 +612,8 @@ acpi_video_device_EDID(struct acpi_video_device *device,
/*
* Arg:
* video : video bus device pointer
* bios_flag :
* video : video bus device pointer
* bios_flag :
* 0. The system BIOS should NOT automatically switch(toggle)
* the active display output.
* 1. The system BIOS should automatically switch (toggle) the
@ -628,9 +625,9 @@ acpi_video_device_EDID(struct acpi_video_device *device,
* lcd_flag :
* 0. The system BIOS should automatically control the brightness level
* of the LCD when the power changes from AC to DC
* 1. The system BIOS should NOT automatically control the brightness
* 1. The system BIOS should NOT automatically control the brightness
* level of the LCD when the power changes from AC to DC.
* Return Value:
* Return Value:
* -EINVAL wrong arg.
*/
@ -638,18 +635,15 @@ static int
acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
{
acpi_status status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
if (!video->cap._DOS)
return 0;
if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
return -EINVAL;
arg0.integer.value = (lcd_flag << 2) | bios_flag;
video->dos_setting = arg0.integer.value;
status = acpi_evaluate_object(video->device->handle, "_DOS",
&args, NULL);
video->dos_setting = (lcd_flag << 2) | bios_flag;
status = acpi_execute_simple_method(video->device->handle, "_DOS",
(lcd_flag << 2) | bios_flag);
if (ACPI_FAILURE(status))
return -EIO;
@ -717,8 +711,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
/*
* Arg:
* device : video output device (LCD, CRT, ..)
* Arg:
* device : video output device (LCD, CRT, ..)
*
* Return Value:
* Maximum brightness level
@ -806,16 +800,6 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br->count = count;
device->brightness = br;
/* Check the input/output of _BQC/_BCL/_BCM */
if ((max_level < 100) && (max_level <= (count - 2)))
br->flags._BCL_use_index = 1;
/*
* _BCM is always consistent with _BCL,
* at least for all the laptops we have ever seen.
*/
br->flags._BCM_use_index = br->flags._BCL_use_index;
/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
br->curr = level = max_level;
@ -877,7 +861,7 @@ out:
* device : video output device (LCD, CRT, ..)
*
* Return Value:
* None
* None
*
* Find out all required AML methods defined under the output
* device.
@ -885,28 +869,21 @@ out:
static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
acpi_handle h_dummy1;
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
if (acpi_has_method(device->dev->handle, "_ADR"))
device->cap._ADR = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
if (acpi_has_method(device->dev->handle, "_BCL"))
device->cap._BCL = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
if (acpi_has_method(device->dev->handle, "_BCM"))
device->cap._BCM = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
if (acpi_has_method(device->dev->handle, "_BQC")) {
device->cap._BQC = 1;
else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
&h_dummy1))) {
} else if (acpi_has_method(device->dev->handle, "_BCQ")) {
printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
device->cap._BCQ = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
if (acpi_has_method(device->dev->handle, "_DDC"))
device->cap._DDC = 1;
}
if (acpi_video_backlight_support()) {
struct backlight_properties props;
@ -914,7 +891,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
acpi_handle acpi_parent;
struct device *parent = NULL;
int result;
static int count = 0;
static int count;
char *name;
result = acpi_video_init_brightness(device);
@ -983,37 +960,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
}
/*
* Arg:
* device : video output device (VGA)
* Arg:
* device : video output device (VGA)
*
* Return Value:
* None
* None
*
* Find out all required AML methods defined under the video bus device.
*/
static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
{
acpi_handle h_dummy1;
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_DOS"))
video->cap._DOS = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_DOD"))
video->cap._DOD = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_ROM"))
video->cap._ROM = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_GPD"))
video->cap._GPD = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_SPD"))
video->cap._SPD = 1;
}
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
if (acpi_has_method(video->device->handle, "_VPO"))
video->cap._VPO = 1;
}
}
/*
@ -1034,7 +1003,8 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
return -ENODEV;
pci_dev_put(dev);
/* Since there is no HID, CID and so on for VGA driver, we have
/*
* Since there is no HID, CID and so on for VGA driver, we have
* to check well known required nodes.
*/
@ -1064,12 +1034,14 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
return status;
}
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
/*
* --------------------------------------------------------------------------
* Driver Interface
* --------------------------------------------------------------------------
*/
/* device interface */
static struct acpi_video_device_attrib*
static struct acpi_video_device_attrib *
acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
{
struct acpi_video_enumerated_device *ids;
@ -1107,7 +1079,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
unsigned long long device_id;
int status, device_type;
struct acpi_video_device *data;
struct acpi_video_device_attrib* attribute;
struct acpi_video_device_attrib *attribute;
status =
acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
@ -1129,7 +1101,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
attribute = acpi_video_get_device_attr(video, device_id);
if((attribute != NULL) && attribute->device_id_scheme) {
if (attribute && attribute->device_id_scheme) {
switch (attribute->display_type) {
case ACPI_VIDEO_DISPLAY_CRT:
data->flags.crt = 1;
@ -1147,24 +1119,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
data->flags.unknown = 1;
break;
}
if(attribute->bios_can_detect)
if (attribute->bios_can_detect)
data->flags.bios = 1;
} else {
/* Check for legacy IDs */
device_type = acpi_video_get_device_type(video, device_id);
/* Ignore bits 16 and 18-20 */
switch (device_type & 0xffe2ffff) {
case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
data->flags.crt = 1;
break;
case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
data->flags.lcd = 1;
break;
case ACPI_VIDEO_DISPLAY_LEGACY_TV:
data->flags.tvout = 1;
break;
default:
data->flags.unknown = 1;
case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
data->flags.crt = 1;
break;
case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
data->flags.lcd = 1;
break;
case ACPI_VIDEO_DISPLAY_LEGACY_TV:
data->flags.tvout = 1;
break;
default:
data->flags.unknown = 1;
}
}
@ -1187,12 +1159,12 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
/*
* Arg:
* video : video bus device
* video : video bus device
*
* Return:
* none
*
* Enumerate the video device list of the video bus,
* none
*
* Enumerate the video device list of the video bus,
* bind the ids with the corresponding video devices
* under the video bus.
*/
@ -1211,13 +1183,13 @@ static void acpi_video_device_rebind(struct acpi_video_bus *video)
/*
* Arg:
* video : video bus device
* device : video output device under the video
* bus
* video : video bus device
* device : video output device under the video
* bus
*
* Return:
* none
*
* none
*
* Bind the ids with the corresponding video devices
* under the video bus.
*/
@ -1240,11 +1212,11 @@ acpi_video_device_bind(struct acpi_video_bus *video,
/*
* Arg:
* video : video bus device
* video : video bus device
*
* Return:
* < 0 : error
*
* < 0 : error
*
* Call _DOD to enumerate all devices attached to display adapter
*
*/
@ -1305,7 +1277,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
video->attached_array = active_list;
video->attached_count = count;
out:
out:
kfree(buffer.pointer);
return status;
}
@ -1572,7 +1544,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
switch (event) {
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
* most likely via hotkey. */
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_SWITCHVIDEOMODE;
break;
@ -1580,20 +1551,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
* connector. */
acpi_video_device_enumerate(video);
acpi_video_device_rebind(video);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_VIDEO_NEXT;
break;
case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_VIDEO_PREV;
break;
@ -1636,31 +1603,26 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
if (brightness_switch_enabled)
acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_BRIGHTNESS_CYCLE;
break;
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
if (brightness_switch_enabled)
acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_BRIGHTNESSUP;
break;
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
if (brightness_switch_enabled)
acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_BRIGHTNESSDOWN;
break;
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
if (brightness_switch_enabled)
acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_BRIGHTNESS_ZERO;
break;
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
if (brightness_switch_enabled)
acpi_video_switch_brightness(video_device, event);
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_DISPLAY_OFF;
break;
default:
@ -1760,7 +1722,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
if (!strcmp(device->pnp.bus_id, "VID")) {
if (instance)
device->pnp.bus_id[3] = '0' + instance;
instance ++;
instance++;
}
/* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
if (!strcmp(device->pnp.bus_id, "VGA")) {

View File

@ -53,14 +53,13 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
void **retyurn_value)
{
long *cap = context;
acpi_handle h_dummy;
if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
if (acpi_has_method(handle, "_BCM") &&
acpi_has_method(handle, "_BCL")) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
if (!acpi_has_method(handle, "_BQC"))
printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
"cannot determine initial brightness\n");
/* We have backlight support, no need to scan further */
@ -79,22 +78,20 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
*/
long acpi_is_video_device(acpi_handle handle)
{
acpi_handle h_dummy;
long video_caps = 0;
/* Is this device able to support video switching ? */
if (ACPI_SUCCESS(acpi_get_handle(handle, "_DOD", &h_dummy)) ||
ACPI_SUCCESS(acpi_get_handle(handle, "_DOS", &h_dummy)))
if (acpi_has_method(handle, "_DOD") || acpi_has_method(handle, "_DOS"))
video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
/* Is this device able to retrieve a video ROM ? */
if (ACPI_SUCCESS(acpi_get_handle(handle, "_ROM", &h_dummy)))
if (acpi_has_method(handle, "_ROM"))
video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
/* Is this device able to configure which video head to be POSTed ? */
if (ACPI_SUCCESS(acpi_get_handle(handle, "_VPO", &h_dummy)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "_GPD", &h_dummy)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "_SPD", &h_dummy)))
if (acpi_has_method(handle, "_VPO") &&
acpi_has_method(handle, "_GPD") &&
acpi_has_method(handle, "_SPD"))
video_caps |= ACPI_VIDEO_DEVICE_POSTING;
/* Only check for backlight functionality if one of the above hit. */

View File

@ -947,11 +947,11 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
continue;
acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ?
ACPI_STATE_D0 : ACPI_STATE_D3);
ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
}
if (!(state.event & PM_EVENT_RESUME))
acpi_bus_set_power(port_handle, ACPI_STATE_D3);
acpi_bus_set_power(port_handle, ACPI_STATE_D3_COLD);
}
/**

View File

@ -50,6 +50,28 @@ static struct kobject *dev_kobj;
struct kobject *sysfs_dev_char_kobj;
struct kobject *sysfs_dev_block_kobj;
static DEFINE_MUTEX(device_hotplug_lock);
void lock_device_hotplug(void)
{
mutex_lock(&device_hotplug_lock);
}
void unlock_device_hotplug(void)
{
mutex_unlock(&device_hotplug_lock);
}
int lock_device_hotplug_sysfs(void)
{
if (mutex_trylock(&device_hotplug_lock))
return 0;
/* Avoid busy looping (5 ms of sleep should do). */
msleep(5);
return restart_syscall();
}
#ifdef CONFIG_BLOCK
static inline int device_is_not_partition(struct device *dev)
{
@ -407,9 +429,9 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr,
{
bool val;
lock_device_hotplug();
device_lock(dev);
val = !dev->offline;
unlock_device_hotplug();
device_unlock(dev);
return sprintf(buf, "%u\n", val);
}
@ -423,7 +445,10 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr,
if (ret < 0)
return ret;
lock_device_hotplug();
ret = lock_device_hotplug_sysfs();
if (ret)
return ret;
ret = val ? device_online(dev) : device_offline(dev);
unlock_device_hotplug();
return ret < 0 ? ret : count;
@ -1450,18 +1475,6 @@ int __init devices_init(void)
return -ENOMEM;
}
static DEFINE_MUTEX(device_hotplug_lock);
void lock_device_hotplug(void)
{
mutex_lock(&device_hotplug_lock);
}
void unlock_device_hotplug(void)
{
mutex_unlock(&device_hotplug_lock);
}
static int device_check_offline(struct device *dev, void *not_used)
{
int ret;

View File

@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include "base.h"
@ -293,6 +294,7 @@ int register_cpu(struct cpu *cpu, int num)
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
cpu->dev.of_node = of_get_cpu_node(num, NULL);
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent;
#endif

View File

@ -321,7 +321,9 @@ store_mem_state(struct device *dev,
struct memory_block *mem = to_memory_block(dev);
int ret, online_type;
lock_device_hotplug();
ret = lock_device_hotplug_sysfs();
if (ret)
return ret;
if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
online_type = ONLINE_KERNEL;

View File

@ -28,6 +28,7 @@
#include <linux/sched.h>
#include <linux/async.h>
#include <linux/suspend.h>
#include <trace/events/power.h>
#include <linux/cpuidle.h>
#include "../base.h"
#include "power.h"
@ -56,6 +57,30 @@ static pm_message_t pm_transition;
static int async_error;
static char *pm_verb(int event)
{
switch (event) {
case PM_EVENT_SUSPEND:
return "suspend";
case PM_EVENT_RESUME:
return "resume";
case PM_EVENT_FREEZE:
return "freeze";
case PM_EVENT_QUIESCE:
return "quiesce";
case PM_EVENT_HIBERNATE:
return "hibernate";
case PM_EVENT_THAW:
return "thaw";
case PM_EVENT_RESTORE:
return "restore";
case PM_EVENT_RECOVER:
return "recover";
default:
return "(unknown PM event)";
}
}
/**
* device_pm_sleep_init - Initialize system suspend-related device fields.
* @dev: Device object being initialized.
@ -172,16 +197,21 @@ static ktime_t initcall_debug_start(struct device *dev)
}
static void initcall_debug_report(struct device *dev, ktime_t calltime,
int error)
int error, pm_message_t state, char *info)
{
ktime_t delta, rettime;
ktime_t rettime;
s64 nsecs;
rettime = ktime_get();
nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
if (pm_print_times_enabled) {
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
error, (unsigned long long)ktime_to_ns(delta) >> 10);
error, (unsigned long long)nsecs >> 10);
}
trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event),
error);
}
/**
@ -309,30 +339,6 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat
return NULL;
}
static char *pm_verb(int event)
{
switch (event) {
case PM_EVENT_SUSPEND:
return "suspend";
case PM_EVENT_RESUME:
return "resume";
case PM_EVENT_FREEZE:
return "freeze";
case PM_EVENT_QUIESCE:
return "quiesce";
case PM_EVENT_HIBERNATE:
return "hibernate";
case PM_EVENT_THAW:
return "thaw";
case PM_EVENT_RESTORE:
return "restore";
case PM_EVENT_RECOVER:
return "recover";
default:
return "(unknown PM event)";
}
}
static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info)
{
dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
@ -379,7 +385,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
error = cb(dev);
suspend_report_result(cb, error);
initcall_debug_report(dev, calltime, error);
initcall_debug_report(dev, calltime, error, state, info);
return error;
}
@ -1027,7 +1033,8 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
* @cb: Suspend callback to execute.
*/
static int legacy_suspend(struct device *dev, pm_message_t state,
int (*cb)(struct device *dev, pm_message_t state))
int (*cb)(struct device *dev, pm_message_t state),
char *info)
{
int error;
ktime_t calltime;
@ -1037,7 +1044,7 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
error = cb(dev, state);
suspend_report_result(cb, error);
initcall_debug_report(dev, calltime, error);
initcall_debug_report(dev, calltime, error, state, info);
return error;
}
@ -1097,7 +1104,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
goto Run;
} else if (dev->class->suspend) {
pm_dev_dbg(dev, state, "legacy class ");
error = legacy_suspend(dev, state, dev->class->suspend);
error = legacy_suspend(dev, state, dev->class->suspend,
"legacy class ");
goto End;
}
}
@ -1108,7 +1116,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
callback = pm_op(dev->bus->pm, state);
} else if (dev->bus->suspend) {
pm_dev_dbg(dev, state, "legacy bus ");
error = legacy_suspend(dev, state, dev->bus->suspend);
error = legacy_suspend(dev, state, dev->bus->suspend,
"legacy bus ");
goto End;
}
}

View File

@ -460,6 +460,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
return 0;
}
EXPORT_SYMBOL_GPL(opp_add);
/**
* opp_set_availability() - helper to set the availability of an opp

View File

@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);
static void __init cci_ace_init_ports(void)
{
int port, ac, cpu;
u64 hwid;
const u32 *cell;
struct device_node *cpun, *cpus;
cpus = of_find_node_by_path("/cpus");
if (WARN(!cpus, "Missing cpus node, bailing out\n"))
return;
if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
ac = of_n_addr_cells(cpus);
int port, cpu;
struct device_node *cpun;
/*
* Port index look-up speeds up the function disabling ports by CPU,
@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
* The stashed index array is initialized for all possible CPUs
* at probe time.
*/
for_each_child_of_node(cpus, cpun) {
if (of_node_cmp(cpun->type, "cpu"))
continue;
cell = of_get_property(cpun, "reg", NULL);
if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
for_each_possible_cpu(cpu) {
/* too early to use cpu->of_node */
cpun = of_get_cpu_node(cpu, NULL);
if (WARN(!cpun, "Missing cpu device node\n"))
continue;
hwid = of_read_number(cell, ac);
cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
if (cpu < 0 || !cpu_possible(cpu))
continue;
port = __cci_ace_get_port(cpun, ACE_PORT);
if (port < 0)
continue;

View File

@ -876,11 +876,6 @@ found:
if (useinput)
sonypi_report_input_event(event);
#ifdef CONFIG_ACPI
if (sonypi_acpi_device)
acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
#endif
kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
sizeof(event), &sonypi_device.fifo_lock);
kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);

View File

@ -17,37 +17,47 @@ config ARM_DT_BL_CPUFREQ
big.LITTLE platform. This gets frequency tables from DT.
config ARM_EXYNOS_CPUFREQ
bool "SAMSUNG EXYNOS SoCs"
depends on ARCH_EXYNOS
bool
select CPU_FREQ_TABLE
default y
help
This adds the CPUFreq driver common part for Samsung
EXYNOS SoCs.
If in doubt, say N.
config ARM_EXYNOS4210_CPUFREQ
def_bool CPU_EXYNOS4210
bool "SAMSUNG EXYNOS4210"
depends on CPU_EXYNOS4210
default y
select ARM_EXYNOS_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS4210
SoC (S5PV310 or S5PC210).
If in doubt, say N.
config ARM_EXYNOS4X12_CPUFREQ
def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412)
bool "SAMSUNG EXYNOS4x12"
depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
default y
select ARM_EXYNOS_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS4X12
SoC (EXYNOS4212 or EXYNOS4412).
If in doubt, say N.
config ARM_EXYNOS5250_CPUFREQ
def_bool SOC_EXYNOS5250
bool "SAMSUNG EXYNOS5250"
depends on SOC_EXYNOS5250
default y
select ARM_EXYNOS_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.
If in doubt, say N.
config ARM_EXYNOS5440_CPUFREQ
def_bool SOC_EXYNOS5440
bool "SAMSUNG EXYNOS5440"
depends on SOC_EXYNOS5440
depends on HAVE_CLK && PM_OPP && OF
default y
select CPU_FREQ_TABLE
help
This adds the CPUFreq driver for Samsung EXYNOS5440
@ -55,6 +65,8 @@ config ARM_EXYNOS5440_CPUFREQ
different than previous exynos controllers so not using
the common exynos framework.
If in doubt, say N.
config ARM_HIGHBANK_CPUFREQ
tristate "Calxeda Highbank-based"
depends on ARCH_HIGHBANK

View File

@ -23,7 +23,7 @@ obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o
# powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers.
# speedstep-* is preferred over p4-clockmod.
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o

View File

@ -45,7 +45,6 @@
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
#include "mperf.h"
MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
@ -198,7 +197,7 @@ static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
return sprintf(buf, "%u\n", boost_enabled);
}
static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb);
cpufreq_freq_attr_rw(cpb);
#endif
static int check_est_cpu(unsigned int cpuid)
@ -710,7 +709,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
return blacklisted;
#endif
data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@ -800,7 +799,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_unreg;
}
data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
data->freq_table = kmalloc(sizeof(*data->freq_table) *
(perf->state_count+1), GFP_KERNEL);
if (!data->freq_table) {
result = -ENOMEM;
@ -861,10 +860,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);
/* Check for APERF/MPERF support in hardware */
if (boot_cpu_has(X86_FEATURE_APERFMPERF))
acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
pr_debug("CPU%u - ACPI performance management activated.\n", cpu);
for (i = 0; i < perf->state_count; i++)
pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n",
@ -941,7 +936,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.exit = acpi_cpufreq_cpu_exit,
.resume = acpi_cpufreq_resume,
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
};

View File

@ -19,12 +19,11 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/opp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@ -34,27 +33,13 @@
/* get cpu node with valid operating-points */
static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
struct device_node *np = NULL, *parent;
int count = 0;
struct device_node *np = of_cpu_device_node_get(cpu);
parent = of_find_node_by_path("/cpus");
if (!parent) {
pr_err("failed to find OF /cpus\n");
return NULL;
if (!of_get_property(np, "operating-points", NULL)) {
of_node_put(np);
np = NULL;
}
for_each_child_of_node(parent, np) {
if (count++ != cpu)
continue;
if (!of_get_property(np, "operating-points", NULL)) {
of_node_put(np);
np = NULL;
}
break;
}
of_node_put(parent);
return np;
}
@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev)
struct device_node *np;
int ret;
np = get_cpu_node_with_valid_op(cpu_dev->id);
if (!np)
return -ENODATA;
np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("failed to find cpu%d node\n", cpu_dev->id);
return -ENOENT;
}
cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
of_node_put(np);
@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
struct device_node *np;
u32 transition_latency = CPUFREQ_ETERNAL;
np = get_cpu_node_with_valid_op(cpu_dev->id);
if (!np)
np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
}
of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);

View File

@ -108,7 +108,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
static struct cpufreq_driver at32_driver = {
.name = "at32ap",
.owner = THIS_MODULE,
.init = at32_cpufreq_driver_init,
.verify = at32_verify_speed,
.target = at32_set_target,

View File

@ -225,7 +225,6 @@ static struct cpufreq_driver bfin_driver = {
.get = bfin_getfreq_khz,
.init = __bfin_cpu_init,
.name = "bfin cpufreq",
.owner = THIS_MODULE,
.attr = bfin_freq_attr,
};

View File

@ -69,7 +69,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
if (cpu_reg) {
if (!IS_ERR(cpu_reg)) {
rcu_read_lock();
opp = opp_find_freq_ceil(cpu_dev, &freq_Hz);
if (IS_ERR(opp)) {
@ -90,7 +90,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
freqs.new / 1000, volt ? volt / 1000 : -1);
/* scaling up? scale voltage before frequency */
if (cpu_reg && freqs.new > freqs.old) {
if (!IS_ERR(cpu_reg) && freqs.new > freqs.old) {
ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
if (ret) {
pr_err("failed to scale voltage up: %d\n", ret);
@ -102,14 +102,14 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
ret = clk_set_rate(cpu_clk, freq_exact);
if (ret) {
pr_err("failed to set clock rate: %d\n", ret);
if (cpu_reg)
if (!IS_ERR(cpu_reg))
regulator_set_voltage_tol(cpu_reg, volt_old, tol);
freqs.new = freqs.old;
goto post_notify;
}
/* scaling down? scale voltage after frequency */
if (cpu_reg && freqs.new < freqs.old) {
if (!IS_ERR(cpu_reg) && freqs.new < freqs.old) {
ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
if (ret) {
pr_err("failed to scale voltage down: %d\n", ret);
@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
static int cpu0_cpufreq_probe(struct platform_device *pdev)
{
struct device_node *np, *parent;
struct device_node *np;
int ret;
parent = of_find_node_by_path("/cpus");
if (!parent) {
pr_err("failed to find OF /cpus\n");
return -ENOENT;
}
for_each_child_of_node(parent, np) {
if (of_get_property(np, "operating-points", NULL))
break;
}
cpu_dev = &pdev->dev;
np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("failed to find cpu0 node\n");
ret = -ENOENT;
goto out_put_parent;
return -ENOENT;
}
cpu_dev = &pdev->dev;
cpu_dev->of_node = np;
cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
@ -210,7 +198,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
}
pr_warn("failed to get cpu0 regulator: %ld\n",
PTR_ERR(cpu_reg));
cpu_reg = NULL;
}
cpu_clk = devm_clk_get(cpu_dev, NULL);
@ -269,15 +256,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
}
of_node_put(np);
of_node_put(parent);
return 0;
out_free_table:
opp_free_cpufreq_table(cpu_dev, &freq_table);
out_put_node:
of_node_put(np);
out_put_parent:
of_node_put(parent);
return ret;
}

View File

@ -379,7 +379,6 @@ static struct cpufreq_driver nforce2_driver = {
.get = nforce2_get,
.init = nforce2_cpu_init,
.exit = nforce2_cpu_exit,
.owner = THIS_MODULE,
};
#ifdef MODULE

File diff suppressed because it is too large Load Diff

View File

@ -11,19 +11,7 @@
* published by the Free Software Foundation.
*/
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/percpu-defs.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include "cpufreq_governor.h"
/* Conservative governor macros */
@ -79,8 +67,6 @@ static void cs_check_cpu(int cpu, unsigned int load)
return;
dbs_info->requested_freq += get_freq_target(cs_tuners, policy);
if (dbs_info->requested_freq > policy->max)
dbs_info->requested_freq = policy->max;
__cpufreq_driver_target(policy, dbs_info->requested_freq,
CPUFREQ_RELATION_H);
@ -101,8 +87,6 @@ static void cs_check_cpu(int cpu, unsigned int load)
return;
dbs_info->requested_freq -= get_freq_target(cs_tuners, policy);
if (dbs_info->requested_freq < policy->min)
dbs_info->requested_freq = policy->min;
__cpufreq_driver_target(policy, dbs_info->requested_freq,
CPUFREQ_RELATION_L);
@ -329,7 +313,7 @@ static int cs_init(struct dbs_data *dbs_data)
{
struct cs_dbs_tuners *tuners;
tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL);
tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
if (!tuners) {
pr_err("%s: kzalloc failed\n", __func__);
return -ENOMEM;

View File

@ -16,15 +16,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <asm/cputime.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/export.h>
#include <linux/kernel_stat.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include "cpufreq_governor.h"
@ -53,7 +47,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
policy = cdbs->cur_policy;
/* Get Absolute Load (in terms of freq for ondemand gov) */
/* Get Absolute Load */
for_each_cpu(j, policy->cpus) {
struct cpu_dbs_common_info *j_cdbs;
u64 cur_wall_time, cur_idle_time;
@ -104,14 +98,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
load = 100 * (wall_time - idle_time) / wall_time;
if (dbs_data->cdata->governor == GOV_ONDEMAND) {
int freq_avg = __cpufreq_driver_getavg(policy, j);
if (freq_avg <= 0)
freq_avg = policy->cur;
load *= freq_avg;
}
if (load > max_load)
max_load = load;
}
@ -133,8 +119,18 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
{
int i;
if (!policy->governor_enabled)
return;
if (!all_cpus) {
__gov_queue_work(smp_processor_id(), dbs_data, delay);
/*
* Use raw_smp_processor_id() to avoid preemptible warnings.
* We know that this is only called with all_cpus == false from
* works that have been queued with *_work_on() functions and
* those works are canceled during CPU_DOWN_PREPARE so they
* can't possibly run on any other CPU.
*/
__gov_queue_work(raw_smp_processor_id(), dbs_data, delay);
} else {
for_each_cpu(i, policy->cpus)
__gov_queue_work(i, dbs_data, delay);
@ -244,7 +240,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
policy->governor_data = dbs_data;
/* policy latency is in nS. Convert it to uS first */
/* policy latency is in ns. Convert it to us first */
latency = policy->cpuinfo.transition_latency / 1000;
if (latency == 0)
latency = 1;

View File

@ -18,19 +18,18 @@
#define _CPUFREQ_GOVERNOR_H
#include <linux/cpufreq.h>
#include <linux/kobject.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/sysfs.h>
/*
* The polling frequency depends on the capability of the processor. Default
* polling frequency is 1000 times the transition latency of the processor. The
* governor will work on any processor with transition latency <= 10mS, using
* governor will work on any processor with transition latency <= 10ms, using
* appropriate sampling rate.
*
* For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
* this governor will not work. All times here are in uS.
* For CPUs with transition latency > 10ms (mostly drivers with CPUFREQ_ETERNAL)
* this governor will not work. All times here are in us (micro seconds).
*/
#define MIN_SAMPLING_RATE_RATIO (2)
#define LATENCY_MULTIPLIER (1000)
@ -163,13 +162,12 @@ struct cs_cpu_dbs_info_s {
unsigned int enable:1;
};
/* Per policy Governers sysfs tunables */
/* Per policy Governors sysfs tunables */
struct od_dbs_tuners {
unsigned int ignore_nice_load;
unsigned int sampling_rate;
unsigned int sampling_down_factor;
unsigned int up_threshold;
unsigned int adj_up_threshold;
unsigned int powersave_bias;
unsigned int io_is_busy;
};
@ -183,7 +181,7 @@ struct cs_dbs_tuners {
unsigned int freq_step;
};
/* Common Governer data across policies */
/* Common Governor data across policies */
struct dbs_data;
struct common_dbs_data {
/* Common across governors */
@ -207,7 +205,7 @@ struct common_dbs_data {
void *gov_ops;
};
/* Governer Per policy data */
/* Governor Per policy data */
struct dbs_data {
struct common_dbs_data *cdata;
unsigned int min_sampling_rate;
@ -223,7 +221,7 @@ struct od_ops {
void (*powersave_bias_init_cpu)(int cpu);
unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
unsigned int freq_next, unsigned int relation);
void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq);
void (*freq_increase)(struct cpufreq_policy *policy, unsigned int freq);
};
struct cs_ops {

View File

@ -12,28 +12,16 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/cpu.h>
#include <linux/percpu-defs.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/tick.h>
#include <linux/types.h>
#include <linux/cpu.h>
#include "cpufreq_governor.h"
/* On-demand governor macros */
#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10)
#define DEF_FREQUENCY_UP_THRESHOLD (80)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (100000)
#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3)
#define MICRO_FREQUENCY_UP_THRESHOLD (95)
#define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000)
#define MIN_FREQUENCY_UP_THRESHOLD (11)
@ -144,31 +132,27 @@ static void ondemand_powersave_bias_init(void)
}
}
static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq)
{
struct dbs_data *dbs_data = p->governor_data;
struct dbs_data *dbs_data = policy->governor_data;
struct od_dbs_tuners *od_tuners = dbs_data->tuners;
if (od_tuners->powersave_bias)
freq = od_ops.powersave_bias_target(p, freq,
freq = od_ops.powersave_bias_target(policy, freq,
CPUFREQ_RELATION_H);
else if (p->cur == p->max)
else if (policy->cur == policy->max)
return;
__cpufreq_driver_target(p, freq, od_tuners->powersave_bias ?
__cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ?
CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
}
/*
* Every sampling_rate, we check, if current idle time is less than 20%
* (default), then we try to increase frequency. Every sampling_rate, we look
* for the lowest frequency which can sustain the load while keeping idle time
* over 30%. If such a frequency exist, we try to decrease to this frequency.
*
* Any frequency increase takes it to the maximum frequency. Frequency reduction
* happens at minimum steps of 5% (default) of current frequency
* (default), then we try to increase frequency. Else, we adjust the frequency
* proportional to load.
*/
static void od_check_cpu(int cpu, unsigned int load_freq)
static void od_check_cpu(int cpu, unsigned int load)
{
struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
@ -178,36 +162,21 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
dbs_info->freq_lo = 0;
/* Check for frequency increase */
if (load_freq > od_tuners->up_threshold * policy->cur) {
if (load > od_tuners->up_threshold) {
/* If switching to max speed, apply sampling_down_factor */
if (policy->cur < policy->max)
dbs_info->rate_mult =
od_tuners->sampling_down_factor;
dbs_freq_increase(policy, policy->max);
return;
}
/* Check for frequency decrease */
/* if we cannot reduce the frequency anymore, break out early */
if (policy->cur == policy->min)
return;
/*
* The optimal frequency is the frequency that is the lowest that can
* support the current CPU usage without triggering the up policy. To be
* safe, we focus 10 points under the threshold.
*/
if (load_freq < od_tuners->adj_up_threshold
* policy->cur) {
} else {
/* Calculate the next frequency proportional to load */
unsigned int freq_next;
freq_next = load_freq / od_tuners->adj_up_threshold;
freq_next = load * policy->cpuinfo.max_freq / 100;
/* No longer fully busy, reset rate_mult */
dbs_info->rate_mult = 1;
if (freq_next < policy->min)
freq_next = policy->min;
if (!od_tuners->powersave_bias) {
__cpufreq_driver_target(policy, freq_next,
CPUFREQ_RELATION_L);
@ -374,9 +343,6 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf,
input < MIN_FREQUENCY_UP_THRESHOLD) {
return -EINVAL;
}
/* Calculate the new adj_up_threshold */
od_tuners->adj_up_threshold += input;
od_tuners->adj_up_threshold -= od_tuners->up_threshold;
od_tuners->up_threshold = input;
return count;
@ -513,7 +479,7 @@ static int od_init(struct dbs_data *dbs_data)
u64 idle_time;
int cpu;
tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL);
tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
if (!tuners) {
pr_err("%s: kzalloc failed\n", __func__);
return -ENOMEM;
@ -525,8 +491,6 @@ static int od_init(struct dbs_data *dbs_data)
if (idle_time != -1ULL) {
/* Idle micro accounting is supported. Use finer thresholds */
tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
/*
* In nohz/micro accounting case we set the minimum frequency
* not depending on HZ, but fixed (very low). The deferred
@ -535,8 +499,6 @@ static int od_init(struct dbs_data *dbs_data)
dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
} else {
tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
DEF_FREQUENCY_DOWN_DIFFERENTIAL;
/* For correct statistics, we need 10 ticks for each measure */
dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *

View File

@ -12,10 +12,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/module.h>
static int cpufreq_governor_performance(struct cpufreq_policy *policy,
unsigned int event)

View File

@ -12,10 +12,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/module.h>
static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
unsigned int event)

View File

@ -9,17 +9,10 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/sysfs.h>
#include <linux/cpufreq.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/percpu.h>
#include <linux/kobject.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <asm/cputime.h>
static spinlock_t cpufreq_stats_lock;
@ -200,22 +193,22 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
{
unsigned int i, j, count = 0, ret = 0;
struct cpufreq_stats *stat;
struct cpufreq_policy *data;
struct cpufreq_policy *current_policy;
unsigned int alloc_size;
unsigned int cpu = policy->cpu;
if (per_cpu(cpufreq_stats_table, cpu))
return -EBUSY;
stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
stat = kzalloc(sizeof(*stat), GFP_KERNEL);
if ((stat) == NULL)
return -ENOMEM;
data = cpufreq_cpu_get(cpu);
if (data == NULL) {
current_policy = cpufreq_cpu_get(cpu);
if (current_policy == NULL) {
ret = -EINVAL;
goto error_get_fail;
}
ret = sysfs_create_group(&data->kobj, &stats_attr_group);
ret = sysfs_create_group(&current_policy->kobj, &stats_attr_group);
if (ret)
goto error_out;
@ -258,10 +251,10 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
stat->last_time = get_jiffies_64();
stat->last_index = freq_table_get_index(stat, policy->cur);
spin_unlock(&cpufreq_stats_lock);
cpufreq_cpu_put(data);
cpufreq_cpu_put(current_policy);
return 0;
error_out:
cpufreq_cpu_put(data);
cpufreq_cpu_put(current_policy);
error_get_fail:
kfree(stat);
per_cpu(cpufreq_stats_table, cpu) = NULL;
@ -348,16 +341,10 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb,
unsigned int cpu = (unsigned long)hcpu;
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
cpufreq_update_policy(cpu);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
cpufreq_stats_free_sysfs(cpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
cpufreq_stats_free_table(cpu);
break;
}
@ -390,8 +377,6 @@ static int __init cpufreq_stats_init(void)
return ret;
register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
for_each_online_cpu(cpu)
cpufreq_update_policy(cpu);
ret = cpufreq_register_notifier(&notifier_trans_block,
CPUFREQ_TRANSITION_NOTIFIER);

View File

@ -111,7 +111,6 @@ static struct cpufreq_driver cris_freq_driver = {
.init = cris_freq_cpu_init,
.exit = cris_freq_cpu_exit,
.name = "cris_freq",
.owner = THIS_MODULE,
.attr = cris_freq_attr,
};

View File

@ -108,7 +108,6 @@ static struct cpufreq_driver cris_freq_driver = {
.init = cris_freq_cpu_init,
.exit = cris_freq_cpu_exit,
.name = "cris_freq",
.owner = THIS_MODULE,
.attr = cris_freq_attr,
};

View File

@ -54,7 +54,7 @@ static struct acpi_processor_performance *eps_acpi_cpu_perf;
/* Minimum necessary to get acpi_processor_get_bios_limit() working */
static int eps_acpi_init(void)
{
eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance),
eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf),
GFP_KERNEL);
if (!eps_acpi_cpu_perf)
return -ENOMEM;
@ -366,7 +366,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
states = 2;
/* Allocate private data and frequency table for current cpu */
centaur = kzalloc(sizeof(struct eps_cpu_data)
centaur = kzalloc(sizeof(*centaur)
+ (states + 1) * sizeof(struct cpufreq_frequency_table),
GFP_KERNEL);
if (!centaur)
@ -436,7 +436,6 @@ static struct cpufreq_driver eps_driver = {
.exit = eps_cpu_exit,
.get = eps_get,
.name = "e_powersaver",
.owner = THIS_MODULE,
.attr = eps_attr,
};

Some files were not shown because too many files have changed in this diff Show More