2019-05-27 06:55:06 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __ACPI_BUS_H__
|
|
|
|
#define __ACPI_BUS_H__
|
|
|
|
|
2024-03-25 12:32:58 +00:00
|
|
|
#include <linux/completion.h>
|
|
|
|
#include <linux/container_of.h>
|
2006-05-10 14:33:00 +00:00
|
|
|
#include <linux/device.h>
|
2024-03-25 12:32:58 +00:00
|
|
|
#include <linux/kobject.h>
|
|
|
|
#include <linux/mutex.h>
|
2014-11-04 13:03:59 +00:00
|
|
|
#include <linux/property.h>
|
2024-03-25 12:32:58 +00:00
|
|
|
#include <linux/types.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
struct acpi_handle_list {
|
2005-08-05 04:44:28 +00:00
|
|
|
u32 count;
|
2023-12-08 20:07:41 +00:00
|
|
|
acpi_handle *handles;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* acpi_utils.h */
|
|
|
|
acpi_status
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_extract_package(union acpi_object *package,
|
|
|
|
struct acpi_buffer *format, struct acpi_buffer *buffer);
|
2005-04-16 22:20:36 +00:00
|
|
|
acpi_status
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_evaluate_integer(acpi_handle handle,
|
|
|
|
acpi_string pathname,
|
2008-10-10 06:22:59 +00:00
|
|
|
struct acpi_object_list *arguments, unsigned long long *data);
|
2023-12-08 20:06:04 +00:00
|
|
|
bool acpi_evaluate_reference(acpi_handle handle, acpi_string pathname,
|
|
|
|
struct acpi_object_list *arguments,
|
|
|
|
struct acpi_handle_list *list);
|
2023-09-27 20:17:25 +00:00
|
|
|
bool acpi_handle_list_equal(struct acpi_handle_list *list1,
|
|
|
|
struct acpi_handle_list *list2);
|
|
|
|
void acpi_handle_list_replace(struct acpi_handle_list *dst,
|
|
|
|
struct acpi_handle_list *src);
|
|
|
|
void acpi_handle_list_free(struct acpi_handle_list *list);
|
2023-12-14 11:07:55 +00:00
|
|
|
bool acpi_device_dep(acpi_handle target, acpi_handle match);
|
2012-05-24 02:25:19 +00:00
|
|
|
acpi_status
|
2014-02-19 06:02:15 +00:00
|
|
|
acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
|
|
|
|
struct acpi_buffer *status_buf);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2012-05-11 08:08:26 +00:00
|
|
|
acpi_status
|
2012-08-21 01:56:58 +00:00
|
|
|
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
|
2013-06-28 16:24:38 +00:00
|
|
|
|
|
|
|
bool acpi_has_method(acpi_handle handle, char *name);
|
2013-06-28 16:24:39 +00:00
|
|
|
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
|
|
|
|
u64 arg);
|
2013-06-28 16:24:40 +00:00
|
|
|
acpi_status acpi_evaluate_ej0(acpi_handle handle);
|
|
|
|
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock);
|
2020-05-07 10:49:16 +00:00
|
|
|
acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function);
|
2013-06-28 16:24:41 +00:00
|
|
|
bool acpi_ata_match(acpi_handle handle);
|
|
|
|
bool acpi_bay_match(acpi_handle handle);
|
|
|
|
bool acpi_dock_match(acpi_handle handle);
|
2013-06-28 16:24:38 +00:00
|
|
|
|
2017-06-05 16:40:46 +00:00
|
|
|
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,
|
2016-04-11 22:02:26 +00:00
|
|
|
u64 rev, u64 func, union acpi_object *argv4);
|
ACPI: utils: Fix acpi_evaluate_dsm_typed() redefinition error
acpi_evaluate_dsm_typed() needs to be gaurded with CONFIG_ACPI to avoid
a redefintion error when the stub is also enabled.
In file included from ../drivers/bluetooth/btintel.c:13:
../include/acpi/acpi_bus.h:57:1: error: redefinition of 'acpi_evaluate_dsm_typed'
57 | acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid,..
| ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ../drivers/bluetooth/btintel.c:12:
../include/linux/acpi.h:967:34: note: previous definition of
'acpi_evaluate_dsm_typed' with type 'union acpi_object *(void *,
const guid_t *, u64, u64, union acpi_object *, acpi_object_type)'
{aka 'union acpi_object *(void *, const guid_t *, long long unsigned int,
long long unsigned int, union acpi_object *, unsigned int)'}
967 | static inline union acpi_object
*acpi_evaluate_dsm_typed(acpi_handle handle,
Fixes: 1b94ad7ccc21 ("ACPI: utils: Add acpi_evaluate_dsm_typed() and acpi_check_dsm() stubs")
Signed-off-by: Kiran K <kiran.k@intel.com>
[ rjw: Subject and changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-03-16 07:17:15 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
2013-12-19 12:38:10 +00:00
|
|
|
static inline union acpi_object *
|
2017-06-05 16:40:46 +00:00
|
|
|
acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
|
|
|
|
u64 func, union acpi_object *argv4,
|
|
|
|
acpi_object_type type)
|
2013-12-19 12:38:10 +00:00
|
|
|
{
|
|
|
|
union acpi_object *obj;
|
|
|
|
|
2017-06-05 16:40:46 +00:00
|
|
|
obj = acpi_evaluate_dsm(handle, guid, rev, func, argv4);
|
2013-12-19 12:38:10 +00:00
|
|
|
if (obj && obj->type != type) {
|
|
|
|
ACPI_FREE(obj);
|
|
|
|
obj = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
ACPI: utils: Fix acpi_evaluate_dsm_typed() redefinition error
acpi_evaluate_dsm_typed() needs to be gaurded with CONFIG_ACPI to avoid
a redefintion error when the stub is also enabled.
In file included from ../drivers/bluetooth/btintel.c:13:
../include/acpi/acpi_bus.h:57:1: error: redefinition of 'acpi_evaluate_dsm_typed'
57 | acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid,..
| ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ../drivers/bluetooth/btintel.c:12:
../include/linux/acpi.h:967:34: note: previous definition of
'acpi_evaluate_dsm_typed' with type 'union acpi_object *(void *,
const guid_t *, u64, u64, union acpi_object *, acpi_object_type)'
{aka 'union acpi_object *(void *, const guid_t *, long long unsigned int,
long long unsigned int, union acpi_object *, unsigned int)'}
967 | static inline union acpi_object
*acpi_evaluate_dsm_typed(acpi_handle handle,
Fixes: 1b94ad7ccc21 ("ACPI: utils: Add acpi_evaluate_dsm_typed() and acpi_check_dsm() stubs")
Signed-off-by: Kiran K <kiran.k@intel.com>
[ rjw: Subject and changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-03-16 07:17:15 +00:00
|
|
|
#endif
|
2013-12-19 12:38:10 +00:00
|
|
|
|
|
|
|
#define ACPI_INIT_DSM_ARGV4(cnt, eles) \
|
|
|
|
{ \
|
|
|
|
.package.type = ACPI_TYPE_PACKAGE, \
|
|
|
|
.package.count = (cnt), \
|
|
|
|
.package.elements = (eles) \
|
|
|
|
}
|
|
|
|
|
2016-03-24 12:15:20 +00:00
|
|
|
bool acpi_dev_found(const char *hid);
|
2017-04-19 12:02:08 +00:00
|
|
|
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
2021-04-07 17:58:20 +00:00
|
|
|
bool acpi_reduced_hardware(void);
|
2015-11-25 20:19:55 +00:00
|
|
|
|
2005-08-24 16:10:49 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2020-03-21 11:25:49 +00:00
|
|
|
struct proc_dir_entry;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#define ACPI_BUS_FILE_ROOT "acpi"
|
2005-08-05 04:44:28 +00:00
|
|
|
extern struct proc_dir_entry *acpi_root_dir;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
enum acpi_bus_device_type {
|
2005-08-05 04:44:28 +00:00
|
|
|
ACPI_BUS_TYPE_DEVICE = 0,
|
2005-04-16 22:20:36 +00:00
|
|
|
ACPI_BUS_TYPE_POWER,
|
|
|
|
ACPI_BUS_TYPE_PROCESSOR,
|
|
|
|
ACPI_BUS_TYPE_THERMAL,
|
|
|
|
ACPI_BUS_TYPE_POWER_BUTTON,
|
|
|
|
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
2017-09-26 08:54:09 +00:00
|
|
|
ACPI_BUS_TYPE_ECDT_EC,
|
2005-04-16 22:20:36 +00:00
|
|
|
ACPI_BUS_DEVICE_TYPE_COUNT
|
|
|
|
};
|
|
|
|
|
|
|
|
struct acpi_driver;
|
|
|
|
struct acpi_device;
|
|
|
|
|
2013-01-30 13:27:29 +00:00
|
|
|
/*
|
|
|
|
* ACPI Scan Handler
|
|
|
|
* -----------------
|
|
|
|
*/
|
|
|
|
|
2013-03-03 22:05:29 +00:00
|
|
|
struct acpi_hotplug_profile {
|
2013-03-03 22:08:16 +00:00
|
|
|
struct kobject kobj;
|
2013-11-22 20:55:20 +00:00
|
|
|
int (*scan_dependent)(struct acpi_device *adev);
|
2014-09-21 00:58:18 +00:00
|
|
|
void (*notify_online)(struct acpi_device *adev);
|
2013-12-29 14:25:35 +00:00
|
|
|
bool enabled:1;
|
|
|
|
bool demand_offline:1;
|
2013-03-03 22:05:29 +00:00
|
|
|
};
|
|
|
|
|
2013-03-03 22:08:16 +00:00
|
|
|
static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile(
|
|
|
|
struct kobject *kobj)
|
|
|
|
{
|
|
|
|
return container_of(kobj, struct acpi_hotplug_profile, kobj);
|
|
|
|
}
|
|
|
|
|
2013-01-30 13:27:29 +00:00
|
|
|
struct acpi_scan_handler {
|
|
|
|
struct list_head list_node;
|
2024-03-25 12:32:57 +00:00
|
|
|
const struct acpi_device_id *ids;
|
2015-09-09 21:59:41 +00:00
|
|
|
bool (*match)(const char *idstr, const struct acpi_device_id **matchid);
|
2013-01-30 13:27:29 +00:00
|
|
|
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
|
|
|
|
void (*detach)(struct acpi_device *dev);
|
2024-05-29 13:34:37 +00:00
|
|
|
void (*post_eject)(struct acpi_device *dev);
|
2014-02-10 23:35:46 +00:00
|
|
|
void (*bind)(struct device *phys_dev);
|
|
|
|
void (*unbind)(struct device *phys_dev);
|
2013-03-03 22:05:29 +00:00
|
|
|
struct acpi_hotplug_profile hotplug;
|
2013-01-30 13:27:29 +00:00
|
|
|
};
|
|
|
|
|
2014-02-06 16:31:37 +00:00
|
|
|
/*
|
|
|
|
* ACPI Hotplug Context
|
|
|
|
* --------------------
|
|
|
|
*/
|
|
|
|
|
2024-03-25 12:33:03 +00:00
|
|
|
typedef int (*acpi_hp_notify) (struct acpi_device *, u32);
|
|
|
|
typedef void (*acpi_hp_uevent) (struct acpi_device *, u32);
|
|
|
|
typedef void (*acpi_hp_fixup) (struct acpi_device *);
|
|
|
|
|
2014-02-06 16:31:37 +00:00
|
|
|
struct acpi_hotplug_context {
|
|
|
|
struct acpi_device *self;
|
2024-03-25 12:33:03 +00:00
|
|
|
acpi_hp_notify notify;
|
|
|
|
acpi_hp_uevent uevent;
|
|
|
|
acpi_hp_fixup fixup;
|
2014-02-06 16:31:37 +00:00
|
|
|
};
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* ACPI Driver
|
|
|
|
* -----------
|
|
|
|
*/
|
|
|
|
|
2005-08-05 04:44:28 +00:00
|
|
|
typedef int (*acpi_op_add) (struct acpi_device * device);
|
2022-11-13 16:26:09 +00:00
|
|
|
typedef void (*acpi_op_remove) (struct acpi_device *device);
|
2009-03-30 17:48:13 +00:00
|
|
|
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
struct acpi_device_ops {
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_op_add add;
|
|
|
|
acpi_op_remove remove;
|
2009-03-30 17:48:13 +00:00
|
|
|
acpi_op_notify notify;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2009-04-30 15:35:37 +00:00
|
|
|
#define ACPI_DRIVER_ALL_NOTIFY_EVENTS 0x1 /* system AND device events */
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_driver {
|
2005-08-05 04:44:28 +00:00
|
|
|
char name[80];
|
|
|
|
char class[80];
|
2007-07-23 12:43:32 +00:00
|
|
|
const struct acpi_device_id *ids; /* Supported Hardware IDs */
|
2009-04-30 15:35:37 +00:00
|
|
|
unsigned int flags;
|
2005-08-05 04:44:28 +00:00
|
|
|
struct acpi_device_ops ops;
|
2006-12-07 12:56:23 +00:00
|
|
|
struct device_driver drv;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ACPI Device
|
|
|
|
* -----------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Status (_STA) */
|
|
|
|
|
|
|
|
struct acpi_device_status {
|
2005-08-05 04:44:28 +00:00
|
|
|
u32 present:1;
|
|
|
|
u32 enabled:1;
|
|
|
|
u32 show_in_ui:1;
|
|
|
|
u32 functional:1;
|
|
|
|
u32 battery_present:1;
|
|
|
|
u32 reserved:27;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Flags */
|
|
|
|
|
|
|
|
struct acpi_device_flags {
|
2005-08-05 04:44:28 +00:00
|
|
|
u32 dynamic_status:1;
|
|
|
|
u32 removable:1;
|
|
|
|
u32 ejectable:1;
|
|
|
|
u32 power_manageable:1;
|
2012-12-20 23:36:48 +00:00
|
|
|
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-22 20:54:37 +00:00
|
|
|
u32 initialized:1;
|
|
|
|
u32 visited:1;
|
2014-02-06 16:31:37 +00: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 00:51:01 +00:00
|
|
|
u32 is_dock_station:1;
|
2015-05-05 13:43:07 +00:00
|
|
|
u32 of_compatible_ok:1;
|
2015-06-10 16:08:52 +00:00
|
|
|
u32 coherent_dma:1;
|
|
|
|
u32 cca_seen:1;
|
2018-03-14 18:15:56 +00:00
|
|
|
u32 enumeration_by_parent:1;
|
ACPI: delay enumeration of devices with a _DEP pointing to an INT3472 device
The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.
To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.
This causes problems with the probe ordering wrt drivers for consumers
of these clks/regulators. Since the lookups are only registered when the
provider-driver binds, trying to get these clks/regulators before then
results in a -ENOENT error for clks and a dummy regulator for regulators.
One case where we hit this issue is camera sensors such as e.g. the OV8865
sensor found on the Microsoft Surface Go. The sensor uses clks, regulators
and GPIOs provided by a TPS68470 PMIC which is described in an INT3472
ACPI device. There is special platform code handling this and setting
platform_data with the necessary consumer info on the MFD cells
instantiated for the PMIC under: drivers/platform/x86/intel/int3472.
For this to work properly the ov8865 driver must not bind to the I2C-client
for the OV8865 sensor until after the TPS68470 PMIC gpio, regulator and
clk MFD cells have all been fully setup.
The OV8865 on the Microsoft Surface Go is just one example, all X86
devices using the Intel IPU3 camera block found on recent Intel SoCs
have similar issues where there is an INT3472 HID ACPI-device, which
describes the clks and regulators, and the driver for this INT3472 device
must be fully initialized before the sensor driver (any sensor driver)
binds for things to work properly.
On these devices the ACPI nodes describing the sensors all have a _DEP
dependency on the matching INT3472 ACPI device (there is one per sensor).
This allows solving the probe-ordering problem by delaying the enumeration
(instantiation of the I2C-client in the ov8865 example) of ACPI-devices
which have a _DEP dependency on an INT3472 device.
The new acpi_dev_ready_for_enumeration() helper used for this is also
exported because for devices, which have the enumeration_by_parent flag
set, the parent-driver will do its own scan of child ACPI devices and
it will try to enumerate those during its probe(). Code doing this such
as e.g. the i2c-core-acpi.c code must call this new helper to ensure
that it too delays the enumeration until all the _DEP dependencies are
met on devices which have the new honor_deps flag set.
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20211203102857.44539-2-hdegoede@redhat.com
2021-12-03 10:28:44 +00:00
|
|
|
u32 honor_deps:1;
|
|
|
|
u32 reserved:18;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* File System */
|
|
|
|
|
|
|
|
struct acpi_device_dir {
|
2005-08-05 04:44:28 +00:00
|
|
|
struct proc_dir_entry *entry;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define acpi_device_dir(d) ((d)->dir.entry)
|
|
|
|
|
|
|
|
/* Plug and Play */
|
|
|
|
|
2009-05-21 08:25:35 +00:00
|
|
|
typedef char acpi_bus_id[8];
|
2019-05-01 12:53:22 +00:00
|
|
|
typedef u64 acpi_bus_address;
|
2005-08-05 04:44:28 +00:00
|
|
|
typedef char acpi_device_name[40];
|
|
|
|
typedef char acpi_device_class[20];
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2009-09-21 19:35:19 +00:00
|
|
|
struct acpi_hardware_id {
|
|
|
|
struct list_head list;
|
2015-09-09 21:59:42 +00:00
|
|
|
const char *id;
|
2009-09-21 19:35:19 +00:00
|
|
|
};
|
|
|
|
|
2013-03-04 21:30:41 +00:00
|
|
|
struct acpi_pnp_type {
|
|
|
|
u32 hardware_id:1;
|
|
|
|
u32 bus_address:1;
|
2014-05-30 02:26:18 +00:00
|
|
|
u32 platform_id:1;
|
ACPI: Fix selecting wrong ACPI fwnode for the iGPU on some Dell laptops
The Dell Latitude E6430 both with and without the optional NVidia dGPU
has a bug in its ACPI tables which is causing Linux to assign the wrong
ACPI fwnode / companion to the pci_device for the i915 iGPU.
Specifically under the PCI root bridge there are these 2 ACPI Device()s :
Scope (_SB.PCI0)
{
Device (GFX0)
{
Name (_ADR, 0x00020000) // _ADR: Address
}
...
Device (VID)
{
Name (_ADR, 0x00020000) // _ADR: Address
...
Method (_DOS, 1, NotSerialized) // _DOS: Disable Output Switching
{
VDP8 = Arg0
VDP1 (One, VDP8)
}
Method (_DOD, 0, NotSerialized) // _DOD: Display Output Devices
{
...
}
...
}
}
The non-functional GFX0 ACPI device is a problem, because this gets
returned as ACPI companion-device by acpi_find_child_device() for the iGPU.
This is a long standing problem and the i915 driver does use the ACPI
companion for some things, but works fine without it.
However since commit 63f534b8bad9 ("ACPI: PCI: Rework acpi_get_pci_dev()")
acpi_get_pci_dev() relies on the physical-node pointer in the acpi_device
and that is set on the wrong acpi_device because of the wrong
acpi_find_child_device() return. This breaks the ACPI video code,
leading to non working backlight control in some cases.
Add a type.backlight flag, mark ACPI video bus devices with this and make
find_child_checks() return a higher score for children with this flag set,
so that it picks the right companion-device.
Fixes: 63f534b8bad9 ("ACPI: PCI: Rework acpi_get_pci_dev()")
Co-developed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Cc: 6.1+ <stable@vger.kernel.org> # 6.1+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-01-10 15:30:28 +00:00
|
|
|
u32 backlight:1;
|
|
|
|
u32 reserved:28;
|
2013-03-04 21:30:41 +00:00
|
|
|
};
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_pnp {
|
2013-03-04 21:30:41 +00:00
|
|
|
acpi_bus_id bus_id; /* Object name */
|
2021-03-22 16:31:00 +00:00
|
|
|
int instance_no; /* Instance number of this object */
|
2013-03-04 21:30:41 +00:00
|
|
|
struct acpi_pnp_type type; /* ID type */
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_bus_address bus_address; /* _ADR */
|
2013-03-04 21:30:41 +00:00
|
|
|
char *unique_id; /* _UID */
|
2009-09-21 19:35:19 +00:00
|
|
|
struct list_head ids; /* _HID and _CIDs */
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_device_name device_name; /* Driver-determined */
|
|
|
|
acpi_device_class device_class; /* " */
|
2012-10-02 18:43:23 +00:00
|
|
|
union acpi_object *str_obj; /* unicode string for _STR method */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define acpi_device_bid(d) ((d)->pnp.bus_id)
|
|
|
|
#define acpi_device_adr(d) ((d)->pnp.bus_address)
|
2010-10-01 08:54:00 +00:00
|
|
|
const char *acpi_device_hid(struct acpi_device *device);
|
2015-03-17 09:48:30 +00:00
|
|
|
#define acpi_device_uid(d) ((d)->pnp.unique_id)
|
2005-04-16 22:20:36 +00:00
|
|
|
#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 {
|
2005-08-05 04:44:28 +00:00
|
|
|
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 */
|
2013-10-10 10:28:46 +00:00
|
|
|
u32 ignore_parent:1; /* Power is independent of parent power state */
|
2014-05-16 22:18:13 +00:00
|
|
|
u32 dsw_present:1; /* _DSW present? */
|
|
|
|
u32 reserved:26;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct acpi_device_power_state {
|
2024-03-25 12:32:57 +00:00
|
|
|
struct list_head resources; /* Power resources referenced */
|
2005-04-16 22:20:36 +00:00
|
|
|
struct {
|
2005-08-05 04:44:28 +00:00
|
|
|
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) */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct acpi_device_power {
|
2005-08-05 04:44:28 +00:00
|
|
|
int state; /* Current state */
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_power_flags flags;
|
2011-06-01 15:54:02 +00:00
|
|
|
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
|
2021-10-18 12:17:24 +00:00
|
|
|
u8 state_for_enumeration; /* Deepest power state for enumeration */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2021-06-03 22:40:02 +00:00
|
|
|
struct acpi_dep_data {
|
|
|
|
struct list_head node;
|
|
|
|
acpi_handle supplier;
|
|
|
|
acpi_handle consumer;
|
ACPI: delay enumeration of devices with a _DEP pointing to an INT3472 device
The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.
To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.
This causes problems with the probe ordering wrt drivers for consumers
of these clks/regulators. Since the lookups are only registered when the
provider-driver binds, trying to get these clks/regulators before then
results in a -ENOENT error for clks and a dummy regulator for regulators.
One case where we hit this issue is camera sensors such as e.g. the OV8865
sensor found on the Microsoft Surface Go. The sensor uses clks, regulators
and GPIOs provided by a TPS68470 PMIC which is described in an INT3472
ACPI device. There is special platform code handling this and setting
platform_data with the necessary consumer info on the MFD cells
instantiated for the PMIC under: drivers/platform/x86/intel/int3472.
For this to work properly the ov8865 driver must not bind to the I2C-client
for the OV8865 sensor until after the TPS68470 PMIC gpio, regulator and
clk MFD cells have all been fully setup.
The OV8865 on the Microsoft Surface Go is just one example, all X86
devices using the Intel IPU3 camera block found on recent Intel SoCs
have similar issues where there is an INT3472 HID ACPI-device, which
describes the clks and regulators, and the driver for this INT3472 device
must be fully initialized before the sensor driver (any sensor driver)
binds for things to work properly.
On these devices the ACPI nodes describing the sensors all have a _DEP
dependency on the matching INT3472 ACPI device (there is one per sensor).
This allows solving the probe-ordering problem by delaying the enumeration
(instantiation of the I2C-client in the ov8865 example) of ACPI-devices
which have a _DEP dependency on an INT3472 device.
The new acpi_dev_ready_for_enumeration() helper used for this is also
exported because for devices, which have the enumeration_by_parent flag
set, the parent-driver will do its own scan of child ACPI devices and
it will try to enumerate those during its probe(). Code doing this such
as e.g. the i2c-core-acpi.c code must call this new helper to ensure
that it too delays the enumeration until all the _DEP dependencies are
met on devices which have the new honor_deps flag set.
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20211203102857.44539-2-hdegoede@redhat.com
2021-12-03 10:28:44 +00:00
|
|
|
bool honor_dep;
|
2023-05-16 10:25:22 +00:00
|
|
|
bool met;
|
|
|
|
bool free_when_met;
|
2021-06-03 22:40:02 +00:00
|
|
|
};
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Performance Management */
|
|
|
|
|
|
|
|
struct acpi_device_perf_flags {
|
2005-08-05 04:44:28 +00:00
|
|
|
u8 reserved:8;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct acpi_device_perf_state {
|
|
|
|
struct {
|
2005-08-05 04:44:28 +00:00
|
|
|
u8 valid:1;
|
|
|
|
u8 reserved:7;
|
|
|
|
} flags;
|
|
|
|
u8 power; /* % Power (compared to P0) */
|
|
|
|
u8 performance; /* % Performance ( " ) */
|
|
|
|
int latency; /* Px->P0 time (microseconds) */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct acpi_device_perf {
|
2005-08-05 04:44:28 +00:00
|
|
|
int state;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_perf_flags flags;
|
2005-08-05 04:44:28 +00:00
|
|
|
int state_count;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_perf_state *states;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Wakeup Management */
|
|
|
|
struct acpi_device_wakeup_flags {
|
2005-08-05 04:44:28 +00:00
|
|
|
u8 valid:1; /* Can successfully enable wakeup? */
|
2010-02-17 22:44:09 +00:00
|
|
|
u8 notifier_present:1; /* Wake-up notify handler has been installed */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2014-07-22 23:00:45 +00:00
|
|
|
struct acpi_device_wakeup_context {
|
2017-06-12 20:48:41 +00:00
|
|
|
void (*func)(struct acpi_device_wakeup_context *context);
|
2014-07-22 23:00:45 +00:00
|
|
|
struct device *dev;
|
|
|
|
};
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_wakeup {
|
2005-08-05 04:44:28 +00:00
|
|
|
acpi_handle gpe_device;
|
2010-01-28 02:53:19 +00:00
|
|
|
u64 gpe_number;
|
|
|
|
u64 sleep_state;
|
2013-01-17 13:11:06 +00:00
|
|
|
struct list_head resources;
|
2005-08-05 04:44:28 +00:00
|
|
|
struct acpi_device_wakeup_flags flags;
|
2014-07-22 23:00:45 +00:00
|
|
|
struct acpi_device_wakeup_context context;
|
|
|
|
struct wakeup_source *ws;
|
2009-09-08 21:15:31 +00:00
|
|
|
int prepare_count;
|
2017-07-21 12:40:49 +00:00
|
|
|
int enable_count;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2012-08-17 06:44:09 +00:00
|
|
|
struct acpi_device_physical_node {
|
|
|
|
struct list_head node;
|
|
|
|
struct device *dev;
|
2024-03-25 12:32:57 +00:00
|
|
|
unsigned int node_id;
|
2013-05-02 22:26:16 +00:00
|
|
|
bool put_online:1;
|
2012-08-17 06:44:09 +00:00
|
|
|
};
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2018-09-27 21:57:05 +00:00
|
|
|
struct acpi_device_properties {
|
2024-03-25 12:32:57 +00:00
|
|
|
struct list_head list;
|
2018-09-27 21:57:05 +00:00
|
|
|
const guid_t *guid;
|
2022-07-22 06:57:46 +00:00
|
|
|
union acpi_object *properties;
|
|
|
|
void **bufs;
|
2018-09-27 21:57:05 +00:00
|
|
|
};
|
|
|
|
|
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 11:33:55 +00:00
|
|
|
/* ACPI Device Specific Data (_DSD) */
|
|
|
|
struct acpi_device_data {
|
|
|
|
const union acpi_object *pointer;
|
2018-09-27 21:57:05 +00:00
|
|
|
struct list_head properties;
|
2014-10-21 11:33:56 +00:00
|
|
|
const union acpi_object *of_compatible;
|
2015-08-27 02:36:14 +00: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 11:33:55 +00:00
|
|
|
};
|
|
|
|
|
ACPI / GPIO: Driver GPIO mappings for ACPI GPIOs
Provide a way for device drivers using GPIOs described by ACPI
GpioIo resources in _CRS to tell the GPIO subsystem what names
(connection IDs) to associate with specific GPIO pins defined
in there.
To do that, a driver needs to define a mapping table as a
NULL-terminated array of struct acpi_gpio_mapping objects
that each contain a name, a pointer to an array of line data
(struct acpi_gpio_params) objects and the size of that array.
Each struct acpi_gpio_params object consists of three fields,
crs_entry_index, line_index, active_low, representing the index of
the target GpioIo()/GpioInt() resource in _CRS starting from zero,
the index of the target line in that resource starting from zero,
and the active-low flag for that line, respectively.
Next, the mapping table needs to be passed as the second
argument to acpi_dev_add_driver_gpios() that will register it with
the ACPI device object pointed to by its first argument. That
should be done in the driver's .probe() routine.
On removal, the driver should unregister its GPIO mapping table
by calling acpi_dev_remove_driver_gpios() on the ACPI device
object where that table was previously registered.
Included are fixes from Mika Westerberg.
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-03 22:39:41 +00:00
|
|
|
struct acpi_gpio_mapping;
|
|
|
|
|
2023-11-07 19:19:42 +00:00
|
|
|
#define ACPI_DEVICE_SWNODE_ROOT 0
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The maximum expected number of CSI-2 data lanes.
|
|
|
|
*
|
|
|
|
* This number is not expected to ever have to be equal to or greater than the
|
|
|
|
* number of bits in an unsigned long variable, but if it needs to be increased
|
|
|
|
* above that limit, code will need to be adjusted accordingly.
|
|
|
|
*/
|
2023-11-06 16:16:26 +00:00
|
|
|
#define ACPI_DEVICE_CSI2_DATA_LANES 8
|
|
|
|
|
|
|
|
#define ACPI_DEVICE_SWNODE_PORT_NAME_LENGTH 8
|
|
|
|
|
2023-11-07 19:19:42 +00:00
|
|
|
enum acpi_device_swnode_dev_props {
|
2023-11-06 16:28:40 +00:00
|
|
|
ACPI_DEVICE_SWNODE_DEV_ROTATION,
|
2023-11-06 16:31:18 +00:00
|
|
|
ACPI_DEVICE_SWNODE_DEV_CLOCK_FREQUENCY,
|
|
|
|
ACPI_DEVICE_SWNODE_DEV_LED_MAX_MICROAMP,
|
|
|
|
ACPI_DEVICE_SWNODE_DEV_FLASH_MAX_MICROAMP,
|
|
|
|
ACPI_DEVICE_SWNODE_DEV_FLASH_MAX_TIMEOUT_US,
|
2023-11-07 19:19:42 +00:00
|
|
|
ACPI_DEVICE_SWNODE_DEV_NUM_OF,
|
|
|
|
ACPI_DEVICE_SWNODE_DEV_NUM_ENTRIES
|
|
|
|
};
|
|
|
|
|
2023-11-06 16:16:26 +00:00
|
|
|
enum acpi_device_swnode_port_props {
|
|
|
|
ACPI_DEVICE_SWNODE_PORT_REG,
|
|
|
|
ACPI_DEVICE_SWNODE_PORT_NUM_OF,
|
|
|
|
ACPI_DEVICE_SWNODE_PORT_NUM_ENTRIES
|
|
|
|
};
|
|
|
|
|
|
|
|
enum acpi_device_swnode_ep_props {
|
|
|
|
ACPI_DEVICE_SWNODE_EP_REMOTE_EP,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_BUS_TYPE,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_REG,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_CLOCK_LANES,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_DATA_LANES,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_LANE_POLARITIES,
|
|
|
|
/* TX only */
|
|
|
|
ACPI_DEVICE_SWNODE_EP_LINK_FREQUENCIES,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_NUM_OF,
|
|
|
|
ACPI_DEVICE_SWNODE_EP_NUM_ENTRIES
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each device has a root software node plus two times as many nodes as the
|
|
|
|
* number of CSI-2 ports.
|
|
|
|
*/
|
|
|
|
#define ACPI_DEVICE_SWNODE_PORT(port) (2 * (port) + 1)
|
|
|
|
#define ACPI_DEVICE_SWNODE_EP(endpoint) \
|
|
|
|
(ACPI_DEVICE_SWNODE_PORT(endpoint) + 1)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct acpi_device_software_node_port - MIPI DisCo for Imaging CSI-2 port
|
|
|
|
* @port_name: Port name.
|
|
|
|
* @data_lanes: "data-lanes" property values.
|
|
|
|
* @lane_polarities: "lane-polarities" property values.
|
|
|
|
* @link_frequencies: "link_frequencies" property values.
|
|
|
|
* @port_nr: Port number.
|
|
|
|
* @crs_crs2_local: _CRS CSI2 record present (i.e. this is a transmitter one).
|
|
|
|
* @port_props: Port properties.
|
|
|
|
* @ep_props: Endpoint properties.
|
|
|
|
* @remote_ep: Reference to the remote endpoint.
|
|
|
|
*/
|
2023-11-06 16:09:01 +00:00
|
|
|
struct acpi_device_software_node_port {
|
2023-11-06 16:16:26 +00:00
|
|
|
char port_name[ACPI_DEVICE_SWNODE_PORT_NAME_LENGTH + 1];
|
|
|
|
u32 data_lanes[ACPI_DEVICE_CSI2_DATA_LANES];
|
|
|
|
u32 lane_polarities[ACPI_DEVICE_CSI2_DATA_LANES + 1 /* clock lane */];
|
|
|
|
u64 link_frequencies[ACPI_DEVICE_CSI2_DATA_LANES];
|
2023-11-06 16:09:01 +00:00
|
|
|
unsigned int port_nr;
|
2023-11-06 16:16:26 +00:00
|
|
|
bool crs_csi2_local;
|
|
|
|
|
|
|
|
struct property_entry port_props[ACPI_DEVICE_SWNODE_PORT_NUM_ENTRIES];
|
|
|
|
struct property_entry ep_props[ACPI_DEVICE_SWNODE_EP_NUM_ENTRIES];
|
|
|
|
|
|
|
|
struct software_node_ref_args remote_ep[1];
|
2023-11-06 16:09:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct acpi_device_software_nodes - Software nodes for an ACPI device
|
2023-11-07 19:19:42 +00:00
|
|
|
* @dev_props: Device properties.
|
2023-11-06 16:09:01 +00:00
|
|
|
* @nodes: Software nodes for root as well as ports and endpoints.
|
|
|
|
* @nodeprts: Array of software node pointers, for (un)registering them.
|
|
|
|
* @ports: Information related to each port and endpoint within a port.
|
|
|
|
* @num_ports: The number of ports.
|
|
|
|
*/
|
|
|
|
struct acpi_device_software_nodes {
|
2023-11-07 19:19:42 +00:00
|
|
|
struct property_entry dev_props[ACPI_DEVICE_SWNODE_DEV_NUM_ENTRIES];
|
2023-11-06 16:09:01 +00:00
|
|
|
struct software_node *nodes;
|
|
|
|
const struct software_node **nodeptrs;
|
|
|
|
struct acpi_device_software_node_port *ports;
|
|
|
|
unsigned int num_ports;
|
|
|
|
};
|
|
|
|
|
2012-08-17 06:44:09 +00:00
|
|
|
/* Device */
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device {
|
2021-12-23 08:16:17 +00:00
|
|
|
u32 pld_crc;
|
2009-09-21 19:29:10 +00:00
|
|
|
int device_type;
|
|
|
|
acpi_handle handle; /* no handle for fixed hardware */
|
2014-11-04 13:03:59 +00:00
|
|
|
struct fwnode_handle fwnode;
|
2005-08-05 04:44:28 +00:00
|
|
|
struct list_head wakeup_list;
|
2013-11-22 20:52:12 +00:00
|
|
|
struct list_head del_list;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_status status;
|
|
|
|
struct acpi_device_flags flags;
|
2005-08-05 04:44:28 +00:00
|
|
|
struct acpi_device_pnp pnp;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct acpi_device_power power;
|
|
|
|
struct acpi_device_wakeup wakeup;
|
2005-08-05 04:44:28 +00:00
|
|
|
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 11:33:55 +00:00
|
|
|
struct acpi_device_data data;
|
2013-01-30 13:27:29 +00:00
|
|
|
struct acpi_scan_handler *handler;
|
2014-02-06 16:31:37 +00:00
|
|
|
struct acpi_hotplug_context *hp;
|
2023-11-07 19:19:42 +00:00
|
|
|
struct acpi_device_software_nodes *swnodes;
|
ACPI / GPIO: Driver GPIO mappings for ACPI GPIOs
Provide a way for device drivers using GPIOs described by ACPI
GpioIo resources in _CRS to tell the GPIO subsystem what names
(connection IDs) to associate with specific GPIO pins defined
in there.
To do that, a driver needs to define a mapping table as a
NULL-terminated array of struct acpi_gpio_mapping objects
that each contain a name, a pointer to an array of line data
(struct acpi_gpio_params) objects and the size of that array.
Each struct acpi_gpio_params object consists of three fields,
crs_entry_index, line_index, active_low, representing the index of
the target GpioIo()/GpioInt() resource in _CRS starting from zero,
the index of the target line in that resource starting from zero,
and the active-low flag for that line, respectively.
Next, the mapping table needs to be passed as the second
argument to acpi_dev_add_driver_gpios() that will register it with
the ACPI device object pointed to by its first argument. That
should be done in the driver's .probe() routine.
On removal, the driver should unregister its GPIO mapping table
by calling acpi_dev_remove_driver_gpios() on the ACPI device
object where that table was previously registered.
Included are fixes from Mika Westerberg.
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-03 22:39:41 +00:00
|
|
|
const struct acpi_gpio_mapping *driver_gpios;
|
2005-08-05 04:44:28 +00:00
|
|
|
void *driver_data;
|
2006-05-10 14:33:00 +00:00
|
|
|
struct device dev;
|
2013-08-06 12:32:54 +00:00
|
|
|
unsigned int physical_node_count;
|
2014-11-23 13:22:54 +00:00
|
|
|
unsigned int dep_unmet;
|
2012-08-17 06:44:09 +00:00
|
|
|
struct list_head physical_node_list;
|
|
|
|
struct mutex physical_node_lock;
|
2013-01-24 11:50:09 +00:00
|
|
|
void (*remove)(struct acpi_device *);
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2015-08-27 02:36:14 +00:00
|
|
|
/* Non-device subnode */
|
|
|
|
struct acpi_data_node {
|
2024-03-25 12:32:57 +00:00
|
|
|
struct list_head sibling;
|
2015-08-27 02:36:14 +00:00
|
|
|
const char *name;
|
2015-08-27 02:37:19 +00:00
|
|
|
acpi_handle handle;
|
2015-08-27 02:36:14 +00:00
|
|
|
struct fwnode_handle fwnode;
|
2017-03-28 07:52:16 +00:00
|
|
|
struct fwnode_handle *parent;
|
2015-08-27 02:36:14 +00:00
|
|
|
struct acpi_device_data data;
|
2015-08-27 02:37:19 +00:00
|
|
|
struct kobject kobj;
|
|
|
|
struct completion kobj_done;
|
2015-08-27 02:36:14 +00:00
|
|
|
};
|
|
|
|
|
2017-07-21 11:39:31 +00: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;
|
2015-08-27 02:40:05 +00:00
|
|
|
|
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 00:35:27 +00:00
|
|
|
bool is_acpi_device_node(const struct fwnode_handle *fwnode);
|
|
|
|
bool is_acpi_data_node(const struct fwnode_handle *fwnode);
|
2014-11-04 13:03:59 +00:00
|
|
|
|
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 00:35:27 +00:00
|
|
|
static inline bool is_acpi_node(const struct fwnode_handle *fwnode)
|
2014-11-04 13:03:59 +00:00
|
|
|
{
|
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 00:35:27 +00:00
|
|
|
return (is_acpi_device_node(fwnode) || is_acpi_data_node(fwnode));
|
2014-11-04 13:03:59 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 11:39:33 +00:00
|
|
|
#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)
|
2015-08-27 02:40:05 +00:00
|
|
|
{
|
2017-07-21 11:39:31 +00:00
|
|
|
return !IS_ERR_OR_NULL(fwnode) &&
|
|
|
|
fwnode->ops == &acpi_static_fwnode_ops;
|
2015-08-27 02:40:05 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 11:39:33 +00:00
|
|
|
static inline bool acpi_data_node_match(const struct fwnode_handle *fwnode,
|
2016-06-21 17:50:20 +00:00
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return is_acpi_data_node(fwnode) ?
|
|
|
|
(!strcmp(to_acpi_data_node(fwnode)->name, name)) : false;
|
|
|
|
}
|
|
|
|
|
2014-11-04 13:03:59 +00:00
|
|
|
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return &adev->fwnode;
|
|
|
|
}
|
|
|
|
|
2008-09-22 21:37:34 +00:00
|
|
|
static inline void *acpi_driver_data(struct acpi_device *d)
|
|
|
|
{
|
|
|
|
return d->driver_data;
|
|
|
|
}
|
|
|
|
|
2006-12-07 12:56:23 +00:00
|
|
|
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
|
2024-07-01 12:07:37 +00:00
|
|
|
#define to_acpi_driver(d) container_of_const(d, struct acpi_driver, drv)
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-08-24 16:59:48 +00:00
|
|
|
static inline struct acpi_device *acpi_dev_parent(struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
if (adev->dev.parent)
|
|
|
|
return to_acpi_device(adev->dev.parent);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-11-22 20:56:06 +00:00
|
|
|
static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
|
|
|
|
{
|
|
|
|
*((u32 *)&adev->status) = sta;
|
|
|
|
}
|
|
|
|
|
2014-02-06 16:31:37 +00:00
|
|
|
static inline void acpi_set_hp_context(struct acpi_device *adev,
|
2014-07-15 20:03:22 +00:00
|
|
|
struct acpi_hotplug_context *hp)
|
2014-02-06 16:31:37 +00:00
|
|
|
{
|
|
|
|
hp->self = adev;
|
|
|
|
adev->hp = hp;
|
|
|
|
}
|
|
|
|
|
2014-02-21 23:48:31 +00:00
|
|
|
void acpi_initialize_hp_context(struct acpi_device *adev,
|
|
|
|
struct acpi_hotplug_context *hp,
|
2024-03-25 12:33:03 +00:00
|
|
|
acpi_hp_notify notify, acpi_hp_uevent uevent);
|
2014-02-21 23:48:31 +00:00
|
|
|
|
2007-05-08 07:28:35 +00:00
|
|
|
/* acpi_device.dev.bus == &acpi_bus_type */
|
2024-02-11 15:37:11 +00:00
|
|
|
extern const struct bus_type acpi_bus_type;
|
2007-05-08 07:28:35 +00:00
|
|
|
|
2022-02-22 19:51:42 +00:00
|
|
|
int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data);
|
2022-04-04 15:21:50 +00:00
|
|
|
int acpi_dev_for_each_child(struct acpi_device *adev,
|
2022-04-22 15:13:48 +00:00
|
|
|
int (*fn)(struct acpi_device *, void *), void *data);
|
2022-06-13 18:26:47 +00:00
|
|
|
int acpi_dev_for_each_child_reverse(struct acpi_device *adev,
|
|
|
|
int (*fn)(struct acpi_device *, void *),
|
|
|
|
void *data);
|
2022-02-22 19:51:42 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* Events
|
|
|
|
* ------
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct acpi_bus_event {
|
2005-08-05 04:44:28 +00:00
|
|
|
struct list_head node;
|
|
|
|
acpi_device_class device_class;
|
|
|
|
acpi_bus_id bus_id;
|
|
|
|
u32 type;
|
|
|
|
u32 data;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2007-11-02 23:19:59 +00:00
|
|
|
extern struct kobject *acpi_kobj;
|
2007-08-22 17:24:31 +00:00
|
|
|
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
|
2009-06-29 05:43:27 +00:00
|
|
|
void acpi_bus_private_data_handler(acpi_handle, void *);
|
2008-01-17 07:51:21 +00:00
|
|
|
int acpi_bus_get_private_data(acpi_handle, void **);
|
2014-05-20 12:59:21 +00:00
|
|
|
int acpi_bus_attach_private_data(acpi_handle, void *);
|
|
|
|
void acpi_bus_detach_private_data(acpi_handle);
|
2023-07-03 08:02:44 +00:00
|
|
|
int acpi_dev_install_notify_handler(struct acpi_device *adev,
|
|
|
|
u32 handler_type,
|
2023-10-06 15:32:51 +00:00
|
|
|
acpi_notify_handler handler, void *context);
|
2023-07-03 08:02:44 +00:00
|
|
|
void acpi_dev_remove_notify_handler(struct acpi_device *adev,
|
|
|
|
u32 handler_type,
|
|
|
|
acpi_notify_handler handler);
|
2008-01-25 06:48:06 +00:00
|
|
|
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 *);
|
2008-08-28 02:04:29 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* External Functions
|
|
|
|
*/
|
|
|
|
|
2009-09-21 19:30:01 +00:00
|
|
|
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
|
|
|
|
unsigned long long *sta);
|
2005-08-05 04:44:28 +00:00
|
|
|
int acpi_bus_get_status(struct acpi_device *device);
|
2013-01-17 13:11:08 +00:00
|
|
|
|
2005-08-05 04:44:28 +00:00
|
|
|
int acpi_bus_set_power(acpi_handle handle, int state);
|
2013-01-17 13:11:08 +00:00
|
|
|
const char *acpi_power_state_string(int state);
|
2012-11-02 00:40:45 +00:00
|
|
|
int acpi_device_set_power(struct acpi_device *device, int state);
|
2013-01-17 13:11:08 +00:00
|
|
|
int acpi_bus_init_power(struct acpi_device *device);
|
2013-06-18 22:45:34 +00:00
|
|
|
int acpi_device_fix_up_power(struct acpi_device *device);
|
2022-06-13 18:36:06 +00:00
|
|
|
void acpi_device_fix_up_power_extended(struct acpi_device *adev);
|
2023-11-12 20:36:26 +00:00
|
|
|
void acpi_device_fix_up_power_children(struct acpi_device *adev);
|
2010-11-24 23:09:15 +00:00
|
|
|
int acpi_bus_update_power(acpi_handle handle, int *state_p);
|
2013-11-19 07:43:52 +00:00
|
|
|
int acpi_device_update_power(struct acpi_device *device, int *state_p);
|
2008-07-07 01:30:55 +00:00
|
|
|
bool acpi_bus_power_manageable(acpi_handle handle);
|
2022-04-04 15:23:13 +00:00
|
|
|
void acpi_dev_power_up_children_with_adr(struct acpi_device *adev);
|
2023-01-12 20:51:24 +00:00
|
|
|
u8 acpi_dev_power_state_for_wake(struct acpi_device *adev);
|
2019-06-25 10:29:41 +00:00
|
|
|
int acpi_device_power_add_dependent(struct acpi_device *adev,
|
|
|
|
struct device *dev);
|
|
|
|
void acpi_device_power_remove_dependent(struct acpi_device *adev,
|
|
|
|
struct device *dev);
|
2013-05-16 20:29:28 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_PM
|
2008-07-07 01:34:48 +00:00
|
|
|
bool acpi_bus_can_wakeup(acpi_handle handle);
|
2013-05-16 20:29:28 +00:00
|
|
|
#else
|
|
|
|
static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
|
|
|
|
#endif
|
2013-01-17 13:11:08 +00:00
|
|
|
|
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 13:36:47 +00:00
|
|
|
void acpi_scan_lock_acquire(void);
|
|
|
|
void acpi_scan_lock_release(void);
|
2014-02-03 23:43:17 +00:00
|
|
|
void acpi_lock_hp_context(void);
|
|
|
|
void acpi_unlock_hp_context(void);
|
2013-01-30 13:27:29 +00:00
|
|
|
int acpi_scan_add_handler(struct acpi_scan_handler *handler);
|
2024-03-28 19:49:11 +00:00
|
|
|
/*
|
|
|
|
* use a macro to avoid include chaining to get THIS_MODULE
|
|
|
|
*/
|
|
|
|
#define acpi_bus_register_driver(drv) \
|
|
|
|
__acpi_bus_register_driver(drv, THIS_MODULE)
|
|
|
|
int __acpi_bus_register_driver(struct acpi_driver *driver, struct module *owner);
|
2006-04-27 09:25:00 +00:00
|
|
|
void acpi_bus_unregister_driver(struct acpi_driver *driver);
|
2013-01-19 00:27:35 +00:00
|
|
|
int acpi_bus_scan(acpi_handle handle);
|
2013-01-25 23:27:44 +00:00
|
|
|
void acpi_bus_trim(struct acpi_device *start);
|
2007-05-10 03:34:35 +00:00
|
|
|
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
|
2007-07-23 12:43:32 +00:00
|
|
|
int acpi_match_device_ids(struct acpi_device *device,
|
|
|
|
const struct acpi_device_id *ids);
|
2017-02-05 16:30:12 +00:00
|
|
|
void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
|
|
|
|
char *modalias, size_t len);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
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-22 20:54:37 +00:00
|
|
|
static inline bool acpi_device_enumerated(struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return adev && adev->flags.initialized && adev->flags.visited;
|
|
|
|
}
|
|
|
|
|
2012-09-07 07:31:38 +00:00
|
|
|
/**
|
|
|
|
* 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)
|
|
|
|
|
2005-03-18 23:45:35 +00:00
|
|
|
/*
|
|
|
|
* Bind physical devices with ACPI devices
|
|
|
|
*/
|
|
|
|
struct acpi_bus_type {
|
2005-08-05 04:44:28 +00:00
|
|
|
struct list_head list;
|
2013-03-03 21:35:20 +00:00
|
|
|
const char *name;
|
|
|
|
bool (*match)(struct device *dev);
|
2013-11-29 15:27:34 +00:00
|
|
|
struct acpi_device * (*find_companion)(struct device *);
|
2012-12-22 23:02:13 +00:00
|
|
|
void (*setup)(struct device *);
|
2005-03-18 23:45:35 +00:00
|
|
|
};
|
|
|
|
int register_acpi_bus_type(struct acpi_bus_type *);
|
|
|
|
int unregister_acpi_bus_type(struct acpi_bus_type *);
|
2014-07-07 12:07:38 +00:00
|
|
|
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
|
|
|
|
int acpi_unbind_one(struct device *dev);
|
2008-08-01 15:37:54 +00:00
|
|
|
|
2022-04-13 07:36:17 +00:00
|
|
|
enum acpi_bridge_type {
|
|
|
|
ACPI_BRIDGE_TYPE_PCIE = 1,
|
|
|
|
ACPI_BRIDGE_TYPE_CXL,
|
|
|
|
};
|
|
|
|
|
2009-07-23 23:03:00 +00:00
|
|
|
struct acpi_pci_root {
|
|
|
|
struct acpi_device * device;
|
|
|
|
struct pci_bus *bus;
|
|
|
|
u16 segment;
|
2022-04-13 07:36:17 +00:00
|
|
|
int bridge_type;
|
2010-03-11 19:20:06 +00:00
|
|
|
struct resource secondary; /* downstream bus range */
|
2009-07-23 23:03:00 +00:00
|
|
|
|
2022-04-13 07:36:18 +00:00
|
|
|
u32 osc_support_set; /* _OSC state of support bits */
|
|
|
|
u32 osc_control_set; /* _OSC state of control bits */
|
|
|
|
u32 osc_ext_support_set; /* _OSC state of extended support bits */
|
|
|
|
u32 osc_ext_control_set; /* _OSC state of extended control bits */
|
2012-06-22 06:55:16 +00:00
|
|
|
phys_addr_t mcfg_addr;
|
2009-07-23 23:03:00 +00:00
|
|
|
};
|
|
|
|
|
2005-03-18 23:45:35 +00:00
|
|
|
/* helper */
|
2013-11-28 22:57:58 +00:00
|
|
|
|
2023-11-21 18:04:02 +00:00
|
|
|
struct iommu_ops;
|
|
|
|
|
2021-06-04 16:50:46 +00:00
|
|
|
bool acpi_dma_supported(const struct acpi_device *adev);
|
2015-10-28 22:50:48 +00:00
|
|
|
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
|
2021-06-18 15:20:57 +00:00
|
|
|
int acpi_iommu_fwspec_init(struct device *dev, u32 id,
|
2024-07-02 11:40:48 +00:00
|
|
|
struct fwnode_handle *fwnode);
|
2022-09-11 09:06:34 +00:00
|
|
|
int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
|
2020-06-19 08:20:06 +00:00
|
|
|
int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
|
|
|
|
const u32 *input_id);
|
|
|
|
static inline int acpi_dma_configure(struct device *dev,
|
|
|
|
enum dev_dma_attr attr)
|
|
|
|
{
|
|
|
|
return acpi_dma_configure_id(dev, attr, NULL);
|
|
|
|
}
|
2013-11-28 22:57:58 +00:00
|
|
|
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
|
|
|
|
u64 address, bool check_children);
|
2022-06-13 18:10:03 +00:00
|
|
|
struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev,
|
|
|
|
acpi_bus_address adr);
|
2009-06-10 19:55:14 +00:00
|
|
|
int acpi_is_root_bridge(acpi_handle);
|
2009-07-23 23:03:00 +00:00
|
|
|
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
|
2005-03-18 23:45:35 +00:00
|
|
|
|
2010-02-17 22:44:09 +00:00
|
|
|
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
|
|
|
|
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
|
|
|
|
|
2017-04-21 10:47:40 +00:00
|
|
|
#ifdef CONFIG_X86
|
2021-11-22 17:05:31 +00:00
|
|
|
bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status);
|
2021-12-30 19:31:19 +00:00
|
|
|
bool acpi_quirk_skip_acpi_ac_and_battery(void);
|
2023-07-29 04:20:50 +00:00
|
|
|
int acpi_install_cmos_rtc_space_handler(acpi_handle handle);
|
|
|
|
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle);
|
2024-02-18 15:15:32 +00:00
|
|
|
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip);
|
2017-04-21 10:47:40 +00:00
|
|
|
#else
|
2021-11-22 17:05:31 +00:00
|
|
|
static inline bool acpi_device_override_status(struct acpi_device *adev,
|
|
|
|
unsigned long long *status)
|
2017-04-21 10:47:40 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-30 19:31:19 +00:00
|
|
|
static inline bool acpi_quirk_skip_acpi_ac_and_battery(void)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2023-07-29 04:20:50 +00:00
|
|
|
static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
|
|
|
|
{
|
|
|
|
}
|
2024-02-18 15:15:32 +00:00
|
|
|
static inline int
|
|
|
|
acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
|
|
|
{
|
|
|
|
*skip = false;
|
|
|
|
return 0;
|
|
|
|
}
|
2017-04-21 10:47:40 +00:00
|
|
|
#endif
|
|
|
|
|
2021-12-30 14:17:20 +00:00
|
|
|
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
|
|
|
|
bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev);
|
2023-03-01 10:04:34 +00:00
|
|
|
bool acpi_quirk_skip_gpio_event_handlers(void);
|
2021-12-30 14:17:20 +00:00
|
|
|
#else
|
|
|
|
static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2023-03-01 10:04:34 +00:00
|
|
|
static inline bool acpi_quirk_skip_gpio_event_handlers(void)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2017-04-21 10:47:40 +00:00
|
|
|
#endif
|
|
|
|
|
2011-02-10 23:06:54 +00:00
|
|
|
#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-12 20:56:34 +00:00
|
|
|
void acpi_pm_wakeup_event(struct device *dev);
|
2014-07-22 23:00:45 +00:00
|
|
|
acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
|
2017-06-12 20:48:41 +00:00
|
|
|
void (*func)(struct acpi_device_wakeup_context *context));
|
2014-07-22 23:00:45 +00:00
|
|
|
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
|
2017-06-23 23:56:13 +00:00
|
|
|
bool acpi_pm_device_can_wakeup(struct device *dev);
|
2012-06-23 02:23:48 +00:00
|
|
|
int acpi_pm_device_sleep_state(struct device *, int *, int);
|
2017-06-23 23:54:39 +00:00
|
|
|
int acpi_pm_set_device_wakeup(struct device *dev, bool enable);
|
2010-10-14 21:24:13 +00:00
|
|
|
#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-12 20:56:34 +00:00
|
|
|
static inline void acpi_pm_wakeup_event(struct device *dev)
|
|
|
|
{
|
|
|
|
}
|
2012-11-02 00:40:09 +00:00
|
|
|
static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
|
2014-07-22 23:00:45 +00:00
|
|
|
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-12 20:56:34 +00:00
|
|
|
void (*func)(struct acpi_device_wakeup_context *context))
|
2012-11-02 00:40:09 +00:00
|
|
|
{
|
|
|
|
return AE_SUPPORT;
|
|
|
|
}
|
2014-07-22 23:00:45 +00:00
|
|
|
static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
|
2012-11-02 00:40:09 +00:00
|
|
|
{
|
|
|
|
return AE_SUPPORT;
|
|
|
|
}
|
2017-06-23 23:56:13 +00:00
|
|
|
static inline bool acpi_pm_device_can_wakeup(struct device *dev)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-06-15 22:37:42 +00:00
|
|
|
static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
|
2007-07-29 21:27:18 +00:00
|
|
|
{
|
|
|
|
if (p)
|
|
|
|
*p = ACPI_STATE_D0;
|
2013-06-15 22:37:42 +00:00
|
|
|
|
2013-07-30 12:36:20 +00:00
|
|
|
return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
|
|
|
|
m : ACPI_STATE_D0;
|
2007-07-29 21:27:18 +00:00
|
|
|
}
|
2017-06-23 23:54:39 +00:00
|
|
|
static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
|
2008-07-08 14:00:54 +00:00
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
2010-10-14 21:24:13 +00:00
|
|
|
#endif
|
2007-07-17 20:40:25 +00:00
|
|
|
|
ACPI: PM: Make acpi_sleep_state_supported() non-static
With some upcoming patches to save/restore the Hyper-V drivers related
states, a Linux VM running on Hyper-V will be able to hibernate. When
a Linux VM hibernates, unluckily we must disable the memory hot-add/remove
and balloon up/down capabilities in the hv_balloon driver
(drivers/hv/hv_balloon.c), because these can not really work according to
the design of the related back-end driver on the host.
By default, Hyper-V does not enable the virtual ACPI S4 state for a VM;
on recent Hyper-V hosts, the administrator is able to enable the virtual
ACPI S4 state for a VM, so we hope to use the presence of the virtual ACPI
S4 state as a hint for hv_balloon to disable the aforementioned
capabilities. In this way, hibernation will work more reliably, from the
user's perspective.
By marking acpi_sleep_state_supported() non-static, we'll be able to
implement a hv_is_hibernation_supported() API in the always-built-in
module arch/x86/hyperv/hv_init.c, and the API will be called by hv_balloon.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-07-04 02:43:32 +00:00
|
|
|
#ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT
|
|
|
|
bool acpi_sleep_state_supported(u8 sleep_state);
|
|
|
|
#else
|
|
|
|
static inline bool acpi_sleep_state_supported(u8 sleep_state) { return false; }
|
|
|
|
#endif
|
|
|
|
|
2012-11-10 21:48:33 +00:00
|
|
|
#ifdef CONFIG_ACPI_SLEEP
|
|
|
|
u32 acpi_target_system_state(void);
|
|
|
|
#else
|
|
|
|
static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; }
|
|
|
|
#endif
|
|
|
|
|
2012-11-02 00:40:45 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-11-21 22:33:40 +00:00
|
|
|
static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
|
|
|
{
|
2015-12-09 08:17:30 +00:00
|
|
|
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);
|
2012-11-21 22:33:40 +00:00
|
|
|
}
|
|
|
|
|
2022-09-13 16:31:40 +00:00
|
|
|
int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer);
|
2019-10-01 14:27:22 +00:00
|
|
|
|
2023-11-23 10:06:14 +00:00
|
|
|
static inline bool acpi_dev_hid_match(struct acpi_device *adev, const char *hid2)
|
|
|
|
{
|
|
|
|
const char *hid1 = acpi_device_hid(adev);
|
|
|
|
|
|
|
|
return hid1 && hid2 && !strcmp(hid1, hid2);
|
|
|
|
}
|
|
|
|
|
2023-11-23 10:06:13 +00:00
|
|
|
static inline bool acpi_str_uid_match(struct acpi_device *adev, const char *uid2)
|
|
|
|
{
|
|
|
|
const char *uid1 = acpi_device_uid(adev);
|
|
|
|
|
|
|
|
return uid1 && uid2 && !strcmp(uid1, uid2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
|
|
|
|
{
|
|
|
|
u64 uid1;
|
|
|
|
|
|
|
|
return !acpi_dev_uid_to_integer(adev, &uid1) && uid1 == uid2;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define TYPE_ENTRY(type, x) \
|
|
|
|
const type: x, \
|
|
|
|
type: x
|
|
|
|
|
|
|
|
#define ACPI_STR_TYPES(match) \
|
|
|
|
TYPE_ENTRY(unsigned char *, match), \
|
|
|
|
TYPE_ENTRY(signed char *, match), \
|
|
|
|
TYPE_ENTRY(char *, match), \
|
|
|
|
TYPE_ENTRY(void *, match)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* acpi_dev_uid_match - Match device by supplied UID
|
|
|
|
* @adev: ACPI device to match.
|
|
|
|
* @uid2: Unique ID of the device.
|
|
|
|
*
|
|
|
|
* Matches UID in @adev with given @uid2.
|
|
|
|
*
|
|
|
|
* Returns: %true if matches, %false otherwise.
|
|
|
|
*/
|
|
|
|
#define acpi_dev_uid_match(adev, uid2) \
|
|
|
|
_Generic(uid2, \
|
|
|
|
/* Treat @uid2 as a string for acpi string types */ \
|
|
|
|
ACPI_STR_TYPES(acpi_str_uid_match), \
|
|
|
|
/* Treat as an integer otherwise */ \
|
|
|
|
default: acpi_int_uid_match)(adev, uid2)
|
|
|
|
|
2023-11-23 10:06:14 +00:00
|
|
|
/**
|
|
|
|
* acpi_dev_hid_uid_match - Match device by supplied HID and UID
|
|
|
|
* @adev: ACPI device to match.
|
|
|
|
* @hid2: Hardware ID of the device.
|
2024-03-28 03:55:40 +00:00
|
|
|
* @uid2: Unique ID of the device, pass NULL to not check _UID.
|
2023-11-23 10:06:14 +00:00
|
|
|
*
|
|
|
|
* Matches HID and UID in @adev with given @hid2 and @uid2. Absence of @uid2
|
|
|
|
* will be treated as a match. If user wants to validate @uid2, it should be
|
|
|
|
* done before calling this function.
|
|
|
|
*
|
2024-03-28 03:55:40 +00:00
|
|
|
* Returns: %true if matches or @uid2 is NULL, %false otherwise.
|
2023-11-23 10:06:14 +00:00
|
|
|
*/
|
|
|
|
#define acpi_dev_hid_uid_match(adev, hid2, uid2) \
|
|
|
|
(acpi_dev_hid_match(adev, hid2) && \
|
2024-03-28 03:55:40 +00:00
|
|
|
/* Distinguish integer 0 from NULL @uid2 */ \
|
|
|
|
(_Generic(uid2, ACPI_STR_TYPES(!(uid2)), default: 0) || \
|
|
|
|
acpi_dev_uid_match(adev, uid2)))
|
2023-11-23 10:06:14 +00:00
|
|
|
|
2021-06-03 22:40:02 +00:00
|
|
|
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
|
ACPI: delay enumeration of devices with a _DEP pointing to an INT3472 device
The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.
To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.
This causes problems with the probe ordering wrt drivers for consumers
of these clks/regulators. Since the lookups are only registered when the
provider-driver binds, trying to get these clks/regulators before then
results in a -ENOENT error for clks and a dummy regulator for regulators.
One case where we hit this issue is camera sensors such as e.g. the OV8865
sensor found on the Microsoft Surface Go. The sensor uses clks, regulators
and GPIOs provided by a TPS68470 PMIC which is described in an INT3472
ACPI device. There is special platform code handling this and setting
platform_data with the necessary consumer info on the MFD cells
instantiated for the PMIC under: drivers/platform/x86/intel/int3472.
For this to work properly the ov8865 driver must not bind to the I2C-client
for the OV8865 sensor until after the TPS68470 PMIC gpio, regulator and
clk MFD cells have all been fully setup.
The OV8865 on the Microsoft Surface Go is just one example, all X86
devices using the Intel IPU3 camera block found on recent Intel SoCs
have similar issues where there is an INT3472 HID ACPI-device, which
describes the clks and regulators, and the driver for this INT3472 device
must be fully initialized before the sensor driver (any sensor driver)
binds for things to work properly.
On these devices the ACPI nodes describing the sensors all have a _DEP
dependency on the matching INT3472 ACPI device (there is one per sensor).
This allows solving the probe-ordering problem by delaying the enumeration
(instantiation of the I2C-client in the ov8865 example) of ACPI-devices
which have a _DEP dependency on an INT3472 device.
The new acpi_dev_ready_for_enumeration() helper used for this is also
exported because for devices, which have the enumeration_by_parent flag
set, the parent-driver will do its own scan of child ACPI devices and
it will try to enumerate those during its probe(). Code doing this such
as e.g. the i2c-core-acpi.c code must call this new helper to ensure
that it too delays the enumeration until all the _DEP dependencies are
met on devices which have the new honor_deps flag set.
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20211203102857.44539-2-hdegoede@redhat.com
2021-12-03 10:28:44 +00:00
|
|
|
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
|
2022-09-21 23:04:35 +00:00
|
|
|
struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
|
|
|
|
struct acpi_device *start);
|
|
|
|
|
2022-09-21 23:04:36 +00:00
|
|
|
/**
|
|
|
|
* for_each_acpi_consumer_dev - iterate over the consumer ACPI devices for a
|
|
|
|
* given supplier
|
|
|
|
* @supplier: Pointer to the supplier's ACPI device
|
|
|
|
* @consumer: Pointer to &struct acpi_device to hold the consumer, initially NULL
|
|
|
|
*/
|
|
|
|
#define for_each_acpi_consumer_dev(supplier, consumer) \
|
|
|
|
for (consumer = acpi_dev_get_next_consumer_dev(supplier, NULL); \
|
|
|
|
consumer; \
|
|
|
|
consumer = acpi_dev_get_next_consumer_dev(supplier, consumer))
|
|
|
|
|
2021-01-07 13:28:36 +00:00
|
|
|
struct acpi_device *
|
|
|
|
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
|
2019-10-01 14:27:21 +00:00
|
|
|
struct acpi_device *
|
|
|
|
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
|
|
|
|
|
2021-04-12 23:20:51 +00:00
|
|
|
/**
|
|
|
|
* for_each_acpi_dev_match - iterate over ACPI devices that matching the criteria
|
|
|
|
* @adev: pointer to the matching ACPI device, NULL at the end of the loop
|
|
|
|
* @hid: Hardware ID of the device.
|
|
|
|
* @uid: Unique ID of the device, pass NULL to not check _UID
|
|
|
|
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV
|
|
|
|
*
|
|
|
|
* The caller is responsible for invoking acpi_dev_put() on the returned device.
|
|
|
|
*/
|
2021-01-07 13:28:36 +00:00
|
|
|
#define for_each_acpi_dev_match(adev, hid, uid, hrv) \
|
|
|
|
for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \
|
|
|
|
adev; \
|
|
|
|
adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv))
|
|
|
|
|
2021-04-12 22:23:58 +00:00
|
|
|
static inline struct acpi_device *acpi_dev_get(struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return adev ? to_acpi_device(get_device(&adev->dev)) : NULL;
|
|
|
|
}
|
|
|
|
|
2019-04-12 15:19:11 +00:00
|
|
|
static inline void acpi_dev_put(struct acpi_device *adev)
|
|
|
|
{
|
2021-07-24 22:25:54 +00:00
|
|
|
if (adev)
|
|
|
|
put_device(&adev->dev);
|
2019-04-12 15:19:11 +00:00
|
|
|
}
|
2021-06-16 14:06:52 +00:00
|
|
|
|
2022-08-10 16:14:22 +00:00
|
|
|
struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle);
|
|
|
|
struct acpi_device *acpi_get_acpi_dev(acpi_handle handle);
|
2021-06-16 14:06:52 +00:00
|
|
|
|
2022-08-10 16:14:22 +00:00
|
|
|
static inline void acpi_put_acpi_dev(struct acpi_device *adev)
|
2021-06-16 14:06:52 +00:00
|
|
|
{
|
|
|
|
acpi_dev_put(adev);
|
|
|
|
}
|
2024-03-20 08:43:16 +00:00
|
|
|
|
|
|
|
int acpi_wait_for_acpi_ipmi(void);
|
|
|
|
|
2024-08-12 00:59:16 +00:00
|
|
|
int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices);
|
2024-08-12 00:59:18 +00:00
|
|
|
u32 arch_acpi_add_auto_dep(acpi_handle handle);
|
2012-05-11 08:08:25 +00:00
|
|
|
#else /* CONFIG_ACPI */
|
|
|
|
|
2012-06-04 04:29:11 +00:00
|
|
|
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
|
|
|
static inline int unregister_acpi_bus_type(void *bus) { return 0; }
|
2012-05-11 08:08:25 +00:00
|
|
|
|
2024-03-20 08:43:16 +00:00
|
|
|
static inline int acpi_wait_for_acpi_ipmi(void) { return 0; }
|
|
|
|
|
2007-05-10 03:34:35 +00:00
|
|
|
#endif /* CONFIG_ACPI */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#endif /*__ACPI_BUS_H__*/
|