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:
Коммит
40031da445
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
/*
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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, ¬_used);
|
||||
if (ACPI_FAILURE(status))
|
||||
if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
|
||||
return 0;
|
||||
|
||||
c.list = list;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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", ¬_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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(¤t_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(¬ifier_trans_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче