From 445b0eb058f5f31c844a731cb82e7441d0d9e578 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 27 Aug 2015 04:36:14 +0200 Subject: ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki Tested-by: Mika Westerberg --- include/linux/fwnode.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 0408545bce42..b08d6ba5c1e6 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -16,6 +16,7 @@ enum fwnode_type { FWNODE_INVALID = 0, FWNODE_OF, FWNODE_ACPI, + FWNODE_ACPI_DATA, FWNODE_PDATA, }; -- cgit v1.2.3 From 3a7a2ab839ad18c2d542b40f4a647c98d068e55a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 27 Aug 2015 04:40:05 +0200 Subject: ACPI / property: Extend fwnode_property_* to data-only subnodes Modify is_acpi_node() to return "true" for ACPI data-only subnodes as well as for ACPI device objects and change the name of to_acpi_node() to to_acpi_device_node() so it is clear that it covers ACPI device objects only. Accordingly, introduce to_acpi_data_node() to cover data-only subnodes in an analogous way. With that, make the fwnode_property_* family of functions work with ACPI data-only subnodes introduced previously. Signed-off-by: Rafael J. Wysocki Tested-by: Mika Westerberg --- include/linux/acpi.h | 53 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 7235c4851460..6be94ba4e980 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -49,7 +49,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) return adev ? adev->handle : NULL; } -#define ACPI_COMPANION(dev) to_acpi_node((dev)->fwnode) +#define ACPI_COMPANION(dev) to_acpi_device_node((dev)->fwnode) #define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \ acpi_fwnode_handle(adev) : NULL) #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) @@ -69,7 +69,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) static inline bool has_acpi_companion(struct device *dev) { - return is_acpi_node(dev->fwnode); + return is_acpi_device_node(dev->fwnode); } static inline void acpi_preset_companion(struct device *dev, @@ -461,7 +461,22 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode) return false; } -static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode) +static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) +{ + return false; +} + +static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) +{ + return NULL; +} + +static inline bool is_acpi_data_node(struct fwnode_handle *fwnode) +{ + return false; +} + +static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode) { return NULL; } @@ -743,17 +758,16 @@ struct acpi_reference_args { #ifdef CONFIG_ACPI int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, const union acpi_object **obj); -int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, - acpi_object_type type, - const union acpi_object **obj); int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, size_t index, struct acpi_reference_args *args); -int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, - void **valptr); +int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, + void **valptr); int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val); +int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, + enum dev_prop_type proptype, void *val, size_t nval); int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val, size_t nval); @@ -766,13 +780,7 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, { return -ENXIO; } -static inline int acpi_dev_get_property_array(struct acpi_device *adev, - const char *name, - acpi_object_type type, - const union acpi_object **obj) -{ - return -ENXIO; -} + static inline int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, const char *cells_name, size_t index, struct acpi_reference_args *args) @@ -780,6 +788,13 @@ static inline int acpi_dev_get_property_reference(struct acpi_device *adev, return -ENXIO; } +static inline int acpi_node_prop_get(struct fwnode_handle *fwnode, + const char *propname, + void **valptr) +{ + return -ENXIO; +} + static inline int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, void **valptr) @@ -795,6 +810,14 @@ static inline int acpi_dev_prop_read_single(struct acpi_device *adev, return -ENXIO; } +static inline int acpi_node_prop_read(struct fwnode_handle *fwnode, + const char *propname, + enum dev_prop_type proptype, + void *val, size_t nval) +{ + return -ENXIO; +} + static inline int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, -- cgit v1.2.3 From 504a33749971c36c54ba5ccb1364872dee1f17a7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 27 Aug 2015 04:42:33 +0200 Subject: ACPI / property: Extend device_get_next_child_node() to data-only nodes Make device_get_next_child_node() work with ACPI data-only subnodes introduced previously. Namely, replace acpi_get_next_child() with acpi_get_next_subnode() that can handle (and return) child device objects as well as child data-only subnodes of the given device and modify the ACPI part of the GPIO subsystem to handle data-only subnodes returned by it. To that end, introduce acpi_node_get_gpiod() taking a struct fwnode_handle pointer as the first argument. That argument may point to an ACPI device object as well as to a data-only subnode and the function should do the right thing (ie. look for the matching GPIO descriptor correctly) in either case. Next, modify fwnode_get_named_gpiod() to use acpi_node_get_gpiod() instead of acpi_get_gpiod_by_index() which automatically causes devm_get_gpiod_from_child() to work with ACPI data-only subnodes that may be returned by device_get_next_child_node() which in turn is required by the users of that function (the gpio_keys_polled and gpio-leds drivers). Signed-off-by: Rafael J. Wysocki Tested-by: Mika Westerberg Acked-by: Linus Walleij --- include/linux/acpi.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6be94ba4e980..865d948c60e6 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -758,9 +758,9 @@ struct acpi_reference_args { #ifdef CONFIG_ACPI int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, const union acpi_object **obj); -int acpi_dev_get_property_reference(struct acpi_device *adev, - const char *name, size_t index, - struct acpi_reference_args *args); +int acpi_node_get_property_reference(struct fwnode_handle *fwnode, + const char *name, size_t index, + struct acpi_reference_args *args); int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, void **valptr); @@ -771,8 +771,8 @@ int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val, size_t nval); -struct acpi_device *acpi_get_next_child(struct device *dev, - struct acpi_device *child); +struct fwnode_handle *acpi_get_next_subnode(struct device *dev, + struct fwnode_handle *subnode); #else static inline int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, @@ -781,7 +781,7 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, return -ENXIO; } -static inline int acpi_dev_get_property_reference(struct acpi_device *adev, +static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, const char *name, const char *cells_name, size_t index, struct acpi_reference_args *args) { @@ -826,12 +826,11 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev, return -ENXIO; } -static inline struct acpi_device *acpi_get_next_child(struct device *dev, - struct acpi_device *child) +static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev, + struct fwnode_handle *subnode) { return NULL; } - #endif #endif /*_LINUX_ACPI_H*/ -- cgit v1.2.3 From f0489a5ef4d011e29f78021ad13a543e8769d619 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 4 Sep 2015 13:47:23 +0530 Subject: PM / OPP: Rename opp init/free table routines free-table routines are opposite of init-table ones, and must be named to make that clear. Opposite of 'init' is 'exit', but those doesn't suit really well. Replace 'init' with 'add' and 'free' with 'remove'. Reported-by: Pavel Machek Reviewed-by: Stephen Boyd Signed-off-by: Viresh Kumar Acked-by: Shawn Guo Signed-off-by: Rafael J. Wysocki --- include/linux/pm_opp.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index e817722ee3f0..20adcb4ce443 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -132,28 +132,28 @@ static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( #endif /* CONFIG_PM_OPP */ #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) -int of_init_opp_table(struct device *dev); -void of_free_opp_table(struct device *dev); -int of_cpumask_init_opp_table(cpumask_var_t cpumask); -void of_cpumask_free_opp_table(cpumask_var_t cpumask); +int of_add_opp_table(struct device *dev); +void of_remove_opp_table(struct device *dev); +int of_cpumask_add_opp_table(cpumask_var_t cpumask); +void of_cpumask_remove_opp_table(cpumask_var_t cpumask); int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); #else -static inline int of_init_opp_table(struct device *dev) +static inline int of_add_opp_table(struct device *dev) { return -EINVAL; } -static inline void of_free_opp_table(struct device *dev) +static inline void of_remove_opp_table(struct device *dev) { } -static inline int of_cpumask_init_opp_table(cpumask_var_t cpumask) +static inline int of_cpumask_add_opp_table(cpumask_var_t cpumask) { return -ENOSYS; } -static inline void of_cpumask_free_opp_table(cpumask_var_t cpumask) +static inline void of_cpumask_remove_opp_table(cpumask_var_t cpumask) { } -- cgit v1.2.3 From 8f8d37b2537a28b5b2e3cb60dfc85a2a1303f99b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 4 Sep 2015 13:47:24 +0530 Subject: PM / OPP: Prefix exported opp routines with dev_pm_opp_ That's the naming convention followed in most of opp core, but few routines didn't follow this, fix them. Reviewed-by: Stephen Boyd Signed-off-by: Viresh Kumar Acked-by: Shawn Guo Signed-off-by: Rafael J. Wysocki --- include/linux/pm_opp.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 20adcb4ce443..9a2e50337af9 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -132,37 +132,37 @@ static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( #endif /* CONFIG_PM_OPP */ #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) -int of_add_opp_table(struct device *dev); -void of_remove_opp_table(struct device *dev); -int of_cpumask_add_opp_table(cpumask_var_t cpumask); -void of_cpumask_remove_opp_table(cpumask_var_t cpumask); -int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); -int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); +int dev_pm_opp_of_add_table(struct device *dev); +void dev_pm_opp_of_remove_table(struct device *dev); +int dev_pm_opp_of_cpumask_add_table(cpumask_var_t cpumask); +void dev_pm_opp_of_cpumask_remove_table(cpumask_var_t cpumask); +int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask); +int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask); #else -static inline int of_add_opp_table(struct device *dev) +static inline int dev_pm_opp_of_add_table(struct device *dev) { return -EINVAL; } -static inline void of_remove_opp_table(struct device *dev) +static inline void dev_pm_opp_of_remove_table(struct device *dev) { } -static inline int of_cpumask_add_opp_table(cpumask_var_t cpumask) +static inline int dev_pm_opp_of_cpumask_add_table(cpumask_var_t cpumask) { return -ENOSYS; } -static inline void of_cpumask_remove_opp_table(cpumask_var_t cpumask) +static inline void dev_pm_opp_of_cpumask_remove_table(cpumask_var_t cpumask) { } -static inline int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask) { return -ENOSYS; } -static inline int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask) { return -ENOSYS; } -- cgit v1.2.3 From a6f5f0dd4e21191ce35030dd4d6421e1cca10ee4 Mon Sep 17 00:00:00 2001 From: Alexandra Yates Date: Tue, 15 Sep 2015 10:32:46 -0700 Subject: PM / sleep: Report interrupt that caused system wakeup Add a sysfs attribute, /sys/power/pm_wakeup_irq, reporting the IRQ number of the first wakeup interrupt (that is, the first interrupt from an IRQ line armed for system wakeup) seen by the kernel during the most recent system suspend/resume cycle. This feature will be useful for system wakeup diagnostics of spurious wakeup interrupts. Signed-off-by: Alexandra Yates [ rjw: Fixed up pm_wakeup_irq definition ] Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5efe743ce1e8..33aaf9a9596c 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -387,10 +387,12 @@ extern int unregister_pm_notifier(struct notifier_block *nb); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; +extern unsigned int pm_wakeup_irq; extern bool pm_wakeup_pending(void); extern void pm_system_wakeup(void); extern void pm_wakeup_clear(void); +extern void pm_system_irq_wakeup(unsigned int irq_number); extern bool pm_get_wakeup_count(unsigned int *count, bool block); extern bool pm_save_wakeup_count(unsigned int count); extern void pm_wakep_autosleep_enabled(bool set); @@ -440,6 +442,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) static inline bool pm_wakeup_pending(void) { return false; } static inline void pm_system_wakeup(void) {} static inline void pm_wakeup_clear(void) {} +static inline void pm_system_irq_wakeup(unsigned int irq_number) {} static inline void lock_system_sleep(void) {} static inline void unlock_system_sleep(void) {} -- cgit v1.2.3 From 3f5c8d3187852b1cbed8546169e6293d6d421751 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 14 Sep 2015 17:37:35 +0300 Subject: device property: Add fwnode_property_match_string() Sometimes it is useful to be able to extract an index of certain string value from an array of strings. A typical use case is to give a name to a DMA channel, PWM, clock and so on. Provide an implementation using unified device property accessors that follows of_property_match_string() but works for all supported fwnodes. Signed-off-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- include/linux/property.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/property.h b/include/linux/property.h index a59c6ee566c2..463de52fe891 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname, const char **val, size_t nval); int device_property_read_string(struct device *dev, const char *propname, const char **val); +int device_property_match_string(struct device *dev, + const char *propname, const char *string); bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, @@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, size_t nval); int fwnode_property_read_string(struct fwnode_handle *fwnode, const char *propname, const char **val); +int fwnode_property_match_string(struct fwnode_handle *fwnode, + const char *propname, const char *string); struct fwnode_handle *device_get_next_child_node(struct device *dev, struct fwnode_handle *child); -- cgit v1.2.3 From c6f7b48e7e21989f4cfc996837d55c595d5dbf87 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 10 Sep 2015 16:00:50 +0200 Subject: PM / Domains: Remove name based API for genpd As all users of the named based APIs now have converted to the non-named based APIs, the time has come to remove them. Signed-off-by: Ulf Hansson Acked-by: Geert Uytterhoeven Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index b1cf7e797892..443fc196dc01 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -125,27 +125,18 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); -extern int __pm_genpd_name_add_device(const char *domain_name, - struct device *dev, - struct gpd_timing_data *td); - extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_subdomain); -extern int pm_genpd_add_subdomain_names(const char *master_name, - const char *subdomain_name); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); -extern int pm_genpd_name_attach_cpuidle(const char *name, int state); extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd); -extern int pm_genpd_name_detach_cpuidle(const char *name); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); extern int pm_genpd_poweron(struct generic_pm_domain *genpd); -extern int pm_genpd_name_poweron(const char *domain_name); extern void pm_genpd_poweroff_unused(void); extern struct dev_power_governor simple_qos_governor; @@ -166,12 +157,6 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, { return -ENOSYS; } -static inline int __pm_genpd_name_add_device(const char *domain_name, - struct device *dev, - struct gpd_timing_data *td) -{ - return -ENOSYS; -} static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev) { @@ -182,11 +167,6 @@ static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, { return -ENOSYS; } -static inline int pm_genpd_add_subdomain_names(const char *master_name, - const char *subdomain_name) -{ - return -ENOSYS; -} static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target) { @@ -196,18 +176,10 @@ static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int s { return -ENOSYS; } -static inline int pm_genpd_name_attach_cpuidle(const char *name, int state) -{ - return -ENOSYS; -} static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) { return -ENOSYS; } -static inline int pm_genpd_name_detach_cpuidle(const char *name) -{ - return -ENOSYS; -} static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { @@ -216,10 +188,6 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) { return -ENOSYS; } -static inline int pm_genpd_name_poweron(const char *domain_name) -{ - return -ENOSYS; -} static inline void pm_genpd_poweroff_unused(void) {} #endif @@ -229,12 +197,6 @@ static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, return __pm_genpd_add_device(genpd, dev, NULL); } -static inline int pm_genpd_name_add_device(const char *domain_name, - struct device *dev) -{ - return __pm_genpd_name_add_device(domain_name, dev, NULL); -} - #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP extern void pm_genpd_syscore_poweroff(struct device *dev); extern void pm_genpd_syscore_poweron(struct device *dev); -- cgit v1.2.3 From cea3ad93d9a5e054d916f1ad71da02cb306e4828 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 1 Sep 2015 20:37:49 +0200 Subject: PM / Domains: Remove cpuidle attach The power domains code allows to tie a cpuidle state with a power domain. Preventing the cpuidle framework to enter a specific idle state by disabling from the power domain framework is a good idea. Unfortunately, the current implementation has some gaps with a SMP system and a complex cpuidle implementation. Enabling a power domain wakes up all the cpus even if a cpu does not belong to the power domain. There is some work to do a logical representation with the power domains of the hardware dependencies (eg. a cpu belongs to a power domains, these power domains belong to a higher power domain for a cluster, etc ...). A new code relying on the genpd hierarchy to disable the idle states would make more sense. As the unique user of this code has been removed, let's wipe out this code to prevent new user and to have a clean place to put a new implementation. Signed-off-by: Daniel Lezcano Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 443fc196dc01..384b1d193707 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -15,7 +15,6 @@ #include #include #include -#include /* Defines used for the flags field in the struct generic_pm_domain */ #define GENPD_FLAG_PM_CLK (1U << 0) /* PM domain uses PM clk */ @@ -38,11 +37,6 @@ struct gpd_dev_ops { bool (*active_wakeup)(struct device *dev); }; -struct gpd_cpuidle_data { - unsigned int saved_exit_latency; - struct cpuidle_state *idle_state; -}; - struct generic_pm_domain { struct dev_pm_domain domain; /* PM domain operations */ struct list_head gpd_list_node; /* Node in the global PM domains list */ @@ -68,7 +62,6 @@ struct generic_pm_domain { s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; bool cached_power_down_ok; - struct gpd_cpuidle_data *cpuidle_data; int (*attach_dev)(struct generic_pm_domain *domain, struct device *dev); void (*detach_dev)(struct generic_pm_domain *domain, @@ -131,8 +124,6 @@ extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_subdomain); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); -extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); -extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); @@ -172,14 +163,6 @@ static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, { return -ENOSYS; } -static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) -{ - return -ENOSYS; -} -static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) -{ - return -ENOSYS; -} static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { -- cgit v1.2.3 From e647b532275bb357e87272e052fccf5fcdb36a17 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:12 +0100 Subject: ACPI: Add early device probing infrastructure IRQ controllers and timers are the two types of device the kernel requires before being able to use the device driver model. ACPI so far lacks a proper probing infrastructure similar to the one we have with DT, where we're able to declare IRQ chips and clocksources inside the driver code, and let the core code pick it up and call us back on a match. This leads to all kind of really ugly hacks all over the arm64 code and even in the ACPI layer. In order to allow some basic probing based on the ACPI tables, introduce "struct acpi_probe_entry" which contains just enough data and callbacks to match a table, an optional subtable, and call a probe function. A driver can, at build time, register itself and expect being called if the right entry exists in the ACPI table. A acpi_probe_device_table() is provided, taking an identifier for a set of acpi_prove_entries, and iterating over the registered entries. Signed-off-by: Marc Zyngier Reviewed-by: Lorenzo Pieralisi Reviewed-by: Hanjun Guo Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 865d948c60e6..815f5f62513f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -773,6 +773,61 @@ int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, struct fwnode_handle *acpi_get_next_subnode(struct device *dev, struct fwnode_handle *subnode); + +struct acpi_probe_entry; +typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *, + struct acpi_probe_entry *); + +#define ACPI_TABLE_ID_LEN 5 + +/** + * struct acpi_probe_entry - boot-time probing entry + * @id: ACPI table name + * @type: Optional subtable type to match + * (if @id contains subtables) + * @subtable_valid: Optional callback to check the validity of + * the subtable + * @probe_table: Callback to the driver being probed when table + * match is successful + * @probe_subtbl: Callback to the driver being probed when table and + * subtable match (and optional callback is successful) + * @driver_data: Sideband data provided back to the driver + */ +struct acpi_probe_entry { + __u8 id[ACPI_TABLE_ID_LEN]; + __u8 type; + acpi_probe_entry_validate_subtbl subtable_valid; + union { + acpi_tbl_table_handler probe_table; + acpi_tbl_entry_handler probe_subtbl; + }; + kernel_ulong_t driver_data; +}; + +#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \ + static const struct acpi_probe_entry __acpi_probe_##name \ + __used __section(__##table##_acpi_probe_table) \ + = { \ + .id = table_id, \ + .type = subtable, \ + .subtable_valid = valid, \ + .probe_table = (acpi_tbl_table_handler)fn, \ + .driver_data = data, \ + } + +#define ACPI_PROBE_TABLE(name) __##name##_acpi_probe_table +#define ACPI_PROBE_TABLE_END(name) __##name##_acpi_probe_table_end + +int __acpi_probe_device_table(struct acpi_probe_entry *start, int nr); + +#define acpi_probe_device_table(t) \ + ({ \ + extern struct acpi_probe_entry ACPI_PROBE_TABLE(t), \ + ACPI_PROBE_TABLE_END(t); \ + __acpi_probe_device_table(&ACPI_PROBE_TABLE(t), \ + (&ACPI_PROBE_TABLE_END(t) - \ + &ACPI_PROBE_TABLE(t))); \ + }) #else static inline int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, @@ -831,6 +886,17 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev, { return NULL; } + +#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \ + static const void * __acpi_table_##name[] \ + __attribute__((unused)) \ + = { (void *) table_id, \ + (void *) subtable, \ + (void *) valid, \ + (void *) fn, \ + (void *) data } + +#define acpi_probe_device_table(t) ({ int __r = 0; __r;}) #endif #endif /*_LINUX_ACPI_H*/ -- cgit v1.2.3 From 46e589a391809627144e6bee93d71d73fe915db2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:13 +0100 Subject: irqchip / ACPI: Add probing infrastructure for ACPI-based irqchips DT enjoys a rather nice probing infrastructure for irqchips, while ACPI is so far stuck into a very distant past. This patch introduces a declarative API, allowing irqchips to be self-contained and be called when a particular entry is matched in the MADT table. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Reviewed-by: Hanjun Guo Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/acpi_irq.h | 10 ---------- include/linux/irqchip.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 include/linux/acpi_irq.h (limited to 'include/linux') diff --git a/include/linux/acpi_irq.h b/include/linux/acpi_irq.h deleted file mode 100644 index f10c87265855..000000000000 --- a/include/linux/acpi_irq.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _LINUX_ACPI_IRQ_H -#define _LINUX_ACPI_IRQ_H - -#include - -#ifndef acpi_irq_init -static inline void acpi_irq_init(void) { } -#endif - -#endif /* _LINUX_ACPI_IRQ_H */ diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h index 638887376e58..89c34b200671 100644 --- a/include/linux/irqchip.h +++ b/include/linux/irqchip.h @@ -11,6 +11,7 @@ #ifndef _LINUX_IRQCHIP_H #define _LINUX_IRQCHIP_H +#include #include /* @@ -25,6 +26,22 @@ */ #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn) +/* + * This macro must be used by the different irqchip drivers to declare + * the association between their version and their initialization function. + * + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the + * same file. + * @subtable: Subtable to be identified in MADT + * @validate: Function to be called on that subtable to check its validity. + * Can be NULL. + * @data: data to be checked by the validate function. + * @fn: initialization function + */ +#define IRQCHIP_ACPI_DECLARE(name, subtable, validate, data, fn) \ + ACPI_DECLARE_PROBE_ENTRY(irqchip, name, ACPI_SIG_MADT, \ + subtable, validate, data, fn) + #ifdef CONFIG_IRQCHIP void irqchip_init(void); #else -- cgit v1.2.3 From f26527b1428f379fbd7edf779854c3b41bc0b3e5 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:14 +0100 Subject: irqchip / GIC: Convert the GIC driver to ACPI probing Now that we have a basic infrastructure to register irqchips and call them on discovery of a matching entry in MADT, convert the GIC driver to this new probing method. It ends up being a code deletion party, which is a rather good thing. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Reviewed-by: Hanjun Guo Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/irqchip/arm-gic-acpi.h | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 include/linux/irqchip/arm-gic-acpi.h (limited to 'include/linux') diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h deleted file mode 100644 index de3419ed3937..000000000000 --- a/include/linux/irqchip/arm-gic-acpi.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2014, Linaro Ltd. - * Author: Tomasz Nowicki - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARM_GIC_ACPI_H_ -#define ARM_GIC_ACPI_H_ - -#ifdef CONFIG_ACPI - -/* - * Hard code here, we can not get memory size from MADT (but FDT does), - * Actually no need to do that, because this size can be inferred - * from GIC spec. - */ -#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) -#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) - -struct acpi_table_header; - -int gic_v2_acpi_init(struct acpi_table_header *table); -void acpi_gic_init(void); -#else -static inline void acpi_gic_init(void) { } -#endif - -#endif /* ARM_GIC_ACPI_H_ */ -- cgit v1.2.3 From c625f76a9910b9d51df5d6ca40a8da0684326996 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:15 +0100 Subject: clocksource / ACPI: Add probing infrastructure for ACPI-based clocksources DT enjoys a rather nice probing infrastructure for clocksources, while ACPI is so far stuck into a very distant past. This patch introduces a declarative API, allowing clocksources to be self-contained and be called when parsing the GTDT table. Signed-off-by: Marc Zyngier Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/clocksource.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 278dd279a7a8..8cde04803d91 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -258,4 +258,7 @@ void acpi_generic_timer_init(void); static inline void acpi_generic_timer_init(void) { } #endif +#define CLOCKSOURCE_ACPI_DECLARE(name, table_id, fn) \ + ACPI_DECLARE_PROBE_ENTRY(clksrc, name, table_id, 0, NULL, 0, fn) + #endif /* _LINUX_CLOCKSOURCE_H */ -- cgit v1.2.3 From aad83b15aa21f2d9e46b978b27bc63989e61202d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:16 +0100 Subject: clocksource: Add new CLKSRC_{PROBE,ACPI} config symbols The clocksource probing infrastructure currently depends on CONFIG_CLKSRC_OF, which depends on CONFIG_OF. In order to make this infrastructure selectable even if CONFIG_OF is not selected, introduce a new CONFIG_CLKSRC_PROBE (which allow the infrastructure to be compiled in), and CONFIG_CLKSRC_ACPI (which is the pendent of CONFIG_CLKSRC_OF for ACPI). Signed-off-by: Marc Zyngier Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/clocksource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 8cde04803d91..6eab6abf89b3 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -246,7 +246,7 @@ extern int clocksource_i8253_init(void); #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ OF_DECLARE_1(clksrc, name, compat, fn) -#ifdef CONFIG_CLKSRC_OF +#ifdef CONFIG_CLKSRC_PROBE extern void clocksource_of_init(void); #else static inline void clocksource_of_init(void) {} -- cgit v1.2.3 From ae281cbd2689200329afe2474b2f39f3f6eb54b9 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:17 +0100 Subject: clocksource / arm_arch_timer: Convert to ACPI probing It is now absolutely trivial to convert the arch timer driver to use ACPI probing, just like its DT counterpart. Let's enjoy another crapectomy. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/clocksource.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 6eab6abf89b3..116645f746c1 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -252,12 +252,6 @@ extern void clocksource_of_init(void); static inline void clocksource_of_init(void) {} #endif -#ifdef CONFIG_ACPI -void acpi_generic_timer_init(void); -#else -static inline void acpi_generic_timer_init(void) { } -#endif - #define CLOCKSOURCE_ACPI_DECLARE(name, table_id, fn) \ ACPI_DECLARE_PROBE_ENTRY(clksrc, name, table_id, 0, NULL, 0, fn) -- cgit v1.2.3 From 3722ed2380ad6e89eaf81fcf93f06d605e740435 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Sep 2015 15:49:18 +0100 Subject: clocksource: cosmetic: Drop OF 'dependency' from symbols Seeing the 'of' characters in a symbol that is being called from ACPI seems to freak out people. So let's do a bit of pointless renaming so that these folks do feel at home. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Reviewed-by: Hanjun Guo Acked-by: Thomas Gleixner Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/clocksource.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 116645f746c1..7784b597e959 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -247,9 +247,9 @@ extern int clocksource_i8253_init(void); OF_DECLARE_1(clksrc, name, compat, fn) #ifdef CONFIG_CLKSRC_PROBE -extern void clocksource_of_init(void); +extern void clocksource_probe(void); #else -static inline void clocksource_of_init(void) {} +static inline void clocksource_probe(void) {} #endif #define CLOCKSOURCE_ACPI_DECLARE(name, table_id, fn) \ -- cgit v1.2.3 From f96b3c4f34b294a2293a5aa1d55e12e66aee055d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 29 Sep 2015 15:12:37 +0200 Subject: PM / Domains: Remove in_progress counter from struct generic_pm_domain Commit ba2bbfbf6307 ("PM / Domains: Remove intermediate states..") changed the power off sequence (pm_genpd_poweroff()), which from locking point of view means the genpd mutex is held throughout the sequence. The above change means the in_progress counter can't be updated while pm_genpd_poweroff() is executing, which allows us to remove the counter. Instead we inform pm_genpd_poweroff() via a bool parameter, to indicate whether we call it from the scheduled work or from the ->runtime_suspend() callback, since that all that matters. Signed-off-by: Ulf Hansson Reviewed-by: Lina Iyer Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 384b1d193707..0eaa730c890d 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -47,7 +47,6 @@ struct generic_pm_domain { struct dev_power_governor *gov; struct work_struct power_off_work; const char *name; - unsigned int in_progress; /* Number of devices being suspended now */ atomic_t sd_count; /* Number of subdomains with power "on" */ enum gpd_status status; /* Current state of the domain */ unsigned int device_count; /* Number of devices */ -- cgit v1.2.3 From bb4b72fc63d4c1c2ccd5e5af95e48b77d6cad80c Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 6 Oct 2015 14:27:42 +0200 Subject: PM / Domains: Remove pm_genpd_poweroff_unused() API As the last user of the pm_genpd_poweroff_unused() API has moved into relying on genpd to deal with this internally from a late_initcall, let's remove the API. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 0eaa730c890d..a736f0f0ca66 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -125,9 +125,7 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); - extern int pm_genpd_poweron(struct generic_pm_domain *genpd); -extern void pm_genpd_poweroff_unused(void); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -170,7 +168,6 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) { return -ENOSYS; } -static inline void pm_genpd_poweroff_unused(void) {} #endif static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, -- cgit v1.2.3 From ea823c7cbffa7bae311d78761866ac4db344c89b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 6 Oct 2015 14:27:51 +0200 Subject: PM / Domains: Remove pm_genpd_poweron() API Once genpd could be configured to be built with CONFIG_PM_RUNTIME unset (nowadays CONFIG_PM), the pm_genpd_poweron() API served a purpose, since it allowed users to power on a PM domain. As such configuration no longer is supported, users shall solely rely on using some of the runtime PM APIs to power on a PM domain. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index a736f0f0ca66..f4dd8105b024 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -125,7 +125,6 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); -extern int pm_genpd_poweron(struct generic_pm_domain *genpd); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -164,10 +163,6 @@ static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { } -static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) -{ - return -ENOSYS; -} #endif static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, -- cgit v1.2.3 From ef25ba0476015908ef5960f9faac149ddf34ede0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Oct 2015 00:49:34 +0200 Subject: PM / sleep: Add flags to indicate platform firmware involvement There are quite a few cases in which device drivers, bus types or even the PM core itself may benefit from knowing whether or not the platform firmware will be involved in the upcoming system power transition (during system suspend) or whether or not it was involved in it (during system resume). For this reason, introduce global system suspend flags that can be used by the platform code to expose that information for the benefit of the other parts of the kernel and make the ACPI core set them as appropriate. Users of the new flags will be added later. Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 33aaf9a9596c..8b6ec7ef0854 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -202,6 +202,36 @@ struct platform_freeze_ops { extern void suspend_set_ops(const struct platform_suspend_ops *ops); extern int suspend_valid_only_mem(suspend_state_t state); +extern unsigned int pm_suspend_global_flags; + +#define PM_SUSPEND_FLAG_FW_SUSPEND (1 << 0) +#define PM_SUSPEND_FLAG_FW_RESUME (1 << 1) + +static inline void pm_suspend_clear_flags(void) +{ + pm_suspend_global_flags = 0; +} + +static inline void pm_set_suspend_via_firmware(void) +{ + pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_SUSPEND; +} + +static inline void pm_set_resume_via_firmware(void) +{ + pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_RESUME; +} + +static inline bool pm_suspend_via_firmware(void) +{ + return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_SUSPEND); +} + +static inline bool pm_resume_via_firmware(void) +{ + return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_RESUME); +} + /* Suspend-to-idle state machnine. */ enum freeze_state { FREEZE_STATE_NONE, /* Not suspended/suspending. */ @@ -241,6 +271,12 @@ extern int pm_suspend(suspend_state_t state); #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL +static inline void pm_suspend_clear_flags(void) {} +static inline void pm_set_suspend_via_firmware(void) {} +static inline void pm_set_resume_via_firmware(void) {} +static inline bool pm_suspend_via_firmware(void) { return false; } +static inline bool pm_resume_via_firmware(void) { return false; } + static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {} static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } static inline bool idle_should_freeze(void) { return false; } -- cgit v1.2.3 From 58a1fbbb2ee873dd1fe327e80bc7b08e80866269 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Oct 2015 00:50:24 +0200 Subject: PM / PCI / ACPI: Kick devices that might have been reset by firmware There is a concern that if the platform firmware was involved in the system resume that's being completed, some devices might have been reset by it and if those devices had the power.direct_complete flag set during the preceding suspend transition, they may stay in a reset-power-on state indefinitely (until they are runtime-resumed and then suspended again). That may not be a big deal from the individual device's perspective, but if the system is an SoC, it may be prevented from entering deep SoC-wide low-power states on idle because of that. The devices that are most likely to be affected by this issue are PCI devices and ACPI-enumerated devices using the general ACPI PM domain, so to prevent it from happening for those devices, force a runtime resume for them if they have their power.direct_complete flags set and the platform firmware was involved in the resume transition currently in progress. Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pm.h b/include/linux/pm.h index 35d599e7250d..528be6787796 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -732,6 +732,7 @@ extern int pm_generic_poweroff_noirq(struct device *dev); extern int pm_generic_poweroff_late(struct device *dev); extern int pm_generic_poweroff(struct device *dev); extern void pm_generic_complete(struct device *dev); +extern void pm_complete_with_resume_check(struct device *dev); #else /* !CONFIG_PM_SLEEP */ -- cgit v1.2.3 From 9b3fedde27d3d63055c43c05e8254e252e58ba48 Mon Sep 17 00:00:00 2001 From: Lukasz Anaczkowski Date: Wed, 9 Sep 2015 15:47:28 +0200 Subject: ACPI / tables: Add acpi_subtable_proc to ACPI table parsers ACPI subtable parsing needs to be extended to allow two or more handlers to be run in the same ACPI table walk, thus adding acpi_subtable_proc structure which stores () ACPI table id () handler that processes table () counter how many items has been processed and passing it to acpi_parse_entries_array() and acpi_table_parse_entries_array(). This is needed to fix CPU enumeration when APIC/X2APIC entries are interleaved. Signed-off-by: Lukasz Anaczkowski Reviewed-by: Marc Zyngier Tested-by: Marc Zyngier Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 7235c4851460..b0299f8db660 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -131,6 +131,12 @@ static inline void acpi_initrd_override(void *data, size_t size) (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) +struct acpi_subtable_proc { + int id; + acpi_tbl_entry_handler handler; + int count; +}; + char * __acpi_map_table (unsigned long phys_addr, unsigned long size); void __acpi_unmap_table(char *map, unsigned long size); int early_acpi_boot_init(void); @@ -146,9 +152,16 @@ int __init acpi_parse_entries(char *id, unsigned long table_size, struct acpi_table_header *table_header, int entry_id, unsigned int max_entries); int __init acpi_table_parse_entries(char *id, unsigned long table_size, - int entry_id, - acpi_tbl_entry_handler handler, - unsigned int max_entries); + int entry_id, + acpi_tbl_entry_handler handler, + unsigned int max_entries); +int __init acpi_table_parse_entries(char *id, unsigned long table_size, + int entry_id, + acpi_tbl_entry_handler handler, + unsigned int max_entries); +int __init acpi_table_parse_entries_array(char *id, unsigned long table_size, + struct acpi_subtable_proc *proc, int proc_num, + unsigned int max_entries); int acpi_table_parse_madt(enum acpi_madt_type id, acpi_tbl_entry_handler handler, unsigned int max_entries); -- cgit v1.2.3 From 91236ecc74a25431138f71b6d52e130cd0f774b3 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 14 Oct 2015 14:29:36 +0800 Subject: ACPI/PCI: Enhance ACPI core to support sparse IO space Enhance ACPI resource parsing interfaces to support sparse IO space, which will be used to share common code between x86 and IA64 later. Tested-by: Tony Luck Signed-off-by: Jiang Liu Reviewed-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/ioport.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 388e3ae94f7a..24bea087e7af 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -94,6 +94,7 @@ struct resource { /* PnP I/O specific bits (IORESOURCE_BITS) */ #define IORESOURCE_IO_16BIT_ADDR (1<<0) #define IORESOURCE_IO_FIXED (1<<1) +#define IORESOURCE_IO_SPARSE (1<<2) /* PCI ROM control bits (IORESOURCE_BITS) */ #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ -- cgit v1.2.3 From 2c204383a2922cd6b79b9d78680a049a2144fbcc Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 14 Oct 2015 14:29:39 +0800 Subject: PCI/ACPI: Add interface acpi_pci_root_create() Introduce common interface acpi_pci_root_create() and related data structures to create PCI root bus for ACPI PCI host bridges. It will be used to kill duplicated arch specific code for IA64 and x86. It may also help ARM64 in future. Reviewed-by: Lorenzo Pieralisi Tested-by: Tony Luck Signed-off-by: Jiang Liu Acked-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- include/linux/pci-acpi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index a965efa52152..89ab0572dbc6 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -52,6 +52,30 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus) return ACPI_HANDLE(dev); } +struct acpi_pci_root; +struct acpi_pci_root_ops; + +struct acpi_pci_root_info { + struct acpi_pci_root *root; + struct acpi_device *bridge; + struct acpi_pci_root_ops *ops; + struct list_head resources; + char name[16]; +}; + +struct acpi_pci_root_ops { + struct pci_ops *pci_ops; + int (*init_info)(struct acpi_pci_root_info *info); + void (*release_info)(struct acpi_pci_root_info *info); + int (*prepare_resources)(struct acpi_pci_root_info *info); +}; + +extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info); +extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, + struct acpi_pci_root_ops *ops, + struct acpi_pci_root_info *info, + void *sd); + void acpi_pci_add_bus(struct pci_bus *bus); void acpi_pci_remove_bus(struct pci_bus *bus); -- cgit v1.2.3 From 49e4b84333f338d4f183f28f1f3c1131b9fb2b5a Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Sun, 25 Oct 2015 01:02:19 +0800 Subject: ACPI: Use correct IRQ when uninstalling ACPI interrupt handler Currently when the system is trying to uninstall the ACPI interrupt handler, it uses acpi_gbl_FADT.sci_interrupt as the IRQ number. However, the IRQ number that the ACPI interrupt handled is installed for comes from acpi_gsi_to_irq() and that is the number that should be used for the handler removal. Fix this problem by using the mapped IRQ returned from acpi_gsi_to_irq() as appropriate. Cc: All applicable Acked-by: Lv Zheng Signed-off-by: Chen Yu Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 43856d19cf4d..1ae6ba06f9ac 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -193,6 +193,12 @@ int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base); void acpi_irq_stats_init(void); extern u32 acpi_irq_handled; extern u32 acpi_irq_not_handled; +extern unsigned int acpi_sci_irq; +#define INVALID_ACPI_IRQ ((unsigned)-1) +static inline bool acpi_sci_irq_valid(void) +{ + return acpi_sci_irq != INVALID_ACPI_IRQ; +} extern int sbf_port; extern unsigned long acpi_realmode_flags; -- cgit v1.2.3 From 2b1d88cda32f81685bae45c00bf517f77bcda3cd Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 15 Oct 2015 17:02:19 +0200 Subject: PM / Domains: Merge measurements for PM QoS device latencies Measure latency does by itself contribute to an increased latency, thus we should avoid it when it isn't needed. By merging the latency measurements for the ->save_state() and the ->stop() callbacks, we get one measurement instead of two and we get one value to store instead of two. Let's also apply the likewise change for the ->start() and ->restore_state() callbacks. Signed-off-by: Ulf Hansson Reviewed-by: Lina Iyer Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index f4dd8105b024..ba4ced38efae 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -81,10 +81,8 @@ struct gpd_link { }; struct gpd_timing_data { - s64 stop_latency_ns; - s64 start_latency_ns; - s64 save_state_latency_ns; - s64 restore_state_latency_ns; + s64 suspend_latency_ns; + s64 resume_latency_ns; s64 effective_constraint_ns; bool constraint_changed; bool cached_stop_ok; -- cgit v1.2.3 From 8eec1020f0c0c03f7219ed50cf1b754be49dd448 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 15 Oct 2015 21:35:22 +0530 Subject: cpufreq: create cpu/cpufreq at boot time Later patches will need to create policy specific directories in /sys/devices/system/cpu/cpufreq/ directory and so the cpufreq directory wouldn't be ever empty. And so no fun creating/destroying it on need basis anymore. Create it once on system boot. Reviewed-by: Saravana Kannan Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index dca22de98d94..338bf0e59bb8 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -149,8 +149,6 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy) /* /sys/devices/system/cpu/cpufreq: entry point for global variables */ extern struct kobject *cpufreq_global_kobject; -int cpufreq_get_global_kobject(void); -void cpufreq_put_global_kobject(void); int cpufreq_sysfs_create_file(const struct attribute *attr); void cpufreq_sysfs_remove_file(const struct attribute *attr); -- cgit v1.2.3 From c82bd44437f5d53d1654d9e36a9e4e55610f6624 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 15 Oct 2015 21:35:23 +0530 Subject: cpufreq: remove cpufreq_sysfs_{create|remove}_file() They don't do anything special now, remove the unnecessary wrapper. Reviewed-by: Saravana Kannan Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 338bf0e59bb8..9623218d996a 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -149,8 +149,6 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy) /* /sys/devices/system/cpu/cpufreq: entry point for global variables */ extern struct kobject *cpufreq_global_kobject; -int cpufreq_sysfs_create_file(const struct attribute *attr); -void cpufreq_sysfs_remove_file(const struct attribute *attr); #ifdef CONFIG_CPU_FREQ unsigned int cpufreq_get(unsigned int cpu); -- cgit v1.2.3 From 96bdda61f58b70431bbe8a3e49794c8210f7691b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 15 Oct 2015 21:35:24 +0530 Subject: cpufreq: create cpu/cpufreq/policyX directories The cpufreq sysfs interface had been a bit inconsistent as one of the CPUs for a policy had a real directory within its sysfs 'cpuX' directory and all other CPUs had links to it. That also made the code a bit complex as we need to take care of moving the sysfs directory if the CPU containing the real directory is getting physically hot-unplugged. Solve this by creating 'policyX' directories (per-policy) in /sys/devices/system/cpu/cpufreq/ directory, where X is the CPU for which the policy was first created. This also removes the need of keeping kobj_cpu and we can remove it now. Suggested-by: Saravana Kannan Signed-off-by: Viresh Kumar Reviewed-by: Saravana Kannan Acked-by: is more of a general agreement from the person that he is Reviewed-by: is a more strict tag and implies that the reviewer has Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 9623218d996a..ef4c5b1a860f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -65,7 +65,6 @@ struct cpufreq_policy { unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs should set cpufreq */ unsigned int cpu; /* cpu managing this policy, must be online */ - unsigned int kobj_cpu; /* cpu managing sysfs files, can be offline */ struct clk *clk; struct cpufreq_cpuinfo cpuinfo;/* see above */ -- cgit v1.2.3