OpenCloudOS-Kernel/include/acpi/acpi_bus.h

693 lines
19 KiB
C
Raw Normal View History

/*
* acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef __ACPI_BUS_H__
#define __ACPI_BUS_H__
#include <linux/device.h>
#include <linux/property.h>
/* TBD: Make dynamic */
#define ACPI_MAX_HANDLES 10
struct acpi_handle_list {
u32 count;
acpi_handle handles[ACPI_MAX_HANDLES];
};
/* acpi_utils.h */
acpi_status
acpi_extract_package(union acpi_object *package,
struct acpi_buffer *format, struct acpi_buffer *buffer);
acpi_status
acpi_evaluate_integer(acpi_handle handle,
acpi_string pathname,
struct acpi_object_list *arguments, unsigned long long *data);
acpi_status
acpi_evaluate_reference(acpi_handle handle,
acpi_string pathname,
struct acpi_object_list *arguments,
struct acpi_handle_list *list);
ACPI: Add an interface to evaluate _OST Added acpi_evaluate_hotplug_opt(). All ACPI hotplug handlers must call this function when evaluating _OST for hotplug operations. If the platform does not support _OST, this function returns AE_NOT_FOUND and has no effect on the platform. ACPI_HOTPLUG_OST is defined when all relevant ACPI hotplug operations, such as CPU, memory and container hotplug, are enabled. This assures consistent behavior among the hotplug operations with regarding the _OST support. When ACPI_HOTPLUG_OST is not defined, this function is a no-op. ACPI PCI hotplug is not enhanced to support _OST at this time since it is a legacy method being replaced by PCIe native hotplug. _OST support for ACPI PCI hotplug may be added in future if necessary. Some platforms may require the OS to support _OST in order to support ACPI hotplug operations. For example, if a platform has the management console where user can request a hotplug operation from, this _OST support would be required for the management console to show the result of the hotplug request to user. Added macro definitions of _OST source events and status codes. Also renamed OSC_SB_CPUHP_OST_SUPPORT to OSC_SB_HOTPLUG_OST_SUPPORT since this _OSC bit is not specific to CPU hotplug. This bit is defined in Table 6-147 of ACPI 5.0 as follows. Bits: 3 Field Name: Insertion / Ejection _OST Processing Support Definition: This bit is set if OSPM will evaluate the _OST object defined under a device when processing insertion and ejection source event codes. Signed-off-by: Toshi Kani <toshi.kani@hp.com> Signed-off-by: Len Brown <len.brown@intel.com>
2012-05-24 10:25:19 +08:00
acpi_status
acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
struct acpi_buffer *status_buf);
acpi_status
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
bool acpi_has_method(acpi_handle handle, char *name);
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
u64 arg);
acpi_status acpi_evaluate_ej0(acpi_handle handle);
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock);
bool acpi_ata_match(acpi_handle handle);
bool acpi_bay_match(acpi_handle handle);
bool acpi_dock_match(acpi_handle handle);
bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs);
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid,
u64 rev, u64 func, union acpi_object *argv4);
static inline union acpi_object *
acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
u64 func, union acpi_object *argv4,
acpi_object_type type)
{
union acpi_object *obj;
obj = acpi_evaluate_dsm(handle, guid, rev, func, argv4);
if (obj && obj->type != type) {
ACPI_FREE(obj);
obj = NULL;
}
return obj;
}
#define ACPI_INIT_DSM_ARGV4(cnt, eles) \
{ \
.package.type = ACPI_TYPE_PACKAGE, \
.package.count = (cnt), \
.package.elements = (eles) \
}
bool acpi_dev_found(const char *hid);
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
const char *
acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv);
#ifdef CONFIG_ACPI
#include <linux/proc_fs.h>
#define ACPI_BUS_FILE_ROOT "acpi"
extern struct proc_dir_entry *acpi_root_dir;
enum acpi_bus_device_type {
ACPI_BUS_TYPE_DEVICE = 0,
ACPI_BUS_TYPE_POWER,
ACPI_BUS_TYPE_PROCESSOR,
ACPI_BUS_TYPE_THERMAL,
ACPI_BUS_TYPE_POWER_BUTTON,
ACPI_BUS_TYPE_SLEEP_BUTTON,
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI_BUS_TYPE_ECDT_EC,
ACPI_BUS_DEVICE_TYPE_COUNT
};
struct acpi_driver;
struct acpi_device;
/*
* ACPI Scan Handler
* -----------------
*/
struct acpi_hotplug_profile {
struct kobject kobj;
int (*scan_dependent)(struct acpi_device *adev);
void (*notify_online)(struct acpi_device *adev);
bool enabled:1;
bool demand_offline:1;
};
static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile(
struct kobject *kobj)
{
return container_of(kobj, struct acpi_hotplug_profile, kobj);
}
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
bool (*match)(const char *idstr, const struct acpi_device_id **matchid);
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
void (*bind)(struct device *phys_dev);
void (*unbind)(struct device *phys_dev);
struct acpi_hotplug_profile hotplug;
};
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
/*
* ACPI Hotplug Context
* --------------------
*/
struct acpi_hotplug_context {
struct acpi_device *self;
int (*notify)(struct acpi_device *, u32);
void (*uevent)(struct acpi_device *, u32);
void (*fixup)(struct acpi_device *);
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
};
/*
* ACPI Driver
* -----------
*/
typedef int (*acpi_op_add) (struct acpi_device * device);
typedef int (*acpi_op_remove) (struct acpi_device * device);
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
struct acpi_device_ops {
acpi_op_add add;
acpi_op_remove remove;
acpi_op_notify notify;
};
#define ACPI_DRIVER_ALL_NOTIFY_EVENTS 0x1 /* system AND device events */
struct acpi_driver {
char name[80];
char class[80];
const struct acpi_device_id *ids; /* Supported Hardware IDs */
unsigned int flags;
struct acpi_device_ops ops;
struct device_driver drv;
struct module *owner;
};
/*
* ACPI Device
* -----------
*/
/* Status (_STA) */
struct acpi_device_status {
u32 present:1;
u32 enabled:1;
u32 show_in_ui:1;
u32 functional:1;
u32 battery_present:1;
u32 reserved:27;
};
/* Flags */
struct acpi_device_flags {
u32 dynamic_status:1;
u32 removable:1;
u32 ejectable:1;
u32 power_manageable:1;
u32 match_driver:1;
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
u32 initialized:1;
u32 visited:1;
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
u32 hotplug_notify:1;
ACPI / dock: Dispatch dock notifications from the global notify handler The ACPI dock station code carries out an extra namespace scan before the main one in order to find and register all of the dock device objects. Then, it registers a notify handler for each of them for handling dock events. However, dock device objects need not be scanned for upfront. They very well can be enumerated and registered during the first phase of the main namespace scan, before attaching scan handlers and ACPI drivers to ACPI device objects. Then, the dependent devices can be added to the in the second phase. That makes it possible to drop the extra namespace scan, so do it. Moreover, it is not necessary to register notify handlers for all of the dock stations' namespace nodes, becuase notifications may be dispatched from the global notify handler for them. Do that and drop two functions used for dock notify handling, acpi_dock_deferred_cb() and dock_notify_handler(), that aren't necessary any more. Finally, some dock station objects have _HID objects matching the ACPI container scan handler which causes it to claim those objects and try to handle their hotplug, but that is not a good idea, because those objects have their own special hotplug handling anyway. For this reason, the hotplug_notify flag should not be set for ACPI device objects representing dock stations and the container scan handler should be made ignore those objects, so make that happen. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-16 08:51:01 +08:00
u32 is_dock_station:1;
u32 of_compatible_ok:1;
u32 coherent_dma:1;
u32 cca_seen:1;
u32 enumeration_by_parent:1;
u32 reserved:19;
};
/* File System */
struct acpi_device_dir {
struct proc_dir_entry *entry;
};
#define acpi_device_dir(d) ((d)->dir.entry)
/* Plug and Play */
typedef char acpi_bus_id[8];
typedef unsigned long acpi_bus_address;
typedef char acpi_device_name[40];
typedef char acpi_device_class[20];
struct acpi_hardware_id {
struct list_head list;
const char *id;
};
struct acpi_pnp_type {
u32 hardware_id:1;
u32 bus_address:1;
u32 platform_id:1;
u32 reserved:29;
};
struct acpi_device_pnp {
acpi_bus_id bus_id; /* Object name */
struct acpi_pnp_type type; /* ID type */
acpi_bus_address bus_address; /* _ADR */
char *unique_id; /* _UID */
struct list_head ids; /* _HID and _CIDs */
acpi_device_name device_name; /* Driver-determined */
acpi_device_class device_class; /* " */
ACPI: Add new sysfs interface to export device description Add support to export the device description obtained from the ACPI _STR method, if one exists for a device, to user-space via a sysfs interface. This new interface provides a standard and platform neutral way for users to obtain the description text stored in the ACPI _STR method. If no _STR method exists for the device, no sysfs 'description' file will be created. The 'description' file will be located in the /sys/devices/ directory using the device's path. /sys/device/<bus>/<bridge path>/<device path>.../firmware_node/description Example: /sys/devices/pci0000:00/0000:00.07.0/0000:0e:00.0/firmware_node/description It can also be located using the ACPI device path, for example: /sys/devices/LNXSYSTM:00/device:00/ACPI0004:00/PNP0A08:00/device:13/device:15/description /sys/devices/LNXSYSTM:00/device:00/ACPI0004:00/ACPI0004:01/ACPI0007:02/description Execute the 'cat' command on the 'description' file to obtain the description string for that device. This patch also includes documentation describing how the new sysfs interface works Changes from v1-v2 based on comments by Len Brown and Fengguang Wu * Removed output "No Description" and leaving a NULL attribute if the _STR method failed to evaluate. * In acpi_device_remove_files() removed the redundent check of dev->pnp.str_obj before calling free. This check triggered a message from smatch. Signed-off-by: Lance Ortiz <lance.ortiz@hp.com> Signed-off-by: Len Brown <len.brown@intel.com>
2012-10-03 02:43:23 +08:00
union acpi_object *str_obj; /* unicode string for _STR method */
};
#define acpi_device_bid(d) ((d)->pnp.bus_id)
#define acpi_device_adr(d) ((d)->pnp.bus_address)
const char *acpi_device_hid(struct acpi_device *device);
#define acpi_device_uid(d) ((d)->pnp.unique_id)
#define acpi_device_name(d) ((d)->pnp.device_name)
#define acpi_device_class(d) ((d)->pnp.device_class)
/* Power Management */
struct acpi_device_power_flags {
u32 explicit_get:1; /* _PSC present? */
u32 power_resources:1; /* Power resources */
u32 inrush_current:1; /* Serialize Dx->D0 */
u32 power_removed:1; /* Optimize Dx->D0 */
u32 ignore_parent:1; /* Power is independent of parent power state */
u32 dsw_present:1; /* _DSW present? */
u32 reserved:26;
};
struct acpi_device_power_state {
struct {
u8 valid:1;
u8 explicit_set:1; /* _PSx present? */
u8 reserved:6;
} flags;
int power; /* % Power (compared to D0) */
int latency; /* Dx->D0 time (microseconds) */
struct list_head resources; /* Power resources referenced */
};
struct acpi_device_power {
int state; /* Current state */
struct acpi_device_power_flags flags;
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
};
/* Performance Management */
struct acpi_device_perf_flags {
u8 reserved:8;
};
struct acpi_device_perf_state {
struct {
u8 valid:1;
u8 reserved:7;
} flags;
u8 power; /* % Power (compared to P0) */
u8 performance; /* % Performance ( " ) */
int latency; /* Px->P0 time (microseconds) */
};
struct acpi_device_perf {
int state;
struct acpi_device_perf_flags flags;
int state_count;
struct acpi_device_perf_state *states;
};
/* Wakeup Management */
struct acpi_device_wakeup_flags {
u8 valid:1; /* Can successfully enable wakeup? */
PCI / ACPI / PM: Platform support for PCI PME wake-up Although the majority of PCI devices can generate PMEs that in principle may be used to wake up devices suspended at run time, platform support is generally necessary to convert PMEs into wake-up events that can be delivered to the kernel. If ACPI is used for this purpose, PME signals generated by a PCI device will trigger the ACPI GPE associated with the device to generate an ACPI wake-up event that we can set up a handler for, provided that everything is configured correctly. Unfortunately, the subset of PCI devices that have GPEs associated with them is quite limited. The devices without dedicated GPEs have to rely on the GPEs associated with other devices (in the majority of cases their upstream bridges and, possibly, the root bridge) to generate ACPI wake-up events in response to PME signals from them. Add ACPI platform support for PCI PME wake-up: o Add a framework making is possible to use ACPI system notify handlers for run-time PM. o Add new PCI platform callback ->run_wake() to struct pci_platform_pm_ops allowing us to enable/disable the platform to generate wake-up events for given device. Implemet this callback for the ACPI platform. o Define ACPI wake-up handlers for PCI devices and PCI root buses and make the PCI-ACPI binding code register wake-up notifiers for all PCI devices present in the ACPI tables. o Add function pci_dev_run_wake() which can be used by PCI drivers to check if given device is capable of generating wake-up events at run time. Developed in cooperation with Matthew Garrett <mjg@redhat.com>. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2010-02-18 06:44:09 +08:00
u8 notifier_present:1; /* Wake-up notify handler has been installed */
};
struct acpi_device_wakeup_context {
void (*func)(struct acpi_device_wakeup_context *context);
struct device *dev;
};
struct acpi_device_wakeup {
acpi_handle gpe_device;
u64 gpe_number;
u64 sleep_state;
struct list_head resources;
struct acpi_device_wakeup_flags flags;
struct acpi_device_wakeup_context context;
struct wakeup_source *ws;
int prepare_count;
int enable_count;
};
struct acpi_device_physical_node {
unsigned int node_id;
struct list_head node;
struct device *dev;
bool put_online:1;
};
ACPI: Add support for device specific properties Device Tree is used in many embedded systems to describe the system configuration to the OS. It supports attaching properties or name-value pairs to the devices it describe. With these properties one can pass additional information to the drivers that would not be available otherwise. ACPI is another configuration mechanism (among other things) typically seen, but not limited to, x86 machines. ACPI allows passing arbitrary data from methods but there has not been mechanism equivalent to Device Tree until the introduction of _DSD in the recent publication of the ACPI 5.1 specification. In order to facilitate ACPI usage in systems where Device Tree is typically used, it would be beneficial to standardize a way to retrieve Device Tree style properties from ACPI devices, which is what we do in this patch. If a given device described in ACPI namespace wants to export properties it must implement _DSD method (Device Specific Data, introduced with ACPI 5.1) that returns the properties in a package of packages. For example: Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"name1", <VALUE1>}, Package () {"name2", <VALUE2>}, ... } }) The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301 and is documented in the ACPI 5.1 companion document called "_DSD Implementation Guide" [1], [2]. We add several helper functions that can be used to extract these properties and convert them to different Linux data types. The ultimate goal is that we only have one device property API that retrieves the requested properties from Device Tree or from ACPI transparent to the caller. [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Reviewed-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Darren Hart <dvhart@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-10-21 19:33:55 +08:00
/* ACPI Device Specific Data (_DSD) */
struct acpi_device_data {
const union acpi_object *pointer;
const union acpi_object *properties;
const union acpi_object *of_compatible;
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 10:36:14 +08:00
struct list_head subnodes;
ACPI: Add support for device specific properties Device Tree is used in many embedded systems to describe the system configuration to the OS. It supports attaching properties or name-value pairs to the devices it describe. With these properties one can pass additional information to the drivers that would not be available otherwise. ACPI is another configuration mechanism (among other things) typically seen, but not limited to, x86 machines. ACPI allows passing arbitrary data from methods but there has not been mechanism equivalent to Device Tree until the introduction of _DSD in the recent publication of the ACPI 5.1 specification. In order to facilitate ACPI usage in systems where Device Tree is typically used, it would be beneficial to standardize a way to retrieve Device Tree style properties from ACPI devices, which is what we do in this patch. If a given device described in ACPI namespace wants to export properties it must implement _DSD method (Device Specific Data, introduced with ACPI 5.1) that returns the properties in a package of packages. For example: Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"name1", <VALUE1>}, Package () {"name2", <VALUE2>}, ... } }) The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301 and is documented in the ACPI 5.1 companion document called "_DSD Implementation Guide" [1], [2]. We add several helper functions that can be used to extract these properties and convert them to different Linux data types. The ultimate goal is that we only have one device property API that retrieves the requested properties from Device Tree or from ACPI transparent to the caller. [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Reviewed-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Darren Hart <dvhart@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-10-21 19:33:55 +08:00
};
struct acpi_gpio_mapping;
/* Device */
struct acpi_device {
int device_type;
acpi_handle handle; /* no handle for fixed hardware */
struct fwnode_handle fwnode;
struct acpi_device *parent;
struct list_head children;
struct list_head node;
struct list_head wakeup_list;
struct list_head del_list;
struct acpi_device_status status;
struct acpi_device_flags flags;
struct acpi_device_pnp pnp;
struct acpi_device_power power;
struct acpi_device_wakeup wakeup;
struct acpi_device_perf performance;
struct acpi_device_dir dir;
ACPI: Add support for device specific properties Device Tree is used in many embedded systems to describe the system configuration to the OS. It supports attaching properties or name-value pairs to the devices it describe. With these properties one can pass additional information to the drivers that would not be available otherwise. ACPI is another configuration mechanism (among other things) typically seen, but not limited to, x86 machines. ACPI allows passing arbitrary data from methods but there has not been mechanism equivalent to Device Tree until the introduction of _DSD in the recent publication of the ACPI 5.1 specification. In order to facilitate ACPI usage in systems where Device Tree is typically used, it would be beneficial to standardize a way to retrieve Device Tree style properties from ACPI devices, which is what we do in this patch. If a given device described in ACPI namespace wants to export properties it must implement _DSD method (Device Specific Data, introduced with ACPI 5.1) that returns the properties in a package of packages. For example: Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"name1", <VALUE1>}, Package () {"name2", <VALUE2>}, ... } }) The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301 and is documented in the ACPI 5.1 companion document called "_DSD Implementation Guide" [1], [2]. We add several helper functions that can be used to extract these properties and convert them to different Linux data types. The ultimate goal is that we only have one device property API that retrieves the requested properties from Device Tree or from ACPI transparent to the caller. [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Reviewed-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Darren Hart <dvhart@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-10-21 19:33:55 +08:00
struct acpi_device_data data;
struct acpi_scan_handler *handler;
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
struct acpi_hotplug_context *hp;
struct acpi_driver *driver;
const struct acpi_gpio_mapping *driver_gpios;
void *driver_data;
struct device dev;
unsigned int physical_node_count;
ACPI: Add _DEP support to fix battery issue on Asus T100TA ACPI 5.0 introduces _DEP (Operation Region Dependencies) to designate device objects that OSPM should assign a higher priority in start ordering due to future operation region accesses. On Asus T100TA, ACPI battery info are read from a I2C slave device via I2C operation region. Before I2C operation region handler is installed, battery _STA always returns 0. There is a _DEP method of designating start order under battery device node. This patch is to implement _DEP feature to fix battery issue on the Asus T100TA. Introducing acpi_dep_list and adding dep_unmet count in struct acpi_device. During ACPI namespace scan, create struct acpi_dep_data for a valid pair of master (device pointed to by _DEP)/ slave(device with _DEP), record master's and slave's ACPI handle in it and put it into acpi_dep_list. The dep_unmet count will increase by one if there is a device under its _DEP. Driver's probe() should return EPROBE_DEFER when find dep_unmet is larger than 0. When I2C operation region handler is installed, remove all struct acpi_dep_data on the acpi_dep_list whose master is pointed to I2C host controller and decrease slave's dep_unmet. When dep_unmet decreases to 0, all _DEP conditions are met and then do acpi_bus_attach() for the device in order to resolve battery _STA issue on the Asus T100TA. Link: https://bugzilla.kernel.org/show_bug.cgi?id=69011 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Tested-by: Adam Williamson <adamw@happyassassin.net> Tested-by: Michael Shigorin <shigorin@gmail.com> Acked-by: Wolfram Sang <wsa@the-dreams.de> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-23 21:22:54 +08:00
unsigned int dep_unmet;
struct list_head physical_node_list;
struct mutex physical_node_lock;
void (*remove)(struct acpi_device *);
};
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 10:36:14 +08:00
/* Non-device subnode */
struct acpi_data_node {
const char *name;
acpi_handle handle;
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 10:36:14 +08:00
struct fwnode_handle fwnode;
struct fwnode_handle *parent;
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 10:36:14 +08:00
struct acpi_device_data data;
struct list_head sibling;
struct kobject kobj;
struct completion kobj_done;
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 10:36:14 +08:00
};
extern const struct fwnode_operations acpi_device_fwnode_ops;
extern const struct fwnode_operations acpi_data_fwnode_ops;
extern const struct fwnode_operations acpi_static_fwnode_ops;
ACPI / bus: Make ACPI_HANDLE() work for non-GPL code again Due to commit db3e50f3234b (device property: Get rid of struct fwnode_handle type field), ACPI_HANDLE() inadvertently became a GPL-only call. The call path that led to that was: ACPI_HANDLE() ACPI_COMPANION() to_acpi_device_node() is_acpi_device_node() acpi_device_fwnode_ops DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops); ...and the new DECLARE_ACPI_FWNODE_OPS() includes EXPORT_SYMBOL_GPL, whereas previously it was a static struct. In order to avoid changing any of that, let's instead provide ever so slightly better encapsulation of those struct fwnode_operations instances. Those do not really need to be directly used in inline function calls in header files. Simply moving two small functions (is_acpi_device_node and is_acpi_data_node) out of acpi_bus.h, and into a .c file, does that. That leaves the internals of struct fwnode_operations as GPL-only (which I think was the intent all along), but un-breaks any driver code out there that relies on the ACPI subsystem's being (historically) an EXPORT_SYMBOL-usable system. By that, I mean, ACPI_HANDLE() and other basic ACPI calls were non-GPL-protected. Also, while I'm there, remove a tiny bit of redundancy that was missed in the earlier commit, by having is_acpi_node() use the other two routines, instead of checking fwnode directly. Fixes: db3e50f3234b (device property: Get rid of struct fwnode_handle type field) Signed-off-by: John Hubbard <jhubbard@nvidia.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-16 08:35:27 +08:00
bool is_acpi_device_node(const struct fwnode_handle *fwnode);
bool is_acpi_data_node(const struct fwnode_handle *fwnode);
ACPI / bus: Make ACPI_HANDLE() work for non-GPL code again Due to commit db3e50f3234b (device property: Get rid of struct fwnode_handle type field), ACPI_HANDLE() inadvertently became a GPL-only call. The call path that led to that was: ACPI_HANDLE() ACPI_COMPANION() to_acpi_device_node() is_acpi_device_node() acpi_device_fwnode_ops DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops); ...and the new DECLARE_ACPI_FWNODE_OPS() includes EXPORT_SYMBOL_GPL, whereas previously it was a static struct. In order to avoid changing any of that, let's instead provide ever so slightly better encapsulation of those struct fwnode_operations instances. Those do not really need to be directly used in inline function calls in header files. Simply moving two small functions (is_acpi_device_node and is_acpi_data_node) out of acpi_bus.h, and into a .c file, does that. That leaves the internals of struct fwnode_operations as GPL-only (which I think was the intent all along), but un-breaks any driver code out there that relies on the ACPI subsystem's being (historically) an EXPORT_SYMBOL-usable system. By that, I mean, ACPI_HANDLE() and other basic ACPI calls were non-GPL-protected. Also, while I'm there, remove a tiny bit of redundancy that was missed in the earlier commit, by having is_acpi_node() use the other two routines, instead of checking fwnode directly. Fixes: db3e50f3234b (device property: Get rid of struct fwnode_handle type field) Signed-off-by: John Hubbard <jhubbard@nvidia.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-16 08:35:27 +08:00
static inline bool is_acpi_node(const struct fwnode_handle *fwnode)
{
ACPI / bus: Make ACPI_HANDLE() work for non-GPL code again Due to commit db3e50f3234b (device property: Get rid of struct fwnode_handle type field), ACPI_HANDLE() inadvertently became a GPL-only call. The call path that led to that was: ACPI_HANDLE() ACPI_COMPANION() to_acpi_device_node() is_acpi_device_node() acpi_device_fwnode_ops DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops); ...and the new DECLARE_ACPI_FWNODE_OPS() includes EXPORT_SYMBOL_GPL, whereas previously it was a static struct. In order to avoid changing any of that, let's instead provide ever so slightly better encapsulation of those struct fwnode_operations instances. Those do not really need to be directly used in inline function calls in header files. Simply moving two small functions (is_acpi_device_node and is_acpi_data_node) out of acpi_bus.h, and into a .c file, does that. That leaves the internals of struct fwnode_operations as GPL-only (which I think was the intent all along), but un-breaks any driver code out there that relies on the ACPI subsystem's being (historically) an EXPORT_SYMBOL-usable system. By that, I mean, ACPI_HANDLE() and other basic ACPI calls were non-GPL-protected. Also, while I'm there, remove a tiny bit of redundancy that was missed in the earlier commit, by having is_acpi_node() use the other two routines, instead of checking fwnode directly. Fixes: db3e50f3234b (device property: Get rid of struct fwnode_handle type field) Signed-off-by: John Hubbard <jhubbard@nvidia.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-16 08:35:27 +08:00
return (is_acpi_device_node(fwnode) || is_acpi_data_node(fwnode));
}
#define to_acpi_device_node(__fwnode) \
({ \
typeof(__fwnode) __to_acpi_device_node_fwnode = __fwnode; \
\
is_acpi_device_node(__to_acpi_device_node_fwnode) ? \
container_of(__to_acpi_device_node_fwnode, \
struct acpi_device, fwnode) : \
NULL; \
})
#define to_acpi_data_node(__fwnode) \
({ \
typeof(__fwnode) __to_acpi_data_node_fwnode = __fwnode; \
\
is_acpi_data_node(__to_acpi_data_node_fwnode) ? \
container_of(__to_acpi_data_node_fwnode, \
struct acpi_data_node, fwnode) : \
NULL; \
})
static inline bool is_acpi_static_node(const struct fwnode_handle *fwnode)
{
return !IS_ERR_OR_NULL(fwnode) &&
fwnode->ops == &acpi_static_fwnode_ops;
}
static inline bool acpi_data_node_match(const struct fwnode_handle *fwnode,
const char *name)
{
return is_acpi_data_node(fwnode) ?
(!strcmp(to_acpi_data_node(fwnode)->name, name)) : false;
}
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
{
return &adev->fwnode;
}
static inline void *acpi_driver_data(struct acpi_device *d)
{
return d->driver_data;
}
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
{
*((u32 *)&adev->status) = sta;
}
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
static inline void acpi_set_hp_context(struct acpi_device *adev,
struct acpi_hotplug_context *hp)
ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to the theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices or use the generic ACPI device hotplug code for device objects with matching scan handlers. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-07 00:31:37 +08:00
{
hp->self = adev;
adev->hp = hp;
}
void acpi_initialize_hp_context(struct acpi_device *adev,
struct acpi_hotplug_context *hp,
int (*notify)(struct acpi_device *, u32),
void (*uevent)(struct acpi_device *, u32));
/* acpi_device.dev.bus == &acpi_bus_type */
extern struct bus_type acpi_bus_type;
/*
* Events
* ------
*/
struct acpi_bus_event {
struct list_head node;
acpi_device_class device_class;
acpi_bus_id bus_id;
u32 type;
u32 data;
};
extern struct kobject *acpi_kobj;
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
void acpi_bus_private_data_handler(acpi_handle, void *);
int acpi_bus_get_private_data(acpi_handle, void **);
int acpi_bus_attach_private_data(acpi_handle, void *);
void acpi_bus_detach_private_data(acpi_handle);
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
extern int register_acpi_notifier(struct notifier_block *);
extern int unregister_acpi_notifier(struct notifier_block *);
/*
* External Functions
*/
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
ACPI / hotplug: Fix potential race in acpi_bus_notify() There is a slight possibility for the ACPI device object pointed to by adev in acpi_hotplug_notify_cb() to become invalid between the acpi_bus_get_device() that it comes from and the subsequent dereference of that pointer under get_device(). Namely, if acpi_scan_drop_device() runs in parallel with acpi_hotplug_notify_cb(), acpi_device_del_work_fn() queued up by it may delete the device object in question right after a successful execution of acpi_bus_get_device() in acpi_bus_notify(). An analogous problem is present in acpi_bus_notify() where the device pointer coming from acpi_bus_get_device() may become invalid before it subsequent dereference in the "if" block. To prevent that from happening, introduce a new function, acpi_bus_get_acpi_device(), working analogously to acpi_bus_get_device() except that it will grab a reference to the ACPI device object returned by it and it will do that under the ACPICA's namespace mutex. Then, make both acpi_hotplug_notify_cb() and acpi_bus_notify() use acpi_bus_get_acpi_device() instead of acpi_bus_get_device() so as to ensure that the pointers used by them will not become stale at one point. In addition to that, introduce acpi_bus_put_acpi_device() as a wrapper around put_device() to be used along with acpi_bus_get_acpi_device() and make the (new) users of the latter use acpi_bus_put_acpi_device() too. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2014-02-04 07:43:05 +08:00
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
void acpi_bus_put_acpi_device(struct acpi_device *adev);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_set_power(acpi_handle handle, int state);
const char *acpi_power_state_string(int state);
int acpi_device_get_power(struct acpi_device *device, int *state);
int acpi_device_set_power(struct acpi_device *device, int state);
int acpi_bus_init_power(struct acpi_device *device);
int acpi_device_fix_up_power(struct acpi_device *device);
int acpi_bus_update_power(acpi_handle handle, int *state_p);
int acpi_device_update_power(struct acpi_device *device, int *state_p);
bool acpi_bus_power_manageable(acpi_handle handle);
#ifdef CONFIG_PM
PCI ACPI: Rework PCI handling of wake-up * Introduce function acpi_pm_device_sleep_wake() for enabling and disabling the system wake-up capability of devices that are power manageable by ACPI. * Introduce function acpi_bus_can_wakeup() allowing other (dependent) subsystems to check if ACPI is able to enable the system wake-up capability of given device. * Introduce callback .sleep_wake() in struct pci_platform_pm_ops and for the ACPI PCI 'driver' make it use acpi_pm_device_sleep_wake(). * Introduce callback .can_wakeup() in struct pci_platform_pm_ops and for the ACPI 'driver' make it use acpi_bus_can_wakeup(). * Move the PME# handlig code out of pci_enable_wake() and split it into two functions, pci_pme_capable() and pci_pme_active(), allowing the caller to check if given device is capable of generating PME# from given power state and to enable/disable the device's PME# functionality, respectively. * Modify pci_enable_wake() to use the new ACPI callbacks and the new PME#-related functions. * Drop the generic .platform_enable_wakeup() callback that is not used any more. * Introduce device_set_wakeup_capable() that will set the power.can_wakeup flag of given device. * Rework PCI device PM initialization so that, if given device is capable of generating wake-up events, either natively through the PME# mechanism, or with the help of the platform, its power.can_wakeup flag is set and its power.should_wakeup flag is unset as appropriate. * Make ACPI set the power.can_wakeup flag for devices found to be wake-up capable by it. * Make the ACPI wake-up code enable/disable GPEs for devices that have the wakeup.flags.prepared flag set (which means that their wake-up power has been enabled). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-07-07 09:34:48 +08:00
bool acpi_bus_can_wakeup(acpi_handle handle);
#else
static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
#endif
ACPI / hotplug: Fix concurrency issues and memory leaks This changeset is aimed at fixing a few different but related problems in the ACPI hotplug infrastructure. First of all, since notify handlers may be run in parallel with acpi_bus_scan(), acpi_bus_trim() and acpi_bus_hot_remove_device() and some of them are installed for ACPI handles that have no struct acpi_device objects attached (i.e. before those objects are created), those notify handlers have to take acpi_scan_lock to prevent races from taking place (e.g. a struct acpi_device is found to be present for the given ACPI handle, but right after that it is removed by acpi_bus_trim() running in parallel to the given notify handler). Moreover, since some of them call acpi_bus_scan() and acpi_bus_trim(), this leads to the conclusion that acpi_scan_lock should be acquired by the callers of these two funtions rather by these functions themselves. For these reasons, make all notify handlers that can handle device addition and eject events take acpi_scan_lock and remove the acpi_scan_lock locking from acpi_bus_scan() and acpi_bus_trim(). Accordingly, update all of their users to make sure that they are always called under acpi_scan_lock. Furthermore, since eject operations are carried out asynchronously with respect to the notify events that trigger them, with the help of acpi_bus_hot_remove_device(), even if notify handlers take the ACPI scan lock, it still is possible that, for example, acpi_bus_trim() will run between acpi_bus_hot_remove_device() and the notify handler that scheduled its execution and that acpi_bus_trim() will remove the device node passed to acpi_bus_hot_remove_device() for ejection. In that case, the struct acpi_device object obtained by acpi_bus_hot_remove_device() will be invalid and not-so-funny things will ensue. To protect agaist that, make the users of acpi_bus_hot_remove_device() run get_device() on ACPI device node objects that are about to be passed to it and make acpi_bus_hot_remove_device() run put_device() on them and check if their ACPI handles are not NULL (make acpi_device_unregister() clear the device nodes' ACPI handles for that check to work). Finally, observe that acpi_os_hotplug_execute() actually can fail, in which case its caller ought to free memory allocated for the context object to prevent leaks from happening. It also needs to run put_device() on the device node that it ran get_device() on previously in that case. Modify the code accordingly. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Yinghai Lu <yinghai@kernel.org>
2013-02-13 21:36:47 +08:00
void acpi_scan_lock_acquire(void);
void acpi_scan_lock_release(void);
void acpi_lock_hp_context(void);
void acpi_unlock_hp_context(void);
int acpi_scan_add_handler(struct acpi_scan_handler *handler);
int acpi_bus_register_driver(struct acpi_driver *driver);
void acpi_bus_unregister_driver(struct acpi_driver *driver);
int acpi_bus_scan(acpi_handle handle);
void acpi_bus_trim(struct acpi_device *start);
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
int acpi_match_device_ids(struct acpi_device *device,
const struct acpi_device_id *ids);
void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
char *modalias, size_t len);
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);
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
static inline bool acpi_device_enumerated(struct acpi_device *adev)
{
return adev && adev->flags.initialized && adev->flags.visited;
}
/**
* module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
* @__acpi_driver: acpi_driver struct
*
* Helper macro for ACPI drivers which do not do anything special in module
* init/exit. This eliminates a lot of boilerplate. Each module may only
* use this macro once, and calling it replaces module_init() and module_exit()
*/
#define module_acpi_driver(__acpi_driver) \
module_driver(__acpi_driver, acpi_bus_register_driver, \
acpi_bus_unregister_driver)
/*
* Bind physical devices with ACPI devices
*/
struct acpi_bus_type {
struct list_head list;
const char *name;
bool (*match)(struct device *dev);
struct acpi_device * (*find_companion)(struct device *);
void (*setup)(struct device *);
void (*cleanup)(struct device *);
};
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
int acpi_unbind_one(struct device *dev);
struct acpi_pci_root {
struct acpi_device * device;
struct pci_bus *bus;
u16 segment;
struct resource secondary; /* downstream bus range */
u32 osc_support_set; /* _OSC state of support bits */
u32 osc_control_set; /* _OSC state of control bits */
phys_addr_t mcfg_addr;
};
/* helper */
bool acpi_dma_supported(struct acpi_device *adev);
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
u64 *size);
int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
ACPI: Implement acpi_dma_configure On DT based systems, the of_dma_configure() API implements DMA configuration for a given device. On ACPI systems an API equivalent to of_dma_configure() is missing which implies that it is currently not possible to set-up DMA operations for devices through the ACPI generic kernel layer. This patch fills the gap by introducing acpi_dma_configure/deconfigure() calls that for now are just wrappers around arch_setup_dma_ops() and arch_teardown_dma_ops() and also updates ACPI and PCI core code to use the newly introduced acpi_dma_configure/acpi_dma_deconfigure functions. Since acpi_dma_configure() is used to configure DMA operations, the function initializes the dma/coherent_dma masks to sane default values if the current masks are uninitialized (also to keep the default values consistent with DT systems) to make sure the device has a complete default DMA set-up. The DMA range size passed to arch_setup_dma_ops() is sized according to the device coherent_dma_mask (starting at address 0x0), mirroring the DT probing path behaviour when a dma-ranges property is not provided for the device being probed; this changes the current arch_setup_dma_ops() call parameters in the ACPI probing case, but since arch_setup_dma_ops() is a NOP on all architectures but ARM/ARM64 this patch does not change the current kernel behaviour on them. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> [pci] Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Tomasz Nowicki <tn@semihalf.com> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Tomasz Nowicki <tn@semihalf.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Robin Murphy <robin.murphy@arm.com> Cc: Tomasz Nowicki <tn@semihalf.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Signed-off-by: Will Deacon <will.deacon@arm.com>
2016-11-21 18:01:39 +08:00
void acpi_dma_deconfigure(struct device *dev);
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
u64 address, bool check_children);
int acpi_is_root_bridge(acpi_handle);
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
PCI / ACPI / PM: Platform support for PCI PME wake-up Although the majority of PCI devices can generate PMEs that in principle may be used to wake up devices suspended at run time, platform support is generally necessary to convert PMEs into wake-up events that can be delivered to the kernel. If ACPI is used for this purpose, PME signals generated by a PCI device will trigger the ACPI GPE associated with the device to generate an ACPI wake-up event that we can set up a handler for, provided that everything is configured correctly. Unfortunately, the subset of PCI devices that have GPEs associated with them is quite limited. The devices without dedicated GPEs have to rely on the GPEs associated with other devices (in the majority of cases their upstream bridges and, possibly, the root bridge) to generate ACPI wake-up events in response to PME signals from them. Add ACPI platform support for PCI PME wake-up: o Add a framework making is possible to use ACPI system notify handlers for run-time PM. o Add new PCI platform callback ->run_wake() to struct pci_platform_pm_ops allowing us to enable/disable the platform to generate wake-up events for given device. Implemet this callback for the ACPI platform. o Define ACPI wake-up handlers for PCI devices and PCI root buses and make the PCI-ACPI binding code register wake-up notifiers for all PCI devices present in the ACPI tables. o Add function pci_dev_run_wake() which can be used by PCI drivers to check if given device is capable of generating wake-up events at run time. Developed in cooperation with Matthew Garrett <mjg@redhat.com>. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2010-02-18 06:44:09 +08:00
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
#ifdef CONFIG_X86
bool acpi_device_always_present(struct acpi_device *adev);
#else
static inline bool acpi_device_always_present(struct acpi_device *adev)
{
return false;
}
#endif
#ifdef CONFIG_PM
ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ during suspend-to-idle transitions and, consequently, any events signaled through it wake up the system from that state. However, on some systems some of the events signaled via the ACPI SCI while suspended to idle should not cause the system to wake up. In fact, quite often they should just be discarded. Arguably, systems should not resume entirely on such events, but in order to decide which events really should cause the system to resume and which are spurious, it is necessary to resume up to the point when ACPI SCIs are actually handled and processed, which is after executing dpm_resume_noirq() in the system resume path. For this reasons, add a loop around freeze_enter() in which the platforms can process events signaled via multiplexed IRQ lines like the ACPI SCI and add suspend-to-idle hooks that can be used for this purpose to struct platform_freeze_ops. In the ACPI case, the ->wake hook is used for checking if the SCI has triggered while suspended and deferring the interrupt-induced system wakeup until the events signaled through it are actually processed sufficiently to decide whether or not the system should resume. In turn, the ->sync hook allows all of the relevant event queues to be flushed so as to prevent events from being missed due to race conditions. In addition to that, some ACPI code processing wakeup events needs to be modified to use the "hard" version of wakeup triggers, so that it will cause a system resume to happen on device-induced wakeup events even if the "soft" mechanism to prevent the system from suspending is not enabled. However, to preserve the existing behavior with respect to suspend-to-RAM, this only is done in the suspend-to-idle case and only if an SCI has occurred while suspended. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-13 04:56:34 +08:00
void acpi_pm_wakeup_event(struct device *dev);
acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
void (*func)(struct acpi_device_wakeup_context *context));
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
bool acpi_pm_device_can_wakeup(struct device *dev);
int acpi_pm_device_sleep_state(struct device *, int *, int);
int acpi_pm_set_device_wakeup(struct device *dev, bool enable);
ACPI / PCI / PM: Rework acpi_pci_propagate_wakeup() The acpi_pci_propagate_wakeup() routine is there to handle cases in which PCI bridges (or PCIe ports) are expected to signal wakeup for devices below them, but currently it doesn't do that correctly. The problem is that acpi_pci_propagate_wakeup() uses acpi_pm_set_device_wakeup() for bridges and if that routine is called for multiple times to disable wakeup for the same device, it will disable it on the first invocation and the next calls will have no effect (it works analogously when called to enable wakeup, but that is not a problem). Now, say acpi_pci_propagate_wakeup() has been called for two different devices under the same bridge and it has called acpi_pm_set_device_wakeup() for that bridge each time. The bridge is now enabled to generate wakeup signals. Next, suppose that one of the devices below it resumes and acpi_pci_propagate_wakeup() is called to disable wakeup for that device. It will then call acpi_pm_set_device_wakeup() for the bridge and that will effectively disable remote wakeup for all devices under it even though some of them may still be suspended and remote wakeup may be expected to work for them. To address this (arguably theoretical) issue, allow wakeup.enable_count under struct acpi_device to grow beyond 1 in certain situations. In particular, allow that to happen in acpi_pci_propagate_wakeup() when wakeup is enabled or disabled for PCI bridges, so that wakeup is actually disabled for the bridge when all devices under it resume and not when just one of them does that. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
2017-08-01 08:56:18 +08:00
int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable);
#else
ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ during suspend-to-idle transitions and, consequently, any events signaled through it wake up the system from that state. However, on some systems some of the events signaled via the ACPI SCI while suspended to idle should not cause the system to wake up. In fact, quite often they should just be discarded. Arguably, systems should not resume entirely on such events, but in order to decide which events really should cause the system to resume and which are spurious, it is necessary to resume up to the point when ACPI SCIs are actually handled and processed, which is after executing dpm_resume_noirq() in the system resume path. For this reasons, add a loop around freeze_enter() in which the platforms can process events signaled via multiplexed IRQ lines like the ACPI SCI and add suspend-to-idle hooks that can be used for this purpose to struct platform_freeze_ops. In the ACPI case, the ->wake hook is used for checking if the SCI has triggered while suspended and deferring the interrupt-induced system wakeup until the events signaled through it are actually processed sufficiently to decide whether or not the system should resume. In turn, the ->sync hook allows all of the relevant event queues to be flushed so as to prevent events from being missed due to race conditions. In addition to that, some ACPI code processing wakeup events needs to be modified to use the "hard" version of wakeup triggers, so that it will cause a system resume to happen on device-induced wakeup events even if the "soft" mechanism to prevent the system from suspending is not enabled. However, to preserve the existing behavior with respect to suspend-to-RAM, this only is done in the suspend-to-idle case and only if an SCI has occurred while suspended. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-13 04:56:34 +08:00
static inline void acpi_pm_wakeup_event(struct device *dev)
{
}
static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
struct device *dev,
ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ during suspend-to-idle transitions and, consequently, any events signaled through it wake up the system from that state. However, on some systems some of the events signaled via the ACPI SCI while suspended to idle should not cause the system to wake up. In fact, quite often they should just be discarded. Arguably, systems should not resume entirely on such events, but in order to decide which events really should cause the system to resume and which are spurious, it is necessary to resume up to the point when ACPI SCIs are actually handled and processed, which is after executing dpm_resume_noirq() in the system resume path. For this reasons, add a loop around freeze_enter() in which the platforms can process events signaled via multiplexed IRQ lines like the ACPI SCI and add suspend-to-idle hooks that can be used for this purpose to struct platform_freeze_ops. In the ACPI case, the ->wake hook is used for checking if the SCI has triggered while suspended and deferring the interrupt-induced system wakeup until the events signaled through it are actually processed sufficiently to decide whether or not the system should resume. In turn, the ->sync hook allows all of the relevant event queues to be flushed so as to prevent events from being missed due to race conditions. In addition to that, some ACPI code processing wakeup events needs to be modified to use the "hard" version of wakeup triggers, so that it will cause a system resume to happen on device-induced wakeup events even if the "soft" mechanism to prevent the system from suspending is not enabled. However, to preserve the existing behavior with respect to suspend-to-RAM, this only is done in the suspend-to-idle case and only if an SCI has occurred while suspended. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-13 04:56:34 +08:00
void (*func)(struct acpi_device_wakeup_context *context))
{
return AE_SUPPORT;
}
static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
{
return AE_SUPPORT;
}
static inline bool acpi_pm_device_can_wakeup(struct device *dev)
{
return false;
}
static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
{
if (p)
*p = ACPI_STATE_D0;
return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
m : ACPI_STATE_D0;
}
static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
{
return -ENODEV;
}
ACPI / PCI / PM: Rework acpi_pci_propagate_wakeup() The acpi_pci_propagate_wakeup() routine is there to handle cases in which PCI bridges (or PCIe ports) are expected to signal wakeup for devices below them, but currently it doesn't do that correctly. The problem is that acpi_pci_propagate_wakeup() uses acpi_pm_set_device_wakeup() for bridges and if that routine is called for multiple times to disable wakeup for the same device, it will disable it on the first invocation and the next calls will have no effect (it works analogously when called to enable wakeup, but that is not a problem). Now, say acpi_pci_propagate_wakeup() has been called for two different devices under the same bridge and it has called acpi_pm_set_device_wakeup() for that bridge each time. The bridge is now enabled to generate wakeup signals. Next, suppose that one of the devices below it resumes and acpi_pci_propagate_wakeup() is called to disable wakeup for that device. It will then call acpi_pm_set_device_wakeup() for the bridge and that will effectively disable remote wakeup for all devices under it even though some of them may still be suspended and remote wakeup may be expected to work for them. To address this (arguably theoretical) issue, allow wakeup.enable_count under struct acpi_device to grow beyond 1 in certain situations. In particular, allow that to happen in acpi_pci_propagate_wakeup() when wakeup is enabled or disabled for PCI bridges, so that wakeup is actually disabled for the bridge when all devices under it resume and not when just one of them does that. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
2017-08-01 08:56:18 +08:00
static inline int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_ACPI_SLEEP
u32 acpi_target_system_state(void);
#else
static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; }
#endif
static inline bool acpi_device_power_manageable(struct acpi_device *adev)
{
return adev->flags.power_manageable;
}
static inline bool acpi_device_can_wakeup(struct acpi_device *adev)
{
return adev->wakeup.flags.valid;
}
static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
{
return adev->power.states[ACPI_STATE_D3_COLD].flags.valid ||
((acpi_gbl_FADT.header.revision < 6) &&
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
}
#else /* CONFIG_ACPI */
static inline int register_acpi_bus_type(void *bus) { return 0; }
static inline int unregister_acpi_bus_type(void *bus) { return 0; }
#endif /* CONFIG_ACPI */
#endif /*__ACPI_BUS_H__*/