
Hi Simon,
On Tue, Apr 28, 2015 at 6:48 AM, Simon Glass sjg@chromium.org wrote:
It is useful to be able to keep track of the available CPUs in a multi-CPU system. This uclass is mostly intended for use with SMP systems.
The uclass provides methods for getting basic information about each CPU.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/cpu/Kconfig | 8 +++++ drivers/cpu/Makefile | 7 ++++ drivers/cpu/cpu-uclass.c | 61 +++++++++++++++++++++++++++++++++++ include/cpu.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 7 files changed, 164 insertions(+) create mode 100644 drivers/cpu/Kconfig create mode 100644 drivers/cpu/Makefile create mode 100644 drivers/cpu/cpu-uclass.c create mode 100644 include/cpu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 941aa0c..1f40887 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -2,6 +2,8 @@ menu "Device Drivers"
source "drivers/core/Kconfig"
+source "drivers/cpu/Kconfig"
source "drivers/demo/Kconfig"
source "drivers/pci/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 5ef58c0..405b64b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_DM_DEMO) += demo/ obj-$(CONFIG_BIOSEMU) += bios_emulator/ obj-y += block/ obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/ +obj-$(CONFIG_CPU) += cpu/
Should it be CONFIG_DM_CPU?
obj-y += crypto/ obj-$(CONFIG_FPGA) += fpga/ obj-y += hwmon/ diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig new file mode 100644 index 0000000..23745e3 --- /dev/null +++ b/drivers/cpu/Kconfig @@ -0,0 +1,8 @@ +config CPU
bool "Enable CPU drivers using Driver Model"
help
This allows drivers to be provided for CPUs and their type to be
specified in the board's device tree. For boards which support
multiple CPUs, they normally have to be set up in U-Boot so that
they can work correctly in the OS. This provides a framework for
finding out information about available CPUs and making changes.
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile new file mode 100644 index 0000000..8710160 --- /dev/null +++ b/drivers/cpu/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015 Google, Inc +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-$(CONFIG_CPU) += cpu-uclass.o diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c new file mode 100644 index 0000000..ab18ee2 --- /dev/null +++ b/drivers/cpu/cpu-uclass.c @@ -0,0 +1,61 @@ +/*
- Copyright (C) 2015 Google, Inc
- Written by Simon Glass sjg@chromium.org
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/root.h>
+int cpu_get_desc(struct udevice *dev, char *buf, int size) +{
struct cpu_ops *ops = cpu_get_ops(dev);
if (!ops->get_desc)
return -ENOSYS;
return ops->get_desc(dev, buf, size);
+}
+int cpu_get_info(struct udevice *dev, struct cpu_info *info) +{
struct cpu_ops *ops = cpu_get_ops(dev);
if (!ops->get_desc)
return -ENOSYS;
return ops->get_info(dev, info);
+}
+U_BOOT_DRIVER(cpu_bus) = {
.name = "cpu_bus",
.id = UCLASS_SIMPLE_BUS,
.per_child_platdata_auto_alloc_size = sizeof(struct cpu_platdata),
+};
+static int uclass_cpu_init(struct uclass *uc) +{
struct udevice *dev;
int node;
int ret;
node = fdt_path_offset(gd->fdt_blob, "/cpus");
if (node < 0)
return 0;
ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
&dev);
return ret;
+}
+UCLASS_DRIVER(cpu) = {
.id = UCLASS_CPU,
.name = "cpu",
.flags = DM_UC_FLAG_SEQ_ALIAS,
.init = uclass_cpu_init,
+}; diff --git a/include/cpu.h b/include/cpu.h new file mode 100644 index 0000000..46467d0 --- /dev/null +++ b/include/cpu.h @@ -0,0 +1,84 @@ +/*
- Copyright (c) 2015 Google, Inc
- Written by Simon Glass sjg@chromium.org
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __cpu_h +#define __cpu_h
Should be capital letters.
+/**
- struct cpu_platdata - platform data for a CPU
- This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU
- device.
- @cpu_id: Platform-specific way of identifying the CPU.
- */
+struct cpu_platdata {
int cpu_id;
+};
+/* CPU features - mostly just a placeholder for now */ +enum {
CPU_FEAT_L1_CACHE = 0, /* Supports level 1 cache */
CPU_FEAT_MMU = 1, /* Supports virtual memory */
CPU_FEAT_COUNT,
+};
+/**
- struct cpu_info - Information about a CPU
- @cpu_freq: Current CPU frequency in Hz
- @features: Flags for supported CPU features
- */
+struct cpu_info {
ulong cpu_freq;
ulong features;
+};
+struct cpu_ops {
/**
* get_desc() - Get a description string for a CPU
*
* @dev: Device to check (UCLASS_CPU)
* @buf: Buffer to place string
* @size: Size of string space
* @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
*/
int (*get_desc)(struct udevice *dev, char *buf, int size);
/**
* get_info() - Get information about a CPU
*
* @dev: Device to check (UCLASS_CPU)
* @info: Returns CPU info
* @return 0 if OK, -ve on error
*/
int (*get_info)(struct udevice *dev, struct cpu_info *info);
+};
+#define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops)
+/**
- cpu_get_desc() - Get a description string for a CPU
- @dev: Device to check (UCLASS_CPU)
- @buf: Buffer to place string
- @size: Size of string space
- @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
- */
+int cpu_get_desc(struct udevice *dev, char *buf, int size);
+/**
- get_info() - Get information about a CPU
cpu_get_info()
- @dev: Device to check (UCLASS_CPU)
- @info: Returns CPU info
- @return 0 if OK, -ve on error
- */
+int cpu_get_info(struct udevice *dev, struct cpu_info *info);
+#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index fddfd35..395e25a 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -45,6 +45,7 @@ enum uclass_id { UCLASS_USB_HUB, /* USB hub */ UCLASS_USB_DEV_GENERIC, /* USB generic device */ UCLASS_MASS_STORAGE, /* Mass storage device */
UCLASS_CPU, /* CPU, typically part of an SoC */ UCLASS_COUNT, UCLASS_INVALID = -1,
--
Regards, Bin