2009-07-29 04:45:54 +08:00
|
|
|
/*
|
|
|
|
* acpi/internal.h
|
|
|
|
* For use by Linux/ACPI infrastructure, not drivers
|
|
|
|
*
|
|
|
|
* Copyright (c) 2009, Intel Corporation.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2010-07-16 19:11:31 +08:00
|
|
|
#ifndef _ACPI_INTERNAL_H_
|
|
|
|
#define _ACPI_INTERNAL_H_
|
|
|
|
|
2009-07-29 04:45:54 +08:00
|
|
|
#define PREFIX "ACPI: "
|
2009-03-14 02:08:26 +08:00
|
|
|
|
2013-07-23 16:11:55 +08:00
|
|
|
acpi_status acpi_os_initialize1(void);
|
2009-03-25 06:50:09 +08:00
|
|
|
int init_acpi_device_notify(void);
|
2009-03-25 06:49:43 +08:00
|
|
|
int acpi_scan_init(void);
|
2013-01-30 21:27:33 +08:00
|
|
|
void acpi_pci_root_init(void);
|
2013-01-30 21:27:37 +08:00
|
|
|
void acpi_pci_link_init(void);
|
ACPI / processor: Use common hotplug infrastructure
Split the ACPI processor driver into two parts, one that is
non-modular, resides in the ACPI core and handles the enumeration
and hotplug of processors and one that implements the rest of the
existing processor driver functionality.
The non-modular part uses an ACPI scan handler object to enumerate
processors on the basis of information provided by the ACPI namespace
and to hook up with the common ACPI hotplug infrastructure. It also
populates the ACPI handle of each processor device having a
corresponding object in the ACPI namespace, which allows the driver
proper to bind to those devices, and makes the driver bind to them
if it is readily available (i.e. loaded) when the scan handler's
.attach() routine is running.
There are a few reasons to make this change.
First, switching the ACPI processor driver to using the common ACPI
hotplug infrastructure reduces code duplication and size considerably,
even though a new file is created along with a header comment etc.
Second, since the common hotplug code attempts to offline devices
before starting the (non-reversible) removal procedure, it will abort
(and possibly roll back) hot-remove operations involving processors
if cpu_down() returns an error code for one of them instead of
continuing them blindly (if /sys/firmware/acpi/hotplug/force_remove
is unset). That is a more desirable behavior than what the current
code does.
Finally, the separation of the scan/hotplug part from the driver
proper makes it possible to simplify the driver's .remove() routine,
because it doesn't need to worry about the possible cleanup related
to processor removal any more (the scan/hotplug part is responsible
for that now) and can handle device removal and driver removal
symmetricaly (i.e. as appropriate).
Some user-visible changes in sysfs are made (for example, the
'sysdev' link from the ACPI device node to the processor device's
directory is gone and a 'physical_node' link is present instead
and a corresponding 'firmware_node' is present in the processor
device's directory, the processor driver is now visible under
/sys/bus/cpu/drivers/ and bound to the processor device), but
that shouldn't affect the functionality that users care about
(frequency scaling, C-states and thermal management).
Tested on my venerable Toshiba Portege R500.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-03 06:26:22 +08:00
|
|
|
void acpi_processor_init(void);
|
2013-01-30 21:27:40 +08:00
|
|
|
void acpi_platform_init(void);
|
2010-07-15 10:46:30 +08:00
|
|
|
int acpi_sysfs_init(void);
|
2013-02-09 06:52:39 +08:00
|
|
|
#ifdef CONFIG_ACPI_CONTAINER
|
|
|
|
void acpi_container_init(void);
|
|
|
|
#else
|
|
|
|
static inline void acpi_container_init(void) {}
|
|
|
|
#endif
|
2013-06-23 06:59:55 +08:00
|
|
|
#ifdef CONFIG_ACPI_DOCK
|
|
|
|
void acpi_dock_init(void);
|
|
|
|
#else
|
|
|
|
static inline void acpi_dock_init(void) {}
|
|
|
|
#endif
|
2013-03-04 06:18:03 +08:00
|
|
|
#ifdef CONFIG_ACPI_HOTPLUG_MEMORY
|
|
|
|
void acpi_memory_hotplug_init(void);
|
|
|
|
#else
|
|
|
|
static inline void acpi_memory_hotplug_init(void) {}
|
|
|
|
#endif
|
2013-06-05 10:27:50 +08:00
|
|
|
#ifdef CONFIG_X86
|
|
|
|
void acpi_cmos_rtc_init(void);
|
|
|
|
#else
|
|
|
|
static inline void acpi_cmos_rtc_init(void) {}
|
|
|
|
#endif
|
2009-03-25 06:49:43 +08:00
|
|
|
|
2013-05-03 06:26:16 +08:00
|
|
|
extern bool acpi_force_hot_remove;
|
|
|
|
|
2013-03-04 06:08:16 +08:00
|
|
|
void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
|
|
|
|
const char *name);
|
|
|
|
int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
|
|
|
|
const char *hotplug_profile_name);
|
|
|
|
void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val);
|
|
|
|
|
2010-07-15 10:46:15 +08:00
|
|
|
#ifdef CONFIG_DEBUG_FS
|
2011-05-26 18:26:23 +08:00
|
|
|
extern struct dentry *acpi_debugfs_dir;
|
2010-07-15 10:46:15 +08:00
|
|
|
int acpi_debugfs_init(void);
|
|
|
|
#else
|
2011-05-26 18:26:23 +08:00
|
|
|
static inline void acpi_debugfs_init(void) { return; }
|
2010-07-15 10:46:15 +08:00
|
|
|
#endif
|
2013-03-07 06:46:20 +08:00
|
|
|
#ifdef CONFIG_X86_INTEL_LPSS
|
|
|
|
void acpi_lpss_init(void);
|
|
|
|
#else
|
|
|
|
static inline void acpi_lpss_init(void) {}
|
|
|
|
#endif
|
2010-07-15 10:46:15 +08:00
|
|
|
|
2013-11-23 04:52:12 +08:00
|
|
|
bool acpi_queue_hotplug_work(struct work_struct *work);
|
|
|
|
|
2013-01-17 21:11:05 +08:00
|
|
|
/* --------------------------------------------------------------------------
|
|
|
|
Device Node Initialization / Removal
|
|
|
|
-------------------------------------------------------------------------- */
|
|
|
|
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
|
|
|
|
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
|
|
|
|
|
2013-01-24 19:49:49 +08:00
|
|
|
int acpi_device_add(struct acpi_device *device,
|
|
|
|
void (*release)(struct device *));
|
2013-01-17 21:11:05 +08:00
|
|
|
void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
|
|
|
int type, unsigned long long sta);
|
2013-01-24 19:49:49 +08:00
|
|
|
void acpi_device_add_finalize(struct acpi_device *device);
|
2013-03-05 05:30:42 +08:00
|
|
|
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
|
2013-11-29 23:27:43 +08:00
|
|
|
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
|
ACPI / processor: Use common hotplug infrastructure
Split the ACPI processor driver into two parts, one that is
non-modular, resides in the ACPI core and handles the enumeration
and hotplug of processors and one that implements the rest of the
existing processor driver functionality.
The non-modular part uses an ACPI scan handler object to enumerate
processors on the basis of information provided by the ACPI namespace
and to hook up with the common ACPI hotplug infrastructure. It also
populates the ACPI handle of each processor device having a
corresponding object in the ACPI namespace, which allows the driver
proper to bind to those devices, and makes the driver bind to them
if it is readily available (i.e. loaded) when the scan handler's
.attach() routine is running.
There are a few reasons to make this change.
First, switching the ACPI processor driver to using the common ACPI
hotplug infrastructure reduces code duplication and size considerably,
even though a new file is created along with a header comment etc.
Second, since the common hotplug code attempts to offline devices
before starting the (non-reversible) removal procedure, it will abort
(and possibly roll back) hot-remove operations involving processors
if cpu_down() returns an error code for one of them instead of
continuing them blindly (if /sys/firmware/acpi/hotplug/force_remove
is unset). That is a more desirable behavior than what the current
code does.
Finally, the separation of the scan/hotplug part from the driver
proper makes it possible to simplify the driver's .remove() routine,
because it doesn't need to worry about the possible cleanup related
to processor removal any more (the scan/hotplug part is responsible
for that now) and can handle device removal and driver removal
symmetricaly (i.e. as appropriate).
Some user-visible changes in sysfs are made (for example, the
'sysdev' link from the ACPI device node to the processor device's
directory is gone and a 'physical_node' link is present instead
and a corresponding 'firmware_node' is present in the processor
device's directory, the processor driver is now visible under
/sys/bus/cpu/drivers/ and bound to the processor device), but
that shouldn't affect the functionality that users care about
(frequency scaling, C-states and thermal management).
Tested on my venerable Toshiba Portege R500.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-03 06:26:22 +08:00
|
|
|
int acpi_unbind_one(struct device *dev);
|
ACPI / scan: Add acpi_device objects for all device nodes in the namespace
Modify the ACPI namespace scanning code to register a struct
acpi_device object for every namespace node representing a device,
processor and so on, even if the device represented by that namespace
node is reported to be not present and not functional by _STA.
There are multiple reasons to do that. First of all, it avoids
quite a lot of overhead when struct acpi_device objects are
deleted every time acpi_bus_trim() is run and then added again
by a subsequent acpi_bus_scan() for the same scope, although the
namespace objects they correspond to stay in memory all the time
(which always is the case on a vast majority of systems).
Second, it will allow user space to see that there are namespace
nodes representing devices that are not present at the moment and may
be added to the system. It will also allow user space to evaluate
_SUN for those nodes to check what physical slots the "missing"
devices may be put into and it will make sense to add a sysfs
attribute for _STA evaluation after this change (that will be
useful for thermal management on some systems).
Next, it will help to consolidate the ACPI hotplug handling among
subsystems by making it possible to store hotplug-related information
in struct acpi_device objects in a standard common way.
Finally, it will help to avoid a race condition related to the
deletion of ACPI namespace nodes. Namely, namespace nodes may be
deleted as a result of a table unload triggered by _EJ0 or _DCK.
If a hotplug notification for one of those nodes is triggered
right before the deletion and it executes a hotplug callback
via acpi_hotplug_execute(), the ACPI handle passed to that
callback may be stale when the callback actually runs. One way
to work around that is to always pass struct acpi_device pointers
to hotplug callbacks after doing a get_device() on the objects in
question which eliminates the use-after-free possibility (the ACPI
handles in those objects are invalidated by acpi_scan_drop_device(),
so they will trigger ACPICA errors on attempts to use them).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2013-11-23 04:54:37 +08:00
|
|
|
bool acpi_device_is_present(struct acpi_device *adev);
|
2013-01-17 21:11:05 +08:00
|
|
|
|
2009-03-14 02:08:26 +08:00
|
|
|
/* --------------------------------------------------------------------------
|
|
|
|
Power Resource
|
|
|
|
-------------------------------------------------------------------------- */
|
2009-03-25 06:49:53 +08:00
|
|
|
int acpi_power_init(void);
|
2013-01-17 21:11:06 +08:00
|
|
|
void acpi_power_resources_list_free(struct list_head *list);
|
2013-01-17 21:11:07 +08:00
|
|
|
int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
|
|
|
|
struct list_head *list);
|
|
|
|
int acpi_add_power_resource(acpi_handle handle);
|
ACPI / PM: Rework the handling of devices depending on power resources
Commit 0090def6 (ACPI: Add interface to register/unregister device
to/from power resources) made it possible to indicate to the ACPI
core that if the given device depends on any power resources, then
it should be resumed as soon as all of the power resources required
by it to transition to the D0 power state have been turned on.
Unfortunately, however, this was a mistake, because all devices
depending on power resources should be treated this way (i.e. they
should be resumed when all power resources required by their D0
state have been turned on) and for the majority of those devices
the ACPI core can figure out by itself which (physical) devices
depend on what power resources.
For this reason, replace the code added by commit 0090def6 with a
new, much more straightforward, mechanism that will be used
internally by the ACPI core and remove all references to that code
from kernel subsystems using ACPI.
For the cases when there are (physical) devices that should be
resumed whenever a not directly related ACPI device node goes into
D0 as a result of power resources configuration changes, like in
the SATA case, add two new routines, acpi_dev_pm_add_dependent()
and acpi_dev_pm_remove_dependent(), allowing subsystems to manage
such dependencies. Convert the SATA subsystem to use the new
functions accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-01-17 21:11:05 +08:00
|
|
|
void acpi_power_add_remove_device(struct acpi_device *adev, bool add);
|
ACPI / PM: Take unusual configurations of power resources into account
Commit d2e5f0c (ACPI / PCI: Rework the setup and cleanup of device
wakeup) moved the initial disabling of system wakeup for PCI devices
into a place where it can actually work and that exposed a hidden old
issue with crap^Wunusual system designs where the same power
resources are used for both wakeup power and device power control at
run time.
Namely, say there is one power resource such that the ACPI power
state D0 of a PCI device depends on that power resource (i.e. the
device is in D0 when that power resource is "on") and it is used
as a wakeup power resource for the same device. Then, calling
acpi_pci_sleep_wake(pci_dev, false) for the device in question will
cause the reference counter of that power resource to drop to 0,
which in turn will cause it to be turned off. As a result, the
device will go into D3cold at that point, although it should have
stayed in D0.
As it turns out, that happens to USB controllers on some laptops
and USB becomes unusable on those machines as a result, which is
a major regression from v3.8.
To fix this problem, (1) increment the reference counters of wakup
power resources during their initialization if they are "on"
initially, (2) prevent acpi_disable_wakeup_device_power() from
decrementing the reference counters of wakeup power resources that
were not enabled for wakeup power previously, and (3) prevent
acpi_enable_wakeup_device_power() from incrementing the reference
counters of wakeup power resources that already are enabled for
wakeup power.
In addition to that, if it is impossible to determine the initial
states of wakeup power resources, avoid enabling wakeup for devices
whose wakeup power depends on those power resources.
Reported-by: Dave Jones <davej@redhat.com>
Reported-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Tested-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-02-24 06:15:21 +08:00
|
|
|
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level);
|
2009-03-14 02:08:26 +08:00
|
|
|
int acpi_device_sleep_wake(struct acpi_device *dev,
|
|
|
|
int enable, int sleep_state, int dev_state);
|
2010-11-25 07:05:17 +08:00
|
|
|
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
|
2010-11-25 07:06:55 +08:00
|
|
|
int acpi_power_on_resources(struct acpi_device *device, int state);
|
2009-03-14 02:08:26 +08:00
|
|
|
int acpi_power_transition(struct acpi_device *device, int state);
|
|
|
|
|
ACPI / scan: Add acpi_device objects for all device nodes in the namespace
Modify the ACPI namespace scanning code to register a struct
acpi_device object for every namespace node representing a device,
processor and so on, even if the device represented by that namespace
node is reported to be not present and not functional by _STA.
There are multiple reasons to do that. First of all, it avoids
quite a lot of overhead when struct acpi_device objects are
deleted every time acpi_bus_trim() is run and then added again
by a subsequent acpi_bus_scan() for the same scope, although the
namespace objects they correspond to stay in memory all the time
(which always is the case on a vast majority of systems).
Second, it will allow user space to see that there are namespace
nodes representing devices that are not present at the moment and may
be added to the system. It will also allow user space to evaluate
_SUN for those nodes to check what physical slots the "missing"
devices may be put into and it will make sense to add a sysfs
attribute for _STA evaluation after this change (that will be
useful for thermal management on some systems).
Next, it will help to consolidate the ACPI hotplug handling among
subsystems by making it possible to store hotplug-related information
in struct acpi_device objects in a standard common way.
Finally, it will help to avoid a race condition related to the
deletion of ACPI namespace nodes. Namely, namespace nodes may be
deleted as a result of a table unload triggered by _EJ0 or _DCK.
If a hotplug notification for one of those nodes is triggered
right before the deletion and it executes a hotplug callback
via acpi_hotplug_execute(), the ACPI handle passed to that
callback may be stale when the callback actually runs. One way
to work around that is to always pass struct acpi_device pointers
to hotplug callbacks after doing a get_device() on the objects in
question which eliminates the use-after-free possibility (the ACPI
handles in those objects are invalidated by acpi_scan_drop_device(),
so they will trigger ACPICA errors on attempts to use them).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2013-11-23 04:54:37 +08:00
|
|
|
int acpi_device_update_power(struct acpi_device *device, int *state_p);
|
|
|
|
|
2009-03-25 06:50:19 +08:00
|
|
|
int acpi_wakeup_device_init(void);
|
2009-12-21 03:19:09 +08:00
|
|
|
void acpi_early_processor_set_pdc(void);
|
2009-03-25 06:50:19 +08:00
|
|
|
|
2009-03-14 02:08:26 +08:00
|
|
|
/* --------------------------------------------------------------------------
|
|
|
|
Embedded Controller
|
|
|
|
-------------------------------------------------------------------------- */
|
2010-07-16 19:11:31 +08:00
|
|
|
struct acpi_ec {
|
|
|
|
acpi_handle handle;
|
|
|
|
unsigned long gpe;
|
|
|
|
unsigned long command_addr;
|
|
|
|
unsigned long data_addr;
|
|
|
|
unsigned long global_lock;
|
|
|
|
unsigned long flags;
|
2012-10-23 07:29:27 +08:00
|
|
|
struct mutex mutex;
|
2010-07-16 19:11:31 +08:00
|
|
|
wait_queue_head_t wait;
|
|
|
|
struct list_head list;
|
|
|
|
struct transaction *curr;
|
2012-10-23 07:29:27 +08:00
|
|
|
spinlock_t lock;
|
2010-07-16 19:11:31 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
extern struct acpi_ec *first_ec;
|
|
|
|
|
2009-03-25 06:49:48 +08:00
|
|
|
int acpi_ec_init(void);
|
2009-03-14 02:08:26 +08:00
|
|
|
int acpi_ec_ecdt_probe(void);
|
|
|
|
int acpi_boot_ec_enable(void);
|
2010-04-09 07:40:38 +08:00
|
|
|
void acpi_ec_block_transactions(void);
|
|
|
|
void acpi_ec_unblock_transactions(void);
|
|
|
|
void acpi_ec_unblock_transactions_early(void);
|
2009-03-14 02:08:26 +08:00
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
Suspend/Resume
|
|
|
|
-------------------------------------------------------------------------- */
|
|
|
|
extern int acpi_sleep_init(void);
|
2009-03-25 06:50:14 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_ACPI_SLEEP
|
|
|
|
int acpi_sleep_proc_init(void);
|
2011-01-07 08:43:44 +08:00
|
|
|
int suspend_nvs_alloc(void);
|
|
|
|
void suspend_nvs_free(void);
|
|
|
|
int suspend_nvs_save(void);
|
|
|
|
void suspend_nvs_restore(void);
|
2009-03-25 06:50:14 +08:00
|
|
|
#else
|
|
|
|
static inline int acpi_sleep_proc_init(void) { return 0; }
|
2011-01-07 08:43:44 +08:00
|
|
|
static inline int suspend_nvs_alloc(void) { return 0; }
|
|
|
|
static inline void suspend_nvs_free(void) {}
|
2011-01-13 05:03:20 +08:00
|
|
|
static inline int suspend_nvs_save(void) { return 0; }
|
2011-01-07 08:43:44 +08:00
|
|
|
static inline void suspend_nvs_restore(void) {}
|
2009-03-25 06:50:14 +08:00
|
|
|
#endif
|
2010-07-16 19:11:31 +08:00
|
|
|
|
2012-11-01 05:45:02 +08:00
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
Platform bus support
|
|
|
|
-------------------------------------------------------------------------- */
|
|
|
|
struct platform_device;
|
|
|
|
|
2013-03-07 06:46:20 +08:00
|
|
|
int acpi_create_platform_device(struct acpi_device *adev,
|
|
|
|
const struct acpi_device_id *id);
|
|
|
|
|
ACPI / video / i915: No ACPI backlight if firmware expects Windows 8
According to Matthew Garrett, "Windows 8 leaves backlight control up
to individual graphics drivers rather than making ACPI calls itself.
There's plenty of evidence to suggest that the Intel driver for
Windows [8] doesn't use the ACPI interface, including the fact that
it's broken on a bunch of machines when the OS claims to support
Windows 8. The simplest thing to do appears to be to disable the
ACPI backlight interface on these systems".
There's a problem with that approach, however, because simply
avoiding to register the ACPI backlight interface if the firmware
calls _OSI for Windows 8 may not work in the following situations:
(1) The ACPI backlight interface actually works on the given system
and the i915 driver is not loaded (e.g. another graphics driver
is used).
(2) The ACPI backlight interface doesn't work on the given system,
but there is a vendor platform driver that will register its
own, equally broken, backlight interface if not prevented from
doing so by the ACPI subsystem.
Therefore we need to allow the ACPI backlight interface to be
registered until the i915 driver is loaded which then will unregister
it if the firmware has called _OSI for Windows 8 (or will register
the ACPI video driver without backlight support if not already
present).
For this reason, introduce an alternative function for registering
ACPI video, acpi_video_register_with_quirks(), that will check
whether or not the ACPI video driver has already been registered
and whether or not the backlight Windows 8 quirk has to be applied.
If the quirk has to be applied, it will block the ACPI backlight
support and either unregister the backlight interface if the ACPI
video driver has already been registered, or register the ACPI
video driver without the backlight interface otherwise. Make
the i915 driver use acpi_video_register_with_quirks() instead of
acpi_video_register() in i915_driver_load().
This change is based on earlier patches from Matthew Garrett,
Chun-Yi Lee and Seth Forshee and includes a fix from Aaron Lu's.
References: https://bugzilla.kernel.org/show_bug.cgi?id=51231
Tested-by: Aaron Lu <aaron.lu@intel.com>
Tested-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Tested-by: Yves-Alexis Perez <corsac@debian.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Aaron Lu <aaron.lu@intel.com>
Acked-by: Matthew Garrett <matthew.garrett@nebula.com>
2013-07-18 08:08:06 +08:00
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
Video
|
|
|
|
-------------------------------------------------------------------------- */
|
|
|
|
#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
|
2013-10-11 21:27:45 +08:00
|
|
|
bool acpi_osi_is_win8(void);
|
ACPI / video / i915: No ACPI backlight if firmware expects Windows 8
According to Matthew Garrett, "Windows 8 leaves backlight control up
to individual graphics drivers rather than making ACPI calls itself.
There's plenty of evidence to suggest that the Intel driver for
Windows [8] doesn't use the ACPI interface, including the fact that
it's broken on a bunch of machines when the OS claims to support
Windows 8. The simplest thing to do appears to be to disable the
ACPI backlight interface on these systems".
There's a problem with that approach, however, because simply
avoiding to register the ACPI backlight interface if the firmware
calls _OSI for Windows 8 may not work in the following situations:
(1) The ACPI backlight interface actually works on the given system
and the i915 driver is not loaded (e.g. another graphics driver
is used).
(2) The ACPI backlight interface doesn't work on the given system,
but there is a vendor platform driver that will register its
own, equally broken, backlight interface if not prevented from
doing so by the ACPI subsystem.
Therefore we need to allow the ACPI backlight interface to be
registered until the i915 driver is loaded which then will unregister
it if the firmware has called _OSI for Windows 8 (or will register
the ACPI video driver without backlight support if not already
present).
For this reason, introduce an alternative function for registering
ACPI video, acpi_video_register_with_quirks(), that will check
whether or not the ACPI video driver has already been registered
and whether or not the backlight Windows 8 quirk has to be applied.
If the quirk has to be applied, it will block the ACPI backlight
support and either unregister the backlight interface if the ACPI
video driver has already been registered, or register the ACPI
video driver without the backlight interface otherwise. Make
the i915 driver use acpi_video_register_with_quirks() instead of
acpi_video_register() in i915_driver_load().
This change is based on earlier patches from Matthew Garrett,
Chun-Yi Lee and Seth Forshee and includes a fix from Aaron Lu's.
References: https://bugzilla.kernel.org/show_bug.cgi?id=51231
Tested-by: Aaron Lu <aaron.lu@intel.com>
Tested-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Tested-by: Yves-Alexis Perez <corsac@debian.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Aaron Lu <aaron.lu@intel.com>
Acked-by: Matthew Garrett <matthew.garrett@nebula.com>
2013-07-18 08:08:06 +08:00
|
|
|
#endif
|
|
|
|
|
2010-07-16 19:11:31 +08:00
|
|
|
#endif /* _ACPI_INTERNAL_H_ */
|