From patchwork Sun May 3 13:58:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 244892 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Sun, 3 May 2020 21:58:47 +0800 Subject: [PATCH V3 1/9] uclass: cpu: Add new API to get udevice for current CPU Message-ID: <20200503135855.11484-1-peng.fan@nxp.com> When running on SoC with multiple clusters, the boot CPU may not be fixed, saying booting from cluster A or cluster B. Add a API that can return the udevice for current boot CPU. Cpu driver needs to implement is_current_cpu interface for this feature, otherwise the API only returns the first udevice in cpu uclass. Reviewed-by: Simon Glass Signed-off-by: Peng Fan Signed-off-by: Ye Li --- V3: Drop ops check. Add R-b V2: Per Simon's comment, - Add cpu_is_current - use uclass_foreach_dev_probe - Update code comment drivers/cpu/cpu-uclass.c | 34 ++++++++++++++++++++++++++++++++++ include/cpu.h | 23 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index 457f77b7c8..8352e2eb0b 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -10,6 +10,7 @@ #include #include #include +#include int cpu_probe_all(void) { @@ -34,6 +35,39 @@ int cpu_probe_all(void) return 0; } +int cpu_is_current(struct udevice *cpu) +{ + struct cpu_ops *ops = cpu_get_ops(cpu); + + if (ops->is_current) { + if (ops->is_current(cpu)) + return 1; + } + + return -ENOSYS; +} + +struct udevice *cpu_get_current_dev(void) +{ + struct udevice *cpu; + int ret; + + uclass_foreach_dev_probe(UCLASS_CPU, cpu) { + if (cpu_is_current(cpu) > 0) + return cpu; + } + + /* If can't find current cpu device, use the first dev instead */ + ret = uclass_first_device_err(UCLASS_CPU, &cpu); + if (ret) { + debug("%s: Could not get CPU device (err = %d)\n", + __func__, ret); + return NULL; + } + + return cpu; +} + int cpu_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_ops *ops = cpu_get_ops(dev); diff --git a/include/cpu.h b/include/cpu.h index 6b1b6b37b3..2f283fe244 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -89,6 +89,15 @@ struct cpu_ops { * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error */ int (*get_vendor)(struct udevice *dev, char *buf, int size); + + /** + * is_current() - Check if the CPU that U-Boot is currently running from + * + * @dev: Device to check (UCLASS_CPU) + * @return 1 if the CPU that U-Boot is currently running from, 0 + * if not. + */ + int (*is_current)(struct udevice *dev); }; #define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops) @@ -137,4 +146,18 @@ int cpu_get_vendor(struct udevice *dev, char *buf, int size); */ int cpu_probe_all(void); +/** + * cpu_is_current() - Check if the CPU that U-Boot is currently running from + * + * Return: 1 if yes, - 0 if not + */ +int cpu_is_current(struct udevice *cpu); + +/** + * cpu_get_current_dev() - Get CPU udevice for current CPU + * + * Return: udevice if OK, - NULL on error + */ +struct udevice *cpu_get_current_dev(void); + #endif