diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/arch_topology.c | 18 | ||||
-rw-r--r-- | drivers/base/component.c | 6 | ||||
-rw-r--r-- | drivers/base/core.c | 17 | ||||
-rw-r--r-- | drivers/base/firmware_loader/builtin/Makefile | 6 | ||||
-rw-r--r-- | drivers/base/firmware_loader/builtin/main.c | 106 | ||||
-rw-r--r-- | drivers/base/firmware_loader/firmware.h | 17 | ||||
-rw-r--r-- | drivers/base/firmware_loader/main.c | 65 | ||||
-rw-r--r-- | drivers/base/platform.c | 3 | ||||
-rw-r--r-- | drivers/base/power/main.c | 14 | ||||
-rw-r--r-- | drivers/base/power/power.h | 7 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 6 | ||||
-rw-r--r-- | drivers/base/power/wakeirq.c | 101 | ||||
-rw-r--r-- | drivers/base/property.c | 63 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-mdio.c | 6 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-spi.c | 36 | ||||
-rw-r--r-- | drivers/base/swnode.c | 6 | ||||
-rw-r--r-- | drivers/base/topology.c | 10 |
17 files changed, 301 insertions, 186 deletions
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 43407665918f..981e72a3dafb 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -12,15 +12,12 @@ #include <linux/device.h> #include <linux/of.h> #include <linux/slab.h> -#include <linux/string.h> #include <linux/sched/topology.h> #include <linux/cpuset.h> #include <linux/cpumask.h> #include <linux/init.h> -#include <linux/percpu.h> #include <linux/rcupdate.h> #include <linux/sched.h> -#include <linux/smp.h> static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data); static struct cpumask scale_freq_counters_mask; @@ -600,6 +597,11 @@ const struct cpumask *cpu_coregroup_mask(int cpu) return core_mask; } +const struct cpumask *cpu_clustergroup_mask(int cpu) +{ + return &cpu_topology[cpu].cluster_sibling; +} + void update_siblings_masks(unsigned int cpuid) { struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; @@ -617,6 +619,12 @@ void update_siblings_masks(unsigned int cpuid) if (cpuid_topo->package_id != cpu_topo->package_id) continue; + if (cpuid_topo->cluster_id == cpu_topo->cluster_id && + cpuid_topo->cluster_id != -1) { + cpumask_set_cpu(cpu, &cpuid_topo->cluster_sibling); + cpumask_set_cpu(cpuid, &cpu_topo->cluster_sibling); + } + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); @@ -635,6 +643,9 @@ static void clear_cpu_topology(int cpu) cpumask_clear(&cpu_topo->llc_sibling); cpumask_set_cpu(cpu, &cpu_topo->llc_sibling); + cpumask_clear(&cpu_topo->cluster_sibling); + cpumask_set_cpu(cpu, &cpu_topo->cluster_sibling); + cpumask_clear(&cpu_topo->core_sibling); cpumask_set_cpu(cpu, &cpu_topo->core_sibling); cpumask_clear(&cpu_topo->thread_sibling); @@ -650,6 +661,7 @@ void __init reset_cpu_topology(void) cpu_topo->thread_id = -1; cpu_topo->core_id = -1; + cpu_topo->cluster_id = -1; cpu_topo->package_id = -1; cpu_topo->llc_id = -1; diff --git a/drivers/base/component.c b/drivers/base/component.c index 5e79299f6c3f..2d25a6416587 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -9,7 +9,6 @@ */ #include <linux/component.h> #include <linux/device.h> -#include <linux/kref.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/slab.h> @@ -246,7 +245,7 @@ static int try_to_bring_up_master(struct master *master, return 0; } - if (!devres_open_group(master->parent, NULL, GFP_KERNEL)) + if (!devres_open_group(master->parent, master, GFP_KERNEL)) return -ENOMEM; /* Found all components */ @@ -258,6 +257,7 @@ static int try_to_bring_up_master(struct master *master, return ret; } + devres_close_group(master->parent, NULL); master->bound = true; return 1; } @@ -282,7 +282,7 @@ static void take_down_master(struct master *master) { if (master->bound) { master->ops->unbind(master->parent); - devres_release_group(master->parent, NULL); + devres_release_group(master->parent, master); master->bound = false; } } diff --git a/drivers/base/core.c b/drivers/base/core.c index 249da496581a..fd034d742447 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -821,9 +821,7 @@ struct device_link *device_link_add(struct device *consumer, dev_bus_name(supplier), dev_name(supplier), dev_bus_name(consumer), dev_name(consumer)); if (device_register(&link->link_dev)) { - put_device(consumer); - put_device(supplier); - kfree(link); + put_device(&link->link_dev); link = NULL; goto out; } @@ -2875,7 +2873,7 @@ void device_initialize(struct device *dev) spin_lock_init(&dev->devres_lock); INIT_LIST_HEAD(&dev->devres_head); device_pm_init(dev); - set_dev_node(dev, -1); + set_dev_node(dev, NUMA_NO_NODE); #ifdef CONFIG_GENERIC_MSI_IRQ raw_spin_lock_init(&dev->msi_lock); INIT_LIST_HEAD(&dev->msi_list); @@ -4690,6 +4688,11 @@ define_dev_printk_level(_dev_info, KERN_INFO); * * return dev_err_probe(dev, err, ...); * + * Note that it is deemed acceptable to use this function for error + * prints during probe even if the @err is known to never be -EPROBE_DEFER. + * The benefit compared to a normal dev_err() is the standardized format + * of the error code and the fact that the error code is returned. + * * Returns @err. * */ @@ -4835,6 +4838,12 @@ int device_match_acpi_dev(struct device *dev, const void *adev) } EXPORT_SYMBOL(device_match_acpi_dev); +int device_match_acpi_handle(struct device *dev, const void *handle) +{ + return ACPI_HANDLE(dev) == handle; +} +EXPORT_SYMBOL(device_match_acpi_handle); + int device_match_any(struct device *dev, const void *unused) { return 1; diff --git a/drivers/base/firmware_loader/builtin/Makefile b/drivers/base/firmware_loader/builtin/Makefile index 101754ad48d9..eb4be452062a 100644 --- a/drivers/base/firmware_loader/builtin/Makefile +++ b/drivers/base/firmware_loader/builtin/Makefile @@ -1,11 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 +obj-y += main.o # Create $(fwdir) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR)) fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) -obj-y := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) +firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) +obj-y += $(firmware) FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))) @@ -34,7 +36,7 @@ $(obj)/%.gen.S: FORCE $(call filechk,fwbin) # The .o files depend on the binaries directly; the .S files don't. -$(addprefix $(obj)/, $(obj-y)): $(obj)/%.gen.o: $(fwdir)/% +$(addprefix $(obj)/, $(firmware)): $(obj)/%.gen.o: $(fwdir)/% targets := $(patsubst $(obj)/%,%, \ $(shell find $(obj) -name \*.gen.S 2>/dev/null)) diff --git a/drivers/base/firmware_loader/builtin/main.c b/drivers/base/firmware_loader/builtin/main.c new file mode 100644 index 000000000000..a065c3150897 --- /dev/null +++ b/drivers/base/firmware_loader/builtin/main.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Builtin firmware support */ + +#include <linux/firmware.h> +#include "../firmware.h" + +/* Only if FW_LOADER=y */ +#ifdef CONFIG_FW_LOADER + +struct builtin_fw { + char *name; + void *data; + unsigned long size; +}; + +extern struct builtin_fw __start_builtin_fw[]; +extern struct builtin_fw __end_builtin_fw[]; + +static bool fw_copy_to_prealloc_buf(struct firmware *fw, + void *buf, size_t size) +{ + if (!buf) + return true; + if (size < fw->size) + return false; + memcpy(buf, fw->data, fw->size); + return true; +} + +/** + * firmware_request_builtin() - load builtin firmware + * @fw: pointer to firmware struct + * @name: name of firmware file + * + * Some use cases in the kernel have a requirement so that no memory allocator + * is involved as these calls take place early in boot process. An example is + * the x86 CPU microcode loader. In these cases all the caller wants is to see + * if the firmware was built-in and if so use it right away. This can be used + * for such cases. + * + * This looks for the firmware in the built-in kernel. Only if the kernel was + * built-in with the firmware you are looking for will this return successfully. + * + * Callers of this API do not need to use release_firmware() as the pointer to + * the firmware is expected to be provided locally on the stack of the caller. + **/ +bool firmware_request_builtin(struct firmware *fw, const char *name) +{ + struct builtin_fw *b_fw; + + if (!fw) + return false; + + for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { + if (strcmp(name, b_fw->name) == 0) { + fw->size = b_fw->size; + fw->data = b_fw->data; + return true; + } + } + + return false; +} +EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE); + +/** + * firmware_request_builtin_buf() - load builtin firmware into optional buffer + * @fw: pointer to firmware struct + * @name: name of firmware file + * @buf: If set this lets you use a pre-allocated buffer so that the built-in + * firmware into is copied into. This field can be NULL. It is used by + * callers such as request_firmware_into_buf() and + * request_partial_firmware_into_buf() + * @size: if buf was provided, the max size of the allocated buffer available. + * If the built-in firmware does not fit into the pre-allocated @buf this + * call will fail. + * + * This looks for the firmware in the built-in kernel. Only if the kernel was + * built-in with the firmware you are looking for will this call possibly + * succeed. If you passed a @buf the firmware will be copied into it *iff* the + * built-in firmware fits into the pre-allocated buffer size specified in + * @size. + * + * This caller is to be used internally by the firmware_loader only. + **/ +bool firmware_request_builtin_buf(struct firmware *fw, const char *name, + void *buf, size_t size) +{ + if (!firmware_request_builtin(fw, name)) + return false; + + return fw_copy_to_prealloc_buf(fw, buf, size); +} + +bool firmware_is_builtin(const struct firmware *fw) +{ + struct builtin_fw *b_fw; + + for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) + if (fw->data == b_fw->data) + return true; + + return false; +} + +#endif diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index a3014e9e2c85..2889f446ad41 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -151,6 +151,23 @@ static inline void fw_state_done(struct fw_priv *fw_priv) int assign_fw(struct firmware *fw, struct device *device); +#ifdef CONFIG_FW_LOADER +bool firmware_is_builtin(const struct firmware *fw); +bool firmware_request_builtin_buf(struct firmware *fw, const char *name, + void *buf, size_t size); +#else /* module case */ +static inline bool firmware_is_builtin(const struct firmware *fw) +{ + return false; +} +static inline bool firmware_request_builtin_buf(struct firmware *fw, + const char *name, + void *buf, size_t size) +{ + return false; +} +#endif + #ifdef CONFIG_FW_LOADER_PAGED_BUF void fw_free_paged_buf(struct fw_priv *fw_priv); int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index bdbedc6660a8..94d1789a233e 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -93,65 +93,6 @@ DEFINE_MUTEX(fw_lock); static struct firmware_cache fw_cache; -/* Builtin firmware support */ - -#ifdef CONFIG_FW_LOADER - -extern struct builtin_fw __start_builtin_fw[]; -extern struct builtin_fw __end_builtin_fw[]; - -static void fw_copy_to_prealloc_buf(struct firmware *fw, - void *buf, size_t size) -{ - if (!buf || size < fw->size) - return; - memcpy(buf, fw->data, fw->size); -} - -static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, - void *buf, size_t size) -{ - struct builtin_fw *b_fw; - - for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { - if (strcmp(name, b_fw->name) == 0) { - fw->size = b_fw->size; - fw->data = b_fw->data; - fw_copy_to_prealloc_buf(fw, buf, size); - - return true; - } - } - - return false; -} - -static bool fw_is_builtin_firmware(const struct firmware *fw) -{ - struct builtin_fw *b_fw; - - for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) - if (fw->data == b_fw->data) - return true; - - return false; -} - -#else /* Module case - no builtin firmware support */ - -static inline bool fw_get_builtin_firmware(struct firmware *fw, - const char *name, void *buf, - size_t size) -{ - return false; -} - -static inline bool fw_is_builtin_firmware(const struct firmware *fw) -{ - return false; -} -#endif - static void fw_state_init(struct fw_priv *fw_priv) { struct fw_state *fw_st = &fw_priv->fw_st; @@ -736,7 +677,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, return -ENOMEM; } - if (fw_get_builtin_firmware(firmware, name, dbuf, size)) { + if (firmware_request_builtin_buf(firmware, name, dbuf, size)) { dev_dbg(device, "using built-in %s\n", name); return 0; /* assigned */ } @@ -1051,7 +992,7 @@ EXPORT_SYMBOL(request_partial_firmware_into_buf); void release_firmware(const struct firmware *fw) { if (fw) { - if (!fw_is_builtin_firmware(fw)) + if (!firmware_is_builtin(fw)) firmware_free_data(fw); kfree(fw); } @@ -1215,7 +1156,7 @@ static int uncache_firmware(const char *fw_name) pr_debug("%s: %s\n", __func__, fw_name); - if (fw_get_builtin_firmware(&fw, fw_name, NULL, 0)) + if (firmware_request_builtin(&fw, fw_name)) return 0; fw_priv = lookup_fw_priv(fw_name); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 652531f67135..598acf93a360 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1466,8 +1466,7 @@ int platform_dma_configure(struct device *dev) } static const struct dev_pm_ops platform_dev_pm_ops = { - .runtime_suspend = pm_generic_runtime_suspend, - .runtime_resume = pm_generic_runtime_resume, + SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) USE_PLATFORM_PM_SLEEP_OPS }; diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index cbea78e79f3d..ac4dde8fdb8b 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -32,7 +32,6 @@ #include <linux/suspend.h> #include <trace/events/power.h> #include <linux/cpufreq.h> -#include <linux/cpuidle.h> #include <linux/devfreq.h> #include <linux/timer.h> @@ -747,8 +746,6 @@ void dpm_resume_noirq(pm_message_t state) resume_device_irqs(); device_wakeup_disarm_wake_irqs(); - - cpuidle_resume(); } /** @@ -1051,7 +1048,7 @@ static void device_complete(struct device *dev, pm_message_t state) const char *info = NULL; if (dev->power.syscore) - return; + goto out; device_lock(dev); @@ -1081,6 +1078,7 @@ static void device_complete(struct device *dev, pm_message_t state) device_unlock(dev); +out: pm_runtime_put(dev); } @@ -1336,8 +1334,6 @@ int dpm_suspend_noirq(pm_message_t state) { int ret; - cpuidle_pause(); - device_wakeup_arm_wake_irqs(); suspend_device_irqs(); @@ -1794,9 +1790,6 @@ static int device_prepare(struct device *dev, pm_message_t state) int (*callback)(struct device *) = NULL; int ret = 0; - if (dev->power.syscore) - return 0; - /* * If a device's parent goes into runtime suspend at the wrong time, * it won't be possible to resume the device. To prevent this we @@ -1805,6 +1798,9 @@ static int device_prepare(struct device *dev, pm_message_t state) */ pm_runtime_get_noresume(dev); + if (dev->power.syscore) + return 0; + device_lock(dev); dev->power.wakeup_path = false; diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 54292cdd7808..0eb7f02b3ad5 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -25,8 +25,10 @@ extern u64 pm_runtime_active_time(struct device *dev); #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) +#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ - WAKE_IRQ_DEDICATED_MANAGED) + WAKE_IRQ_DEDICATED_MANAGED | \ + WAKE_IRQ_DEDICATED_REVERSE) struct wake_irq { struct device *dev; @@ -39,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); extern void dev_pm_enable_wake_irq_check(struct device *dev, bool can_change_status); -extern void dev_pm_disable_wake_irq_check(struct device *dev); +extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); +extern void dev_pm_enable_wake_irq_complete(struct device *dev); #ifdef CONFIG_PM_SLEEP diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index ec94049442b9..d504cd4ab3cb 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -645,6 +645,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) if (retval) goto fail; + dev_pm_enable_wake_irq_complete(dev); + no_callback: __update_runtime_status(dev, RPM_SUSPENDED); pm_runtime_deactivate_timer(dev); @@ -690,7 +692,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) return retval; fail: - dev_pm_disable_wake_irq_check(dev); + dev_pm_disable_wake_irq_check(dev, true); __update_runtime_status(dev, RPM_ACTIVE); dev->power.deferred_resume = false; wake_up_all(&dev->power.wait_queue); @@ -873,7 +875,7 @@ static int rpm_resume(struct device *dev, int rpmflags) callback = RPM_GET_CALLBACK(dev, runtime_resume); - dev_pm_disable_wake_irq_check(dev); + dev_pm_disable_wake_irq_check(dev, false); retval = rpm_callback(callback, dev); if (retval) { __update_runtime_status(dev, RPM_SUSPENDED); diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index b91a3a9bf9f6..0004db4a9d3b 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -142,24 +142,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq) return IRQ_HANDLED; } -/** - * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt - * @dev: Device entry - * @irq: Device wake-up interrupt - * - * Unless your hardware has separate wake-up interrupts in addition - * to the device IO interrupts, you don't need this. - * - * Sets up a threaded interrupt handler for a device that has - * a dedicated wake-up interrupt in addition to the device IO - * interrupt. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() - * functions. - */ -int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) +static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) { struct wake_irq *wirq; int err; @@ -197,7 +180,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) if (err) goto err_free_irq; - wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; + wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; return err; @@ -210,9 +193,58 @@ err_free: return err; } + + +/** + * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt + * @dev: Device entry + * @irq: Device wake-up interrupt + * + * Unless your hardware has separate wake-up interrupts in addition + * to the device IO interrupts, you don't need this. + * + * Sets up a threaded interrupt handler for a device that has + * a dedicated wake-up interrupt in addition to the device IO + * interrupt. + * + * The interrupt starts disabled, and needs to be managed for + * the device by the bus code or the device driver using + * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() + * functions. + */ +int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) +{ + return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); +} EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); /** + * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt + * with reverse enable ordering + * @dev: Device entry + * @irq: Device wake-up interrupt + * + * Unless your hardware has separate wake-up interrupts in addition + * to the device IO interrupts, you don't need this. + * + * Sets up a threaded interrupt handler for a device that has a dedicated + * wake-up interrupt in addition to the device IO interrupt. It sets + * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() + * to enable dedicated wake-up interrupt after running the runtime suspend + * callback for @dev. + * + * The interrupt starts disabled, and needs to be managed for + * the device by the bus code or the device driver using + * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() + * functions. + */ +int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) +{ + return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); +} +EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); + +/** * dev_pm_enable_wake_irq - Enable device wake-up interrupt * @dev: Device * @@ -282,28 +314,55 @@ void dev_pm_enable_wake_irq_check(struct device *dev, return; enable: - enable_irq(wirq->irq); + if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) + enable_irq(wirq->irq); } /** * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt * @dev: Device + * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE * * Disables wake-up interrupt conditionally based on status. * Should be only called from rpm_suspend() and rpm_resume() path. */ -void dev_pm_disable_wake_irq_check(struct device *dev) +void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) { struct wake_irq *wirq = dev->power.wakeirq; if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) return; + if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) + return; + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) disable_irq_nosync(wirq->irq); } /** + * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before + * @dev: Device using the wake IRQ + * + * Enable wake IRQ conditionally based on status, mainly used if want to + * enable wake IRQ after running ->runtime_suspend() which depends on + * WAKE_IRQ_DEDICATED_REVERSE. + * + * Should be only called from rpm_suspend() path. + */ +void dev_pm_enable_wake_irq_complete(struct device *dev) +{ + struct wake_irq *wirq = dev->power.wakeirq; + + if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) + return; + + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && + wirq->status & WAKE_IRQ_DEDICATED_REVERSE) + enable_irq(wirq->irq); +} + +/** * dev_pm_arm_wake_irq - Arm device wake-up * @wirq: Device wake-up interrupt * diff --git a/drivers/base/property.c b/drivers/base/property.c index 453918eb7390..f1f35b48ab8b 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -15,7 +15,6 @@ #include <linux/of_graph.h> #include <linux/of_irq.h> #include <linux/property.h> -#include <linux/etherdevice.h> #include <linux/phy.h> struct fwnode_handle *dev_fwnode(struct device *dev) @@ -935,68 +934,6 @@ int device_get_phy_mode(struct device *dev) } EXPORT_SYMBOL_GPL(device_get_phy_mode); -static void *fwnode_get_mac_addr(struct fwnode_handle *fwnode, - const char *name, char *addr, - int alen) -{ - int ret = fwnode_property_read_u8_array(fwnode, name, addr, alen); - - if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr)) - return addr; - return NULL; -} - -/** - * fwnode_get_mac_address - Get the MAC from the firmware node - * @fwnode: Pointer to the firmware node - * @addr: Address of buffer to store the MAC in - * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN - * - * Search the firmware node for the best MAC address to use. 'mac-address' is - * checked first, because that is supposed to contain to "most recent" MAC - * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. - * - * Note that the 'address' property is supposed to contain a virtual address of - * the register set, but some DTS files have redefined that property to be the - * MAC address. - * - * All-zero MAC addresses are rejected, because those could be properties that - * exist in the firmware tables, but were not updated by the firmware. For - * example, the DTS could define 'mac-address' and 'local-mac-address', with - * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'. - * In this case, the real MAC is in 'local-mac-address', and 'mac-address' - * exists but is all zeros. -*/ -void *fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr, int alen) -{ - char *res; - - res = fwnode_get_mac_addr(fwnode, "mac-address", addr, alen); - if (res) - return res; - - res = fwnode_get_mac_addr(fwnode, "local-mac-address", addr, alen); - if (res) - return res; - - return fwnode_get_mac_addr(fwnode, "address", addr, alen); -} -EXPORT_SYMBOL(fwnode_get_mac_address); - -/** - * device_get_mac_address - Get the MAC for a given device - * @dev: Pointer to the device - * @addr: Address of buffer to store the MAC in - * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN - */ -void *device_get_mac_address(struct device *dev, char *addr, int alen) -{ - return fwnode_get_mac_address(dev_fwnode(dev), addr, alen); -} -EXPORT_SYMBOL(device_get_mac_address); - /** * fwnode_irq_get - Get IRQ directly from a fwnode * @fwnode: Pointer to the firmware node diff --git a/drivers/base/regmap/regmap-mdio.c b/drivers/base/regmap/regmap-mdio.c index 6a20201299f5..f7293040a2b1 100644 --- a/drivers/base/regmap/regmap-mdio.c +++ b/drivers/base/regmap/regmap-mdio.c @@ -14,7 +14,7 @@ static int regmap_mdio_read(struct mdio_device *mdio_dev, u32 reg, unsigned int { int ret; - ret = mdiobus_read(mdio_dev->bus, mdio_dev->addr, reg); + ret = mdiodev_read(mdio_dev, reg); if (ret < 0) return ret; @@ -24,7 +24,7 @@ static int regmap_mdio_read(struct mdio_device *mdio_dev, u32 reg, unsigned int static int regmap_mdio_write(struct mdio_device *mdio_dev, u32 reg, unsigned int val) { - return mdiobus_write(mdio_dev->bus, mdio_dev->addr, reg, val); + return mdiodev_write(mdio_dev, reg, val); } static int regmap_mdio_c22_read(void *context, unsigned int reg, unsigned int *val) @@ -44,7 +44,7 @@ static int regmap_mdio_c22_write(void *context, unsigned int reg, unsigned int v if (unlikely(reg & ~REGNUM_C22_MASK)) return -ENXIO; - return mdiobus_write(mdio_dev->bus, mdio_dev->addr, reg, val); + return mdiodev_write(mdio_dev, reg, val); } static const struct regmap_bus regmap_mdio_c22_bus = { diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index c1894e93c378..719323bc6c7f 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -109,13 +109,37 @@ static const struct regmap_bus regmap_spi = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; +static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, + const struct regmap_config *config) +{ + size_t max_size = spi_max_transfer_size(spi); + struct regmap_bus *bus; + + if (max_size != SIZE_MAX) { + bus = kmemdup(®map_spi, sizeof(*bus), GFP_KERNEL); + if (!bus) + return ERR_PTR(-ENOMEM); + + bus->free_on_exit = true; + bus->max_raw_read = max_size; + bus->max_raw_write = max_size; + return bus; + } + + return ®map_spi; +} + struct regmap *__regmap_init_spi(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { - return __regmap_init(&spi->dev, ®map_spi, &spi->dev, config, - lock_key, lock_name); + const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); + + if (IS_ERR(bus)) + return ERR_CAST(bus); + + return __regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_spi); @@ -124,8 +148,12 @@ struct regmap *__devm_regmap_init_spi(struct spi_device *spi, struct lock_class_key *lock_key, const char *lock_name) { - return __devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config, - lock_key, lock_name); + const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); + + if (IS_ERR(bus)) + return ERR_CAST(bus); + + return __devm_regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_spi); diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index c46f6a8e14d2..4debcea4fb12 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -413,9 +413,6 @@ software_node_get_name(const struct fwnode_handle *fwnode) { const struct swnode *swnode = to_swnode(fwnode); - if (!swnode) - return "(null)"; - return kobject_name(&swnode->kobj); } @@ -507,9 +504,6 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, int error; int i; - if (!swnode) - return -ENOENT; - prop = property_entry_get(swnode->node->properties, propname); if (!prop) return -ENOENT; diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 43c0940643f5..8f2b641d0b8c 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -48,6 +48,9 @@ static DEVICE_ATTR_RO(physical_package_id); define_id_show_func(die_id); static DEVICE_ATTR_RO(die_id); +define_id_show_func(cluster_id); +static DEVICE_ATTR_RO(cluster_id); + define_id_show_func(core_id); static DEVICE_ATTR_RO(core_id); @@ -63,6 +66,10 @@ define_siblings_read_func(core_siblings, core_cpumask); static BIN_ATTR_RO(core_siblings, 0); static BIN_ATTR_RO(core_siblings_list, 0); +define_siblings_read_func(cluster_cpus, cluster_cpumask); +static BIN_ATTR_RO(cluster_cpus, 0); +static BIN_ATTR_RO(cluster_cpus_list, 0); + define_siblings_read_func(die_cpus, die_cpumask); static BIN_ATTR_RO(die_cpus, 0); static BIN_ATTR_RO(die_cpus_list, 0); @@ -94,6 +101,8 @@ static struct bin_attribute *bin_attrs[] = { &bin_attr_thread_siblings_list, &bin_attr_core_siblings, &bin_attr_core_siblings_list, + &bin_attr_cluster_cpus, + &bin_attr_cluster_cpus_list, &bin_attr_die_cpus, &bin_attr_die_cpus_list, &bin_attr_package_cpus, @@ -112,6 +121,7 @@ static struct bin_attribute *bin_attrs[] = { static struct attribute *default_attrs[] = { &dev_attr_physical_package_id.attr, &dev_attr_die_id.attr, + &dev_attr_cluster_id.attr, &dev_attr_core_id.attr, #ifdef CONFIG_SCHED_BOOK &dev_attr_book_id.attr, |