diff options
Diffstat (limited to 'include/acpi/acpi_bus.h')
-rw-r--r-- | include/acpi/acpi_bus.h | 156 |
1 files changed, 130 insertions, 26 deletions
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0c23fd0548d1..c09d72986968 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -44,6 +44,7 @@ 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); +acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function); bool acpi_ata_match(acpi_handle handle); bool acpi_bay_match(acpi_handle handle); bool acpi_dock_match(acpi_handle handle); @@ -77,10 +78,11 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, bool acpi_dev_found(const char *hid); bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); +bool acpi_reduced_hardware(void); #ifdef CONFIG_ACPI -#include <linux/proc_fs.h> +struct proc_dir_entry; #define ACPI_BUS_FILE_ROOT "acpi" extern struct proc_dir_entry *acpi_root_dir; @@ -200,7 +202,8 @@ struct acpi_device_flags { u32 coherent_dma:1; u32 cca_seen:1; u32 enumeration_by_parent:1; - u32 reserved:19; + u32 honor_deps:1; + u32 reserved:18; }; /* File System */ @@ -232,6 +235,7 @@ struct acpi_pnp_type { struct acpi_device_pnp { acpi_bus_id bus_id; /* Object name */ + int instance_no; /* Instance number of this object */ struct acpi_pnp_type type; /* ID type */ acpi_bus_address bus_address; /* _ADR */ char *unique_id; /* _UID */ @@ -275,6 +279,14 @@ 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) */ + u8 state_for_enumeration; /* Deepest power state for enumeration */ +}; + +struct acpi_dep_data { + struct list_head node; + acpi_handle supplier; + acpi_handle consumer; + bool honor_dep; }; /* Performance Management */ @@ -332,8 +344,9 @@ struct acpi_device_physical_node { struct acpi_device_properties { const guid_t *guid; - const union acpi_object *properties; + union acpi_object *properties; struct list_head list; + void **bufs; }; /* ACPI Device Specific Data (_DSD) */ @@ -348,12 +361,10 @@ struct acpi_gpio_mapping; /* Device */ struct acpi_device { + u32 pld_crc; 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; @@ -366,7 +377,6 @@ struct acpi_device { struct acpi_device_data data; struct acpi_scan_handler *handler; struct acpi_hotplug_context *hp; - struct acpi_driver *driver; const struct acpi_gpio_mapping *driver_gpios; void *driver_data; struct device dev; @@ -447,6 +457,14 @@ static inline void *acpi_driver_data(struct acpi_device *d) #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 struct acpi_device *acpi_dev_parent(struct acpi_device *adev) +{ + if (adev->dev.parent) + return to_acpi_device(adev->dev.parent); + + return NULL; +} + static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta) { *((u32 *)&adev->status) = sta; @@ -467,6 +485,13 @@ void acpi_initialize_hp_context(struct acpi_device *adev, /* acpi_device.dev.bus == &acpi_bus_type */ extern struct bus_type acpi_bus_type; +int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data); +int acpi_dev_for_each_child(struct acpi_device *adev, + int (*fn)(struct acpi_device *, void *), void *data); +int acpi_dev_for_each_child_reverse(struct acpi_device *adev, + int (*fn)(struct acpi_device *, void *), + void *data); + /* * Events * ------ @@ -494,9 +519,6 @@ extern int unregister_acpi_notifier(struct notifier_block *); * External Functions */ -int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); -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); @@ -506,9 +528,11 @@ const char *acpi_power_state_string(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); +void acpi_device_fix_up_power_extended(struct acpi_device *adev); 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); +void acpi_dev_power_up_children_with_adr(struct acpi_device *adev); int acpi_device_power_add_dependent(struct acpi_device *adev, struct device *dev); void acpi_device_power_remove_dependent(struct acpi_device *adev, @@ -563,34 +587,50 @@ struct acpi_bus_type { 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); +enum acpi_bridge_type { + ACPI_BRIDGE_TYPE_PCIE = 1, + ACPI_BRIDGE_TYPE_CXL, +}; + struct acpi_pci_root { struct acpi_device * device; struct pci_bus *bus; u16 segment; + int bridge_type; struct resource secondary; /* downstream bus range */ - u32 osc_support_set; /* _OSC state of support bits */ - u32 osc_control_set; /* _OSC state of control bits */ + 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 */ phys_addr_t mcfg_addr; }; /* helper */ -bool acpi_dma_supported(struct acpi_device *adev); +bool acpi_dma_supported(const 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); - +int acpi_iommu_fwspec_init(struct device *dev, u32 id, + struct fwnode_handle *fwnode, + const struct iommu_ops *ops); +int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map); +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); +} struct acpi_device *acpi_find_child_device(struct acpi_device *parent, u64 address, bool check_children); +struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev, + acpi_bus_address adr); int acpi_is_root_bridge(acpi_handle); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); @@ -598,12 +638,34 @@ 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); +bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status); +bool acpi_quirk_skip_acpi_ac_and_battery(void); +#else +static inline bool acpi_device_override_status(struct acpi_device *adev, + unsigned long long *status) +{ + return false; +} +static inline bool acpi_quirk_skip_acpi_ac_and_battery(void) +{ + return false; +} +#endif + +#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) +bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev); +int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip); #else -static inline bool acpi_device_always_present(struct acpi_device *adev) +static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev) { return false; } +static inline int +acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip) +{ + *skip = false; + return 0; +} #endif #ifdef CONFIG_PM @@ -614,7 +676,6 @@ 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); -int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable); #else static inline void acpi_pm_wakeup_event(struct device *dev) { @@ -645,10 +706,6 @@ static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable) { return -ENODEV; } -static inline int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable) -{ - return -ENODEV; -} #endif #ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT @@ -681,13 +738,60 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev) } bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2); +int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer); +void acpi_dev_clear_dependencies(struct acpi_device *supplier); +bool acpi_dev_ready_for_enumeration(const struct acpi_device *device); +struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier, + struct acpi_device *start); + +/** + * 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)) + +struct acpi_device * +acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv); struct acpi_device * acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); +/** + * 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. + */ +#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)) + +static inline struct acpi_device *acpi_dev_get(struct acpi_device *adev) +{ + return adev ? to_acpi_device(get_device(&adev->dev)) : NULL; +} + static inline void acpi_dev_put(struct acpi_device *adev) { - put_device(&adev->dev); + if (adev) + put_device(&adev->dev); +} + +struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle); +struct acpi_device *acpi_get_acpi_dev(acpi_handle handle); + +static inline void acpi_put_acpi_dev(struct acpi_device *adev) +{ + acpi_dev_put(adev); } #else /* CONFIG_ACPI */ |