diff options
-rw-r--r-- | configs/minnowmax_defconfig | 2 | ||||
-rw-r--r-- | configs/mx6sxsabresd_defconfig | 2 | ||||
-rw-r--r-- | configs/mx6sxsabresd_spl_defconfig | 2 | ||||
-rw-r--r-- | configs/odroid_defconfig | 2 | ||||
-rw-r--r-- | configs/peach-pi_defconfig | 4 | ||||
-rw-r--r-- | configs/peach-pit_defconfig | 4 | ||||
-rw-r--r-- | configs/sandbox_defconfig | 5 | ||||
-rw-r--r-- | configs/snow_defconfig | 5 | ||||
-rw-r--r-- | doc/device-tree-bindings/gpio/gpio.txt | 5 | ||||
-rw-r--r-- | drivers/i2c/Kconfig | 9 | ||||
-rw-r--r-- | drivers/input/Kconfig | 6 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 48 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 59 | ||||
-rw-r--r-- | drivers/serial/ns16550.c | 98 | ||||
-rw-r--r-- | include/configs/exynos5-common.h | 2 | ||||
-rw-r--r-- | include/configs/exynos5-dt-common.h | 3 | ||||
-rw-r--r-- | include/configs/mx6sxsabresd.h | 2 | ||||
-rw-r--r-- | include/configs/odroid.h | 2 | ||||
-rw-r--r-- | include/configs/peach-pi.h | 1 | ||||
-rw-r--r-- | include/configs/peach-pit.h | 1 | ||||
-rw-r--r-- | include/configs/sandbox.h | 4 | ||||
-rw-r--r-- | include/configs/snow.h | 2 | ||||
-rw-r--r-- | include/debug_uart.h | 139 | ||||
-rw-r--r-- | include/dm/device-internal.h | 4 |
24 files changed, 371 insertions, 40 deletions
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 7bc9085..d124289 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -7,7 +7,5 @@ CONFIG_DEFAULT_DEVICE_TREE="minnowmax" CONFIG_VIDEO_X86=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y -CONFIG_DEBUG_UART_NS16550=y -CONFIG_DEBUG_UART=y CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 CONFIG_HAVE_INTEL_ME=y diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index 72e0f10..cc82322 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_MX6SXSABRESD=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig index 6b36e06..901b01b 100644 --- a/configs/mx6sxsabresd_spl_defconfig +++ b/configs/mx6sxsabresd_spl_defconfig @@ -2,3 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX" +S:CONFIG_ARM=y +S:CONFIG_TARGET_MX6SXSABRESD=y +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig index a842837..816a3fa 100644 --- a/configs/odroid_defconfig +++ b/configs/odroid_defconfig @@ -3,3 +3,5 @@ CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig index 8ada0db..333e335 100644 --- a/configs/peach-pi_defconfig +++ b/configs/peach-pi_defconfig @@ -3,3 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_PEACH_PI=y CONFIG_DEFAULT_DEVICE_TREE="exynos5800-peach-pi" +CONFIG_CROS_EC=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig index b944b3b..cf84444 100644 --- a/configs/peach-pit_defconfig +++ b/configs/peach-pit_defconfig @@ -3,3 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_PEACH_PIT=y CONFIG_DEFAULT_DEVICE_TREE="exynos5420-peach-pit" +CONFIG_CROS_EC=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 0bf5ea3..70f5b86 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -7,3 +7,8 @@ CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_CROS_EC=y +CONFIG_DM_CROS_EC=y +CONFIG_CROS_EC_SANDBOX=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/snow_defconfig b/configs/snow_defconfig index 14ed793..353ddb0 100644 --- a/configs/snow_defconfig +++ b/configs/snow_defconfig @@ -3,3 +3,8 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_SNOW=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow" +CONFIG_CROS_EC=y +CONFIG_DM_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/doc/device-tree-bindings/gpio/gpio.txt b/doc/device-tree-bindings/gpio/gpio.txt index b9bd1d6..f7a158d 100644 --- a/doc/device-tree-bindings/gpio/gpio.txt +++ b/doc/device-tree-bindings/gpio/gpio.txt @@ -69,7 +69,8 @@ GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller. ---------------------------------- A gpio-specifier should contain a flag indicating the GPIO polarity; active- -high or active-low. If it does, the follow best practices should be followed: +high or active-low. If it does, the following best practices should be +followed: The gpio-specifier's polarity flag should represent the physical level at the GPIO controller that achieves (or represents, for inputs) a logically asserted @@ -147,7 +148,7 @@ contains information structures as follows: numeric-gpio-range ::= <pinctrl-phandle> <gpio-base> <pinctrl-base> <count> named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>' - gpio-phandle : phandle to pin controller node. + pinctrl-phandle : phandle to pin controller node gpio-base : Base GPIO ID in the GPIO controller pinctrl-base : Base pinctrl pin ID in the pin controller count : The number of GPIOs/pins in this range diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 2cc776c..692810d 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -13,6 +13,15 @@ config DM_I2C enabled together (it is not possible to use driver model for one and not the other). +config DM_I2C_COMPAT + bool "Enable I2C compatibility layer" + depends on DM + help + Enable old-style I2C functions for compatibility with existing code. + This option can be enabled as a temporary measure to avoid needing + to convert all code for a board in a single commit. It should not + be enabled for any board in an official release. + config SYS_I2C_UNIPHIER bool "UniPhier I2C driver" depends on ARCH_UNIPHIER && DM_I2C diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e69de29..bb00de7 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -0,0 +1,6 @@ +config CROS_EC_KEYB + bool "Enable Chrome OS EC keyboard support" + help + Most ARM Chromebooks use an EC to provide access to the keyboard. + Messages are used to request key scans from the EC and these are + then decoded into keys by this driver. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 813d1c2..0df25c3 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -1,3 +1,49 @@ +config CMD_CROS_EC + bool "Enable crosec command" + depends on CROS_EC + help + Enable command-line access to the Chrome OS EC (Embedded + Controller). This provides the 'crosec' command which has + a number of sub-commands for performing EC tasks such as + updating its flash, accessing a small saved context area + and talking to the I2C bus behind the EC (if there is one). + +config CROS_EC + bool "Enable Chrome OS EC" + help + Enable access to the Chrome OS EC. This is a separate + microcontroller typically available on a SPI bus on Chromebooks. It + provides access to the keyboard, some internal storage and may + control access to the battery and main PMIC depending on the + device. You can use the 'crosec' command to access it. + +config CROS_EC_I2C + bool "Enable Chrome OS EC I2C driver" + depends on CROS_EC + help + Enable I2C access to the Chrome OS EC. This is used on older + ARM Chromebooks such as snow and spring before the standard bus + changed to SPI. The EC will accept commands across the I2C using + a special message protocol, and provide responses. + +config CROS_EC_LPC + bool "Enable Chrome OS EC LPC driver" + depends on CROS_EC + help + Enable I2C access to the Chrome OS EC. This is used on x86 + Chromebooks such as link and falco. The keyboard is provided + through a legacy port interface, so on x86 machines the main + function of the EC is power and thermal management. + +config CROS_EC_SPI + bool "Enable Chrome OS EC SPI driver" + depends on CROS_EC + help + Enable SPI access to the Chrome OS EC. This is used on newer + ARM Chromebooks such as pit, pi and nyan-big. The SPI interface + provides a faster and more robust interface than I2C but the bugs + are less interesting. + config DM_CROS_EC bool "Enable Driver Model for Chrome OS EC" depends on DM @@ -5,5 +51,5 @@ config DM_CROS_EC Enable driver model for the Chrome OS EC interface. This allows the cros_ec SPI driver to operate with CONFIG_DM_SPI but otherwise makes few changes. Since cros_ec also supports - I2C and LPC (which don't support driver model yet), a full + LPC (which doesn't support driver model yet), a full conversion is not yet possible. diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index c94353b..1686a1f 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -7,6 +7,65 @@ config DM_SERIAL implements serial_putc() etc. The uclass interface is defined in include/serial.h. +config DEBUG_UART + bool "Enable an early debug UART for debugging" + help + The debug UART is intended for use very early in U-Boot to debug + problems when an ICE or other debug mechanism is not available. + + To use it you should: + - Make sure your UART supports this interface + - Enable CONFIG_DEBUG_UART + - Enable the CONFIG for your UART to tell it to provide this interface + (e.g. CONFIG_DEBUG_UART_NS16550) + - Define the required settings as needed (see below) + - Call debug_uart_init() before use + - Call debug_uart_putc() to output a character + + Depending on your platform it may be possible to use this UART before + a stack is available. + + If your UART does not support this interface you can probably add + support quite easily. Remember that you cannot use driver model and + it is preferred to use no stack. + + You must not use this UART once driver model is working and the + serial drivers are up and running (done in serial_init()). Otherwise + the drivers may conflict and you will get strange output. + +choice + prompt "Select which UART will provide the debug UART" + depends on DEBUG_UART + +config DEBUG_UART_NS16550 + bool "ns16550" + help + Select this to enable a debug UART using the ns16550 driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + +endchoice + +config DEBUG_UART_BASE + hex "Base address of UART" + depends on DEBUG_UART + help + This is the base address of your UART for memory-mapped UARTs. + + A default should be provided by your board, but if not you will need + to use the correct value here. + +config DEBUG_UART_CLOCK + int "UART input clock" + depends on DEBUG_UART + help + The UART input clock determines the speed of the internal UART + circuitry. The baud rate is derived from this by dividing the input + clock down. + + A default should be provided by your board, but if not you will need + to use the correct value here. + config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" depends on ARCH_UNIPHIER && DM_SERIAL diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 70c9462..eb00f1c 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -55,17 +55,9 @@ DECLARE_GLOBAL_DATA_PTR; #endif /* CONFIG_SYS_NS16550_IER */ #ifdef CONFIG_DM_SERIAL -static void ns16550_writeb(NS16550_t port, int offset, int value) -{ - struct ns16550_platdata *plat = port->plat; - unsigned char *addr; - offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; - /* - * As far as we know it doesn't make sense to support selection of - * these options at run-time, so use the existing CONFIG options. - */ +static inline void serial_out_shift(unsigned char *addr, int shift, int value) +{ #ifdef CONFIG_SYS_NS16550_PORT_MAPPED outb(value, (ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) @@ -73,19 +65,14 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) out_be32(addr, value); #elif defined(CONFIG_SYS_BIG_ENDIAN) - writeb(value, addr + (1 << plat->reg_shift) - 1); + writeb(value, addr + (1 << shift) - 1); #else writeb(value, addr); #endif } -static int ns16550_readb(NS16550_t port, int offset) +static inline int serial_in_shift(unsigned char *addr, int shift) { - struct ns16550_platdata *plat = port->plat; - unsigned char *addr; - - offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; #ifdef CONFIG_SYS_NS16550_PORT_MAPPED return inb((ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) @@ -93,12 +80,37 @@ static int ns16550_readb(NS16550_t port, int offset) #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) return in_be32(addr); #elif defined(CONFIG_SYS_BIG_ENDIAN) - return readb(addr + (1 << plat->reg_shift) - 1); + return readb(addr + (1 << reg_shift) - 1); #else return readb(addr); #endif } +static void ns16550_writeb(NS16550_t port, int offset, int value) +{ + struct ns16550_platdata *plat = port->plat; + unsigned char *addr; + + offset *= 1 << plat->reg_shift; + addr = map_sysmem(plat->base, 0) + offset; + /* + * As far as we know it doesn't make sense to support selection of + * these options at run-time, so use the existing CONFIG options. + */ + serial_out_shift(addr, plat->reg_shift, value); +} + +static int ns16550_readb(NS16550_t port, int offset) +{ + struct ns16550_platdata *plat = port->plat; + unsigned char *addr; + + offset *= 1 << plat->reg_shift; + addr = map_sysmem(plat->base, 0) + offset; + + return serial_in_shift(addr, plat->reg_shift); +} + /* We can clean these up once everything is moved to driver model */ #define serial_out(value, addr) \ ns16550_writeb(com_port, addr - (unsigned char *)com_port, value) @@ -106,10 +118,15 @@ static int ns16550_readb(NS16550_t port, int offset) ns16550_readb(com_port, addr - (unsigned char *)com_port) #endif -int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) +static inline int calc_divisor(NS16550_t port, int clock, int baudrate) { const unsigned int mode_x_div = 16; + return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); +} + +int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) +{ #ifdef CONFIG_OMAP1510 /* If can't cleanly clock 115200 set div to 1 */ if ((clock == 12000000) && (baudrate == 115200)) { @@ -119,7 +136,7 @@ int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) port->osc_12m_sel = 0; /* clear if previsouly set */ #endif - return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); + return calc_divisor(port, clock, baudrate); } static void NS16550_setbrg(NS16550_t com_port, int baud_divisor) @@ -219,6 +236,47 @@ int NS16550_tstc(NS16550_t com_port) #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ +#ifdef CONFIG_DEBUG_UART_NS16550 + +#include <debug_uart.h> + +void debug_uart_init(void) +{ + struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; + int baud_divisor; + + /* + * We copy the code from above because it is already horribly messy. + * Trying to refactor to nicely remove the duplication doesn't seem + * feasible. The better fix is to move all users of this driver to + * driver model. + */ + baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK, + CONFIG_BAUDRATE); + + serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER); + serial_out_shift(&com_port->mcr, 0, UART_MCRVAL); + serial_out_shift(&com_port->fcr, 0, UART_FCRVAL); + + serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL); + serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff); + serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff); + serial_out_shift(&com_port->lcr, 0, UART_LCRVAL); +} + +static inline void _debug_uart_putc(int ch) +{ + struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; + + while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE)) + ; + serial_out_shift(&com_port->thr, 0, ch); +} + +DEBUG_UART_FUNCS + +#endif + #ifdef CONFIG_DM_SERIAL static int ns16550_serial_putc(struct udevice *dev, const char ch) { diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index 0ba39a2..3ab8d55 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -126,6 +126,8 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE) /* I2C */ + +/* TODO(sjg@chromium.org): Move these two options to Kconfig */ #define CONFIG_DM_I2C #define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 9cef0b0..b1b8e1a 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -24,9 +24,6 @@ #define CONFIG_POWER_TPS65090 /* Enable keyboard */ -#define CONFIG_CROS_EC /* CROS_EC protocol */ -#define CONFIG_CROS_EC_KEYB /* CROS_EC keyboard input */ -#define CONFIG_CMD_CROS_EC #define CONFIG_KEYBOARD #endif diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 1005b9e..a290129 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -227,8 +227,6 @@ #define CONFIG_PCIE_IMX_POWER_GPIO IMX_GPIO_NR(2, 1) #endif -#define CONFIG_DM -#define CONFIG_DM_THERMAL #define CONFIG_IMX6_THERMAL #define CONFIG_CMD_FUSE diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 9d5dbdc..8b47537 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -177,8 +177,6 @@ /* I2C */ #define CONFIG_CMD_I2C -#define CONFIG_DM_I2C -#define CONFIG_DM_I2C_COMPAT #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index f724164..f04f061 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -43,7 +43,6 @@ #endif #define CONFIG_POWER_TPS65090_EC -#define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index de12a9e..b5efbdc 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -43,7 +43,6 @@ #endif #define CONFIG_POWER_TPS65090_EC -#define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 5c11650..febbfb6 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -141,9 +141,6 @@ #define CONFIG_BOOTARGS "" -#define CONFIG_CROS_EC -#define CONFIG_CMD_CROS_EC -#define CONFIG_CROS_EC_SANDBOX #define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_BOARD_LATE_INIT @@ -166,7 +163,6 @@ #define LCD_BPP LCD_COLOR16 #define CONFIG_LCD_BMP_RLE8 -#define CONFIG_CROS_EC_KEYB #define CONFIG_KEYBOARD #define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial,cros-ec-keyb\0" \ diff --git a/include/configs/snow.h b/include/configs/snow.h index ce6676e..fe802f2 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -20,9 +20,7 @@ #include <configs/exynos5-dt-common.h> -#define CONFIG_CROS_EC_I2C /* Support CROS_EC over I2C */ #define CONFIG_POWER_TPS65090_I2C -#define CONFIG_DM_CROS_EC #define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R diff --git a/include/debug_uart.h b/include/debug_uart.h new file mode 100644 index 0000000..f56797b --- /dev/null +++ b/include/debug_uart.h @@ -0,0 +1,139 @@ +/* + * Early debug UART support + * + * (C) Copyright 2014 Google, Inc + * Writte by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _DEBUG_UART_H +#define _DEBUG_UART_H + +#include <linux/linkage.h> + +/* + * The debug UART is intended for use very early in U-Boot to debug problems + * when an ICE or other debug mechanism is not available. + * + * To use it you should: + * - Make sure your UART supports this interface + * - Enable CONFIG_DEBUG_UART + * - Enable the CONFIG for your UART to tell it to provide this interface + * (e.g. CONFIG_DEBUG_UART_NS16550) + * - Define the required settings as needed (see below) + * - Call debug_uart_init() before use + * - Call printch() to output a character + * + * Depending on your platform it may be possible to use this UART before a + * stack is available. + * + * If your UART does not support this interface you can probably add support + * quite easily. Remember that you cannot use driver model and it is preferred + * to use no stack. + * + * You must not use this UART once driver model is working and the serial + * drivers are up and running (done in serial_init()). Otherwise the drivers + * may conflict and you will get strange output. + * + * + * To enable the debug UART in your serial driver: + * + * - #include <debug_uart.h> + * - Define debug_uart_init(), trying to avoid using the stack + * - Define _debug_uart_putc() as static inline (avoiding stack usage) + * - Immediately afterwards, add DEBUG_UART_FUNCS to define the rest of the + * functionality (printch(), etc.) + */ + +/** + * debug_uart_init() - Set up the debug UART ready for use + * + * This sets up the UART with the correct baud rate, etc. + * + * Available CONFIG is: + * + * - CONFIG_DEBUG_UART_BASE: Base address of UART + * - CONFIG_BAUDRATE: Requested baud rate + * - CONFIG_DEBUG_UART_CLOCK: Input clock for UART + */ +void debug_uart_init(void); + +/** + * printch() - Output a character to the debug UART + * + * @ch: Character to output + */ +asmlinkage void printch(int ch); + +/** + * printascii() - Output an ASCII string to the debug UART + * + * @str: String to output + */ +asmlinkage void printascii(const char *str); + +/** + * printhex2() - Output a 2-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex2(uint value); + +/** + * printhex4() - Output a 4-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex4(uint value); + +/** + * printhex8() - Output a 8-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex8(uint value); + +/* + * Now define some functions - this should be inserted into the serial driver + */ +#define DEBUG_UART_FUNCS \ + asmlinkage void printch(int ch) \ + { \ + _debug_uart_putc(ch); \ + } \ +\ + asmlinkage void printascii(const char *str) \ + { \ + while (*str) \ + _debug_uart_putc(*str++); \ + } \ +\ + static inline void printhex1(uint digit) \ + { \ + digit &= 0xf; \ + _debug_uart_putc(digit > 9 ? digit - 10 + 'a' : digit + '0'); \ + } \ +\ + static inline void printhex(uint value, int digits) \ + { \ + while (digits-- > 0) \ + printhex1(value >> (4 * digits)); \ + } \ +\ + asmlinkage void printhex2(uint value) \ + { \ + printhex(value, 2); \ + } \ +\ + asmlinkage void printhex4(uint value) \ + { \ + printhex(value, 4); \ + } \ +\ + asmlinkage void printhex8(uint value) \ + { \ + printhex(value, 8); \ + } + +#endif diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index f0cc794..e2418fe 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -101,7 +101,11 @@ static inline int device_remove(struct udevice *dev) { return 0; } * @dev: Pointer to device to unbind * @return 0 if OK, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int device_unbind(struct udevice *dev); +#else +static inline int device_unbind(struct udevice *dev) { return 0; } +#endif #ifdef CONFIG_DM_DEVICE_REMOVE void device_free(struct udevice *dev); |