From bf4661bcb0e70da975b7513006b204f01fdbc0f7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 27 Feb 2020 17:21:54 +0200 Subject: dm: serial: Add clock member to struct serial_device_info Some callers of serial_getinfo() would like to know the UART base clock speed in order to make decision what to pass to OS in some cases. In particular, ACPI SPCR table expects only certain base clock speed and thus we have to act accordingly. Signed-off-by: Andy Shevchenko Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- drivers/serial/sandbox.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index 1af5cc12f3..545ff3f747 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -198,6 +198,7 @@ static int sandbox_serial_getinfo(struct udevice *dev, .reg_width = 1, .reg_offset = 0, .reg_shift = 0, + .clock = SERIAL_DEFAULT_CLOCK, }; if (!serial_info) -- cgit From 5db92a0e960ea0559e82f8c3e2ec7f80a4e86c51 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 27 Feb 2020 17:21:55 +0200 Subject: serial: ns16550: Provide UART base clock speed in ->getinfo() Some callers may need the UART base clock speed value. Provide it in the ->getinfo() callback. Signed-off-by: Andy Shevchenko Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- drivers/serial/ns16550.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index a2f1b35629..6415d2e1e5 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -476,6 +476,8 @@ static int ns16550_serial_getinfo(struct udevice *dev, info->reg_width = plat->reg_width; info->reg_shift = plat->reg_shift; info->reg_offset = plat->reg_offset; + info->clock = plat->clock; + return 0; } -- cgit From 600f584d8191799acc19464c4a07f3056083057a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:20 -0600 Subject: cpu: Support querying the address width Different CPUs may support different address widths, meaning the amount of memory they can address. Add a property for this to the cpu_info struct. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/cpu/cpu_sandbox.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c index ff87e8adca..05b384f6a4 100644 --- a/drivers/cpu/cpu_sandbox.c +++ b/drivers/cpu/cpu_sandbox.c @@ -19,6 +19,7 @@ int cpu_sandbox_get_info(struct udevice *dev, struct cpu_info *info) { info->cpu_freq = 42 * 42 * 42 * 42 * 42; info->features = 0x42424242; + info->address_width = IS_ENABLED(CONFIG_PHYS_64BIT) ? 64 : 32; return 0; } -- cgit From 79b7ade5b5b84cb3bfe6f5546885b8f3f8f8baf1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:22 -0600 Subject: tpm: cr50: Release locality on exit At present the cr50 driver claims the locality and does not release it for Linux. This causes problems. Fix this by tracking what is claimed, and adding a 'remove' method. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/tpm/cr50_i2c.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c index b904a7d426..b30f55b40d 100644 --- a/drivers/tpm/cr50_i2c.c +++ b/drivers/tpm/cr50_i2c.c @@ -206,7 +206,7 @@ static int release_locality(struct udevice *dev, int force) cr50_i2c_write(dev, addr, &buf, 1); } - priv->locality = 0; + priv->locality = -1; return 0; } @@ -499,6 +499,7 @@ static int process_reset(struct udevice *dev) static int claim_locality(struct udevice *dev, int loc) { const u8 mask = TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY; + struct cr50_priv *priv = dev_get_priv(dev); u8 access; int ret; @@ -525,6 +526,7 @@ static int claim_locality(struct udevice *dev, int loc) return -EPERM; } log_info("Claimed locality %d\n", loc); + priv->locality = loc; return 0; } @@ -559,7 +561,11 @@ static int cr50_i2c_open(struct udevice *dev) static int cr50_i2c_cleanup(struct udevice *dev) { - release_locality(dev, 1); + struct cr50_priv *priv = dev_get_priv(dev); + + printf("%s: cleanup %d\n", __func__, priv->locality); + if (priv->locality != -1) + release_locality(dev, 1); return 0; } @@ -631,6 +637,7 @@ static int cr50_i2c_probe(struct udevice *dev) return log_msg_ret("vendor-id", -EXDEV); } priv->vendor = vendor; + priv->locality = -1; return 0; } @@ -655,5 +662,7 @@ U_BOOT_DRIVER(cr50_i2c) = { .ops = &cr50_i2c_ops, .ofdata_to_platdata = cr50_i2c_ofdata_to_platdata, .probe = cr50_i2c_probe, + .remove = cr50_i2c_cleanup, .priv_auto_alloc_size = sizeof(struct cr50_priv), + .flags = DM_FLAG_OS_PREPARE, }; -- cgit From fe6831dac40bde3e2c764f451334072b6cbefb45 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:23 -0600 Subject: tpm: cr50: Add a comment for cr50_priv Add a comment for the private structure Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/tpm/cr50_i2c.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c index b30f55b40d..c1d2d2fa38 100644 --- a/drivers/tpm/cr50_i2c.c +++ b/drivers/tpm/cr50_i2c.c @@ -34,6 +34,15 @@ enum { CR50_MAX_BUF_SIZE = 63, }; +/** + * struct cr50_priv - Private driver data + * + * @ready_gpio: GPIO to use to check if the TPM is ready + * @irq: IRQ to use check if the TPM is ready (has priority over @ready_gpio) + * @locality: Currenttly claimed locality (-1 if none) + * @vendor: vendor: Vendor ID for TPM + * @use_irq: true to use @irq, false to use @ready if available + */ struct cr50_priv { struct gpio_desc ready_gpio; struct irq irq; -- cgit From 32e8ee004a3dad1a9cc06bd3ac44d8ba562afc3e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:24 -0600 Subject: tpm: cr50: Use the correct GPIO binding This device should use ready-gpios rather than ready-gpio. Fix it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/tpm/cr50_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c index c1d2d2fa38..b67051af26 100644 --- a/drivers/tpm/cr50_i2c.c +++ b/drivers/tpm/cr50_i2c.c @@ -607,7 +607,7 @@ static int cr50_i2c_ofdata_to_platdata(struct udevice *dev) priv->irq = irq; priv->use_irq = true; } else { - ret = gpio_request_by_name(dev, "ready-gpio", 0, + ret = gpio_request_by_name(dev, "ready-gpios", 0, &priv->ready_gpio, GPIOD_IS_IN); if (ret) { log_warning("Cr50 does not have an ready GPIO/interrupt (err=%d)\n", -- cgit From 88307654af35fd550324fc1d8504db0da7225950 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:25 -0600 Subject: tpm: Don't cleanup unless an error happens At present the cleanup() method is called on every transfer. It should only be called on failing transfers. Fix this and tidy up the error handling a little. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/tpm/tpm-uclass.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c index 1b11c93194..71d5807006 100644 --- a/drivers/tpm/tpm-uclass.c +++ b/drivers/tpm/tpm-uclass.c @@ -72,7 +72,7 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size, struct tpm_ops *ops = tpm_get_ops(dev); ulong start, stop; uint count, ordinal; - int ret, ret2; + int ret, ret2 = 0; if (ops->xfer) return ops->xfer(dev, sendbuf, send_size, recvbuf, recv_size); @@ -120,9 +120,16 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size, } } while (ret); - ret2 = ops->cleanup ? ops->cleanup(dev) : 0; + if (ret) { + if (ops->cleanup) { + ret2 = ops->cleanup(dev); + if (ret2) + return log_msg_ret("cleanup", ret2); + } + return log_msg_ret("xfer", ret); + } - return ret2 ? ret2 : ret; + return 0; } UCLASS_DRIVER(tpm) = { -- cgit From d8c7fb503611f0e16184ffe43b6445740d6fa682 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:26 -0600 Subject: dm: pci: Allow disabling auto-config for a device Add a means to avoid configuring a device when needed. Add an explanation of why this is useful to the binding file. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci-uclass.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index e2882e3b63..ceb6451704 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -536,6 +536,8 @@ int pci_auto_config_devices(struct udevice *bus) int ret; debug("%s: device %s\n", __func__, dev->name); + if (dev_read_bool(dev, "pci,no-autoconfig")) + continue; ret = dm_pciauto_config_device(dev); if (ret < 0) return ret; -- cgit From 9ece4b090fdda97177ac9b3470e9b7de839eb59d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 9 Apr 2020 10:27:36 -0600 Subject: pci: Adjust dm_pci_read_bar32() to return errors correctly At present if reading a BAR returns 0xffffffff then the value is masked and a different value is returned. This makes it harder to detect the problem when debugging. Update the function to avoid masking in this case. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Reviewed-by: Wolfgang Wallner Reviewed-by: Andy Shevchenko --- drivers/pci/pci-uclass.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index ceb6451704..d2e10d6868 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1213,7 +1213,14 @@ u32 dm_pci_read_bar32(const struct udevice *dev, int barnum) bar = PCI_BASE_ADDRESS_0 + barnum * 4; dm_pci_read_config32(dev, bar, &addr); - if (addr & PCI_BASE_ADDRESS_SPACE_IO) + + /* + * If we get an invalid address, return this so that comparisons with + * FDT_ADDR_T_NONE work correctly + */ + if (addr == 0xffffffff) + return addr; + else if (addr & PCI_BASE_ADDRESS_SPACE_IO) return addr & PCI_BASE_ADDRESS_IO_MASK; else return addr & PCI_BASE_ADDRESS_MEM_MASK; -- cgit From 7ca2850cbcb2adca4f6927d9bf77626091ab5c3e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 9 Apr 2020 10:27:38 -0600 Subject: dm: core: Add basic ACPI support ACPI (Advanced Configuration and Power Interface) is a standard for specifying information about a platform. It is a little like device tree but the bindings are part of the specification and it supports an interpreted bytecode language. Driver model does not use ACPI for U-Boot's configuration, but it is convenient to have it support generation of ACPI tables for passing to Linux, etc. As a starting point, add an optional set of ACPI operations to each device. Initially only a single operation is available, to obtain the ACPI name for the device. More operations are added later. Enable ACPI for sandbox to ensure build coverage and so that we can add tests. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Reviewed-by: Wolfgang Wallner Reviewed-by: Andy Shevchenko --- drivers/core/Kconfig | 9 +++++++++ drivers/core/Makefile | 1 + drivers/core/acpi.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 drivers/core/acpi.c (limited to 'drivers') diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 3b95b5387b..a3b0399342 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -261,4 +261,13 @@ config DM_DEV_READ_INLINE bool default y if !OF_LIVE +config ACPIGEN + bool "Support ACPI table generation in driver model" + default y if SANDBOX || GENERATE_ACPI_TABLE + help + This option enables generation of ACPI tables using driver-model + devices. It adds a new operation struct to each driver, to support + things like generating device-specific tables and returning the ACPI + name of a device. + endmenu diff --git a/drivers/core/Makefile b/drivers/core/Makefile index bce7467da1..c707026a3a 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -3,6 +3,7 @@ # Copyright (c) 2013 Google, Inc obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o +obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c new file mode 100644 index 0000000000..ba50d688fe --- /dev/null +++ b/drivers/core/acpi.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Core driver model support for ACPI table generation + * + * Copyright 2019 Google LLC + * Written by Simon Glass + */ + +#define LOG_CATEOGRY LOGC_ACPI + +#include +#include +#include +#include + +int acpi_copy_name(char *out_name, const char *name) +{ + strncpy(out_name, name, ACPI_NAME_LEN); + out_name[ACPI_NAME_LEN] = '\0'; + + return 0; +} + +int acpi_get_name(const struct udevice *dev, char *out_name) +{ + struct acpi_ops *aops; + + aops = device_get_acpi_ops(dev); + if (aops && aops->get_name) + return aops->get_name(dev, out_name); + + return -ENOSYS; +} -- cgit From 3cabcf966d42649cd60eb575c9cf5c22eb9e9123 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 16:57:35 -0600 Subject: x86: Move acpi_s3.h to include/acpi/ This header relates to ACPI and we are about to add some more ACPI headers. Move this one into a new directory so they are together. The header inclusion in pci_rom.c is not specific to x86 anymore, so drop the #ifdef CONFIG_X86. Signed-off-by: Simon Glass Reviewed-by: Andy Shevchenko Reviewed-by: Wolfgang Wallner Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 4 +--- drivers/power/acpi_pmc/acpi-pmc-uclass.c | 2 +- drivers/sysreset/sysreset_x86.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 90f224b045..6b17f18bc0 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -33,12 +33,10 @@ #include #include #include +#include #include -#ifdef CONFIG_X86 -#include DECLARE_GLOBAL_DATA_PTR; -#endif __weak bool board_should_run_oprom(struct udevice *dev) { diff --git a/drivers/power/acpi_pmc/acpi-pmc-uclass.c b/drivers/power/acpi_pmc/acpi-pmc-uclass.c index d43de87126..1c79f835c6 100644 --- a/drivers/power/acpi_pmc/acpi-pmc-uclass.c +++ b/drivers/power/acpi_pmc/acpi-pmc-uclass.c @@ -6,9 +6,9 @@ #define LOG_CATEGORY UCLASS_ACPI_PMC #include -#include #include #include +#include #ifdef CONFIG_X86 #include #endif diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c index 8e2d1eaa7a..bc91143560 100644 --- a/drivers/sysreset/sysreset_x86.c +++ b/drivers/sysreset/sysreset_x86.c @@ -6,11 +6,11 @@ */ #include -#include #include #include #include #include +#include #include #include -- cgit