summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/am33xx/board.c61
-rw-r--r--arch/arm/cpu/armv7/omap3/board.c26
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile1
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c15
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile1
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c15
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile1
-rw-r--r--arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c15
-rw-r--r--arch/arm/dts/am335x-bone-common.dtsi4
-rw-r--r--arch/arm/dts/dt-bindings/gpio/gpio.h15
-rw-r--r--arch/arm/include/asm/arch-uniphier/platdevice.h24
-rw-r--r--arch/arm/include/asm/omap_gpio.h19
-rw-r--r--arch/x86/cpu/start.S13
-rw-r--r--arch/x86/dts/coreboot.dtsi9
-rw-r--r--arch/x86/dts/link.dts18
-rw-r--r--arch/x86/include/asm/arch-coreboot/gpio.h15
-rw-r--r--arch/x86/include/asm/gpio.h1
-rw-r--r--arch/x86/include/asm/ibmpc.h10
-rw-r--r--arch/x86/lib/zimage.c1
-rw-r--r--board/compulab/cm_fx6/cm_fx6.c2
-rw-r--r--board/isee/igep00x0/igep00x0.c13
-rw-r--r--board/logicpd/zoom1/zoom1.c13
-rw-r--r--board/overo/overo.c13
-rw-r--r--board/ti/beagle/beagle.c47
-rw-r--r--board/ti/beagle/led.c61
-rw-r--r--common/cmd_gpio.c57
-rw-r--r--configs/am335x_boneblack_defconfig2
-rw-r--r--configs/am335x_boneblack_vboot_defconfig2
-rw-r--r--configs/ph1_ld4_defconfig3
-rw-r--r--configs/ph1_pro4_defconfig3
-rw-r--r--configs/ph1_sld8_defconfig3
-rw-r--r--doc/driver-model/README.txt29
-rw-r--r--drivers/core/Kconfig6
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/bcm2835_gpio.c89
-rw-r--r--drivers/gpio/gpio-uclass.c236
-rw-r--r--drivers/gpio/intel_ich6_gpio.c250
-rw-r--r--drivers/gpio/mxc_gpio.c116
-rw-r--r--drivers/gpio/omap_gpio.c183
-rw-r--r--drivers/gpio/s5p_gpio.c101
-rw-r--r--drivers/gpio/sandbox.c93
-rw-r--r--drivers/gpio/tegra_gpio.c113
-rw-r--r--drivers/mmc/omap_hsmmc.c15
-rw-r--r--drivers/serial/Kconfig12
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/ns16550.c17
-rw-r--r--drivers/serial/serial-uclass.c99
-rw-r--r--drivers/serial/serial.c2
-rw-r--r--drivers/serial/serial_coreboot.c38
-rw-r--r--drivers/serial/serial_mxc.c2
-rw-r--r--drivers/serial/serial_ns16550.c21
-rw-r--r--drivers/serial/serial_omap.c47
-rw-r--r--drivers/serial/serial_pl01x.c2
-rw-r--r--drivers/serial/serial_s3c24x0.c10
-rw-r--r--drivers/serial/serial_uniphier.c199
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--include/asm-generic/gpio.h70
-rw-r--r--include/common.h7
-rw-r--r--include/configs/coreboot.h22
-rw-r--r--include/configs/ph1_ld4.h6
-rw-r--r--include/configs/ph1_pro4.h6
-rw-r--r--include/configs/ph1_sld8.h6
-rw-r--r--include/configs/ti_am335x_common.h11
-rw-r--r--include/configs/ti_omap3_common.h19
-rw-r--r--include/configs/uniphier-common.h7
-rw-r--r--include/dm/platform_data/serial-uniphier.h18
-rw-r--r--include/dm/platform_data/serial_mxc.h (renamed from include/serial_mxc.h)0
-rw-r--r--include/dm/platform_data/serial_pl01x.h (renamed from include/serial_pl01x.h)0
-rw-r--r--include/dm/test.h23
-rw-r--r--include/dt-bindings/pinctrl/am33xx.h (renamed from arch/arm/dts/dt-bindings/pinctrl/am33xx.h)0
-rw-r--r--include/dt-bindings/pinctrl/omap.h (renamed from arch/arm/dts/dt-bindings/pinctrl/omap.h)0
-rw-r--r--include/ns16550.h2
-rw-r--r--test/dm/core.c46
-rw-r--r--test/dm/gpio.c111
-rw-r--r--test/dm/test-main.c2
75 files changed, 1433 insertions, 1100 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index 828d10b..29b1d73 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -9,7 +9,9 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
+#include <ns16550.h>
#include <spl.h>
#include <asm/arch/cpu.h>
#include <asm/arch/hardware.h>
@@ -36,6 +38,63 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata am33xx_gpio[] = {
+ { 0, AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
+ { 1, AM33XX_GPIO1_BASE, METHOD_GPIO_24XX },
+ { 2, AM33XX_GPIO2_BASE, METHOD_GPIO_24XX },
+ { 3, AM33XX_GPIO3_BASE, METHOD_GPIO_24XX },
+#ifdef CONFIG_AM43XX
+ { 4, AM33XX_GPIO4_BASE, METHOD_GPIO_24XX },
+ { 5, AM33XX_GPIO5_BASE, METHOD_GPIO_24XX },
+#endif
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+ { "gpio_omap", &am33xx_gpio[0] },
+ { "gpio_omap", &am33xx_gpio[1] },
+ { "gpio_omap", &am33xx_gpio[2] },
+ { "gpio_omap", &am33xx_gpio[3] },
+#ifdef CONFIG_AM43XX
+ { "gpio_omap", &am33xx_gpio[4] },
+ { "gpio_omap", &am33xx_gpio[5] },
+#endif
+};
+
+# ifndef CONFIG_OF_CONTROL
+/*
+ * TODO(sjg@chromium.org): When we can move SPL serial to DM, we can remove
+ * the CONFIGs. At the same time, we should move this to the board files.
+ */
+static const struct ns16550_platdata am33xx_serial[] = {
+ { CONFIG_SYS_NS16550_COM1, 2, CONFIG_SYS_NS16550_CLK },
+# ifdef CONFIG_SYS_NS16550_COM2
+ { CONFIG_SYS_NS16550_COM2, 2, CONFIG_SYS_NS16550_CLK },
+# ifdef CONFIG_SYS_NS16550_COM3
+ { CONFIG_SYS_NS16550_COM3, 2, CONFIG_SYS_NS16550_CLK },
+ { CONFIG_SYS_NS16550_COM4, 2, CONFIG_SYS_NS16550_CLK },
+ { CONFIG_SYS_NS16550_COM5, 2, CONFIG_SYS_NS16550_CLK },
+ { CONFIG_SYS_NS16550_COM6, 2, CONFIG_SYS_NS16550_CLK },
+# endif
+# endif
+};
+
+U_BOOT_DEVICES(am33xx_uarts) = {
+ { "serial_omap", &am33xx_serial[0] },
+# ifdef CONFIG_SYS_NS16550_COM2
+ { "serial_omap", &am33xx_serial[1] },
+# ifdef CONFIG_SYS_NS16550_COM3
+ { "serial_omap", &am33xx_serial[2] },
+ { "serial_omap", &am33xx_serial[3] },
+ { "serial_omap", &am33xx_serial[4] },
+ { "serial_omap", &am33xx_serial[5] },
+# endif
+# endif
+};
+# endif
+
+#else
+
static const struct gpio_bank gpio_bank_am33xx[] = {
{ (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
{ (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX },
@@ -49,6 +108,8 @@ static const struct gpio_bank gpio_bank_am33xx[] = {
const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
+#endif
+
#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
int cpu_mmc_init(bd_t *bis)
{
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index a1c5b09..c942fe6 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -17,6 +17,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
#include <mmc.h>
#include <spl.h>
#include <asm/io.h>
@@ -24,7 +25,7 @@
#include <asm/arch/mem.h>
#include <asm/cache.h>
#include <asm/armv7.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
#include <asm/omap_common.h>
#include <asm/arch/mmc_host_def.h>
#include <i2c.h>
@@ -39,6 +40,27 @@ static void omap3_setup_aux_cr(void);
static void omap3_invalidate_l2_cache_secure(void);
#endif
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata omap34xx_gpio[] = {
+ { 0, OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
+ { 1, OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
+ { 2, OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX },
+ { 3, OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX },
+ { 4, OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX },
+ { 5, OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX },
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+ { "gpio_omap", &omap34xx_gpio[0] },
+ { "gpio_omap", &omap34xx_gpio[1] },
+ { "gpio_omap", &omap34xx_gpio[2] },
+ { "gpio_omap", &omap34xx_gpio[3] },
+ { "gpio_omap", &omap34xx_gpio[4] },
+ { "gpio_omap", &omap34xx_gpio[5] },
+};
+
+#else
+
static const struct gpio_bank gpio_bank_34xx[6] = {
{ (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
{ (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
@@ -50,6 +72,8 @@ static const struct gpio_bank gpio_bank_34xx[6] = {
const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
+#endif
+
#ifdef CONFIG_SPL_BUILD
/*
* We use static variables because global data is not ready yet.
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile
index b385e19..781b511 100644
--- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile
+++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile
@@ -3,6 +3,7 @@
#
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
obj-y += boot-mode.o
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \
sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c
new file mode 100644
index 0000000..0047223
--- /dev/null
+++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK 36864000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile
index 712afd1..e11f4f6 100644
--- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile
+++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile
@@ -3,6 +3,7 @@
#
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
obj-y += boot-mode.o
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \
sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c
new file mode 100644
index 0000000..6da921e
--- /dev/null
+++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK 73728000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile
index b385e19..781b511 100644
--- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile
+++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile
@@ -3,6 +3,7 @@
#
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
obj-y += boot-mode.o
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \
sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c
new file mode 100644
index 0000000..59d054a
--- /dev/null
+++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK 80000000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
diff --git a/arch/arm/dts/am335x-bone-common.dtsi b/arch/arm/dts/am335x-bone-common.dtsi
index 2f66ded..e70b4d1 100644
--- a/arch/arm/dts/am335x-bone-common.dtsi
+++ b/arch/arm/dts/am335x-bone-common.dtsi
@@ -10,6 +10,10 @@
model = "TI AM335x BeagleBone";
compatible = "ti,am335x-bone", "ti,am33xx";
+ chosen {
+ stdout-path = &uart0;
+ };
+
cpus {
cpu@0 {
cpu0-supply = <&dcdc2_reg>;
diff --git a/arch/arm/dts/dt-bindings/gpio/gpio.h b/arch/arm/dts/dt-bindings/gpio/gpio.h
deleted file mode 100644
index e6b1e0a..0000000
--- a/arch/arm/dts/dt-bindings/gpio/gpio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This header provides constants for most GPIO bindings.
- *
- * Most GPIO bindings include a flags cell as part of the GPIO specifier.
- * In most cases, the format of the flags cell uses the standard values
- * defined in this header.
- */
-
-#ifndef _DT_BINDINGS_GPIO_GPIO_H
-#define _DT_BINDINGS_GPIO_GPIO_H
-
-#define GPIO_ACTIVE_HIGH 0
-#define GPIO_ACTIVE_LOW 1
-
-#endif
diff --git a/arch/arm/include/asm/arch-uniphier/platdevice.h b/arch/arm/include/asm/arch-uniphier/platdevice.h
new file mode 100644
index 0000000..cdf7d13
--- /dev/null
+++ b/arch/arm/include/asm/arch-uniphier/platdevice.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef ARCH_PLATDEVICE_H
+#define ARCH_PLATDEVICE_H
+
+#include <dm/platdata.h>
+#include <dm/platform_data/serial-uniphier.h>
+
+#define SERIAL_DEVICE(n, ba, clk) \
+static struct uniphier_serial_platform_data serial_device##n = { \
+ .base = ba, \
+ .uartclk = clk \
+}; \
+U_BOOT_DEVICE(serial##n) = { \
+ .name = DRIVER_NAME, \
+ .platdata = &serial_device##n \
+};
+
+#endif /* ARCH_PLATDEVICE_H */
diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h
index 5d25d04..839af54 100644
--- a/arch/arm/include/asm/omap_gpio.h
+++ b/arch/arm/include/asm/omap_gpio.h
@@ -23,6 +23,21 @@
#include <asm/arch/cpu.h>
+enum gpio_method {
+ METHOD_GPIO_24XX = 4,
+};
+
+#ifdef CONFIG_DM_GPIO
+
+/* Information about a GPIO bank */
+struct omap_gpio_platdata {
+ int bank_index;
+ ulong base; /* address of registers in physical memory */
+ enum gpio_method method;
+};
+
+#else
+
struct gpio_bank {
void *base;
int method;
@@ -30,8 +45,6 @@ struct gpio_bank {
extern const struct gpio_bank *const omap_gpio_bank;
-#define METHOD_GPIO_24XX 4
-
/**
* Check if gpio is valid.
*
@@ -39,4 +52,6 @@ extern const struct gpio_bank *const omap_gpio_bank;
* @return 1 if ok, 0 on error
*/
int gpio_is_valid(int gpio);
+#endif
+
#endif /* _GPIO_H_ */
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index 329bb3a..338bab1 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -85,12 +85,25 @@ car_init_ret:
/* Align global data to 16-byte boundary */
andl $0xfffffff0, %esp
+ /* Zero the global data since it won't happen later */
+ xorl %eax, %eax
+ movl $GENERATED_GBL_DATA_SIZE, %ecx
+ movl %esp, %edi
+ rep stosb
+
/* Setup first parameter to setup_gdt */
movl %esp, %eax
/* Reserve space for global descriptor table */
subl $X86_GDT_SIZE, %esp
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
+ subl $CONFIG_SYS_MALLOC_F_LEN, %esp
+ movl %eax, %edx
+ addl $GD_MALLOC_BASE, %edx
+ movl %esp, (%edx)
+#endif
+
/* Align temporary global descriptor table to 16-byte boundary */
andl $0xfffffff0, %esp
diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi
index 4862a59..c8dc4ce 100644
--- a/arch/x86/dts/coreboot.dtsi
+++ b/arch/x86/dts/coreboot.dtsi
@@ -1,13 +1,14 @@
/include/ "skeleton.dtsi"
/ {
- aliases {
- console = "/serial";
+ chosen {
+ stdout-path = "/serial";
};
serial {
- compatible = "ns16550";
- reg-shift = <1>;
+ compatible = "coreboot-uart";
+ reg = <0x3f8 0x10>;
+ reg-shift = <0>;
io-mapped = <1>;
multiplier = <1>;
baudrate = <115200>;
diff --git a/arch/x86/dts/link.dts b/arch/x86/dts/link.dts
index 67ce52a..f2fcb39 100644
--- a/arch/x86/dts/link.dts
+++ b/arch/x86/dts/link.dts
@@ -12,7 +12,23 @@
silent_console = <0>;
};
- gpio: gpio {};
+ gpioa {
+ compatible = "intel,ich6-gpio";
+ reg = <0 0x10>;
+ bank-name = "A";
+ };
+
+ gpiob {
+ compatible = "intel,ich6-gpio";
+ reg = <0x30 0x10>;
+ bank-name = "B";
+ };
+
+ gpioc {
+ compatible = "intel,ich6-gpio";
+ reg = <0x40 0x10>;
+ bank-name = "C";
+ };
serial {
reg = <0x3f8 8>;
diff --git a/arch/x86/include/asm/arch-coreboot/gpio.h b/arch/x86/include/asm/arch-coreboot/gpio.h
new file mode 100644
index 0000000..3ec1816
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/gpio.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014, Google Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+struct ich6_bank_platdata {
+ uint32_t base_addr;
+ const char *bank_name;
+};
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index fe09f31..8bda414 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -6,6 +6,7 @@
#ifndef _X86_GPIO_H_
#define _X86_GPIO_H_
+#include <asm/arch/gpio.h>
#include <asm-generic/gpio.h>
#endif /* _X86_GPIO_H_ */
diff --git a/arch/x86/include/asm/ibmpc.h b/arch/x86/include/asm/ibmpc.h
index 0f9665f..e6d183b 100644
--- a/arch/x86/include/asm/ibmpc.h
+++ b/arch/x86/include/asm/ibmpc.h
@@ -18,14 +18,4 @@
#define SYSCTLA 0x92
#define SLAVE_PIC 0xa0
-#if 1
-#define UART0_BASE 0x3f8
-#define UART1_BASE 0x2f8
-#else
-/* FixMe: uarts swapped */
-#define UART0_BASE 0x2f8
-#define UART1_BASE 0x3f8
-#endif
-
-
#endif
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2f0e92f..b190283 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -282,7 +282,6 @@ void boot_zimage(void *setup_base, void *load_address)
:: [kernel_entry]"a"(load_address),
[boot_params] "S"(setup_base),
"b"(0), "D"(0)
- : "%ebp"
);
}
diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c
index f77ff48..82681b1 100644
--- a/board/compulab/cm_fx6/cm_fx6.c
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -15,7 +15,6 @@
#include <netdev.h>
#include <fdt_support.h>
#include <sata.h>
-#include <serial_mxc.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/iomux.h>
@@ -23,6 +22,7 @@
#include <asm/imx-common/sata.h>
#include <asm/io.h>
#include <asm/gpio.h>
+#include <dm/platform_data/serial_mxc.h>
#include "common.h"
#include "../common/eeprom.h"
diff --git a/board/isee/igep00x0/igep00x0.c b/board/isee/igep00x0/igep00x0.c
index 3b2b1f1..7b87cc2 100644
--- a/board/isee/igep00x0/igep00x0.c
+++ b/board/isee/igep00x0/igep00x0.c
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
#include <twl4030.h>
#include <netdev.h>
#include <asm/gpio.h>
@@ -30,6 +32,17 @@ static const u32 gpmc_lan_config[] = {
};
#endif
+static const struct ns16550_platdata igep_serial = {
+ OMAP34XX_UART3,
+ 2,
+ V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(igep_uart) = {
+ "serial_omap",
+ &igep_serial
+};
+
/*
* Routine: board_init
* Description: Early hardware init.
diff --git a/board/logicpd/zoom1/zoom1.c b/board/logicpd/zoom1/zoom1.c
index 461a852..9ef0026 100644
--- a/board/logicpd/zoom1/zoom1.c
+++ b/board/logicpd/zoom1/zoom1.c
@@ -15,6 +15,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
#include <netdev.h>
#include <twl4030.h>
#include <asm/io.h>
@@ -41,6 +43,17 @@ static const u32 gpmc_lab_enet[] = {
/*CONF7- computed as params */
};
+static const struct ns16550_platdata zoom1_serial = {
+ OMAP34XX_UART3,
+ 2,
+ V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(zoom1_uart) = {
+ "serial_omap",
+ &zoom1_serial
+};
+
/*
* Routine: board_init
* Description: Early hardware init.
diff --git a/board/overo/overo.c b/board/overo/overo.c
index 13220c5..7506820 100644
--- a/board/overo/overo.c
+++ b/board/overo/overo.c
@@ -13,6 +13,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
#include <netdev.h>
#include <twl4030.h>
#include <linux/mtd/nand.h>
@@ -73,6 +75,17 @@ static const u32 gpmc_lan_config[] = {
/*CONFIG7- computed as params */
};
+static const struct ns16550_platdata overo_serial = {
+ OMAP34XX_UART3,
+ 2,
+ V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(overo_uart) = {
+ "serial_omap",
+ &overo_serial
+};
+
/*
* Routine: board_init
* Description: Early hardware init.
diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c
index 94b99bf..4c5e381 100644
--- a/board/ti/beagle/beagle.c
+++ b/board/ti/beagle/beagle.c
@@ -14,6 +14,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
@@ -70,6 +72,17 @@ static struct {
char env_setting[64];
} expansion_config;
+static const struct ns16550_platdata beagle_serial = {
+ OMAP34XX_UART3,
+ 2,
+ V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(beagle_uart) = {
+ "serial_omap",
+ &beagle_serial
+};
+
/*
* Routine: board_init
* Description: Early hardware init.
@@ -103,22 +116,22 @@ int board_init(void)
*/
static int get_board_revision(void)
{
- int revision;
-
- if (!gpio_request(171, "") &&
- !gpio_request(172, "") &&
- !gpio_request(173, "")) {
-
- gpio_direction_input(171);
- gpio_direction_input(172);
- gpio_direction_input(173);
-
- revision = gpio_get_value(173) << 2 |
- gpio_get_value(172) << 1 |
- gpio_get_value(171);
- } else {
- printf("Error: unable to acquire board revision GPIOs\n");
- revision = -1;
+ static int revision = -1;
+
+ if (revision == -1) {
+ if (!gpio_request(171, "rev0") &&
+ !gpio_request(172, "rev1") &&
+ !gpio_request(173, "rev2")) {
+ gpio_direction_input(171);
+ gpio_direction_input(172);
+ gpio_direction_input(173);
+
+ revision = gpio_get_value(173) << 2 |
+ gpio_get_value(172) << 1 |
+ gpio_get_value(171);
+ } else {
+ printf("Error: unable to acquire board revision GPIOs\n");
+ }
}
return revision;
@@ -258,7 +271,7 @@ static void beagle_dvi_pup(void)
case REVISION_AXBX:
case REVISION_CX:
case REVISION_C4:
- gpio_request(170, "");
+ gpio_request(170, "dvi");
gpio_direction_output(170, 0);
gpio_set_value(170, 1);
break;
diff --git a/board/ti/beagle/led.c b/board/ti/beagle/led.c
index 89b8dd3..a913a4c 100644
--- a/board/ti/beagle/led.c
+++ b/board/ti/beagle/led.c
@@ -27,47 +27,46 @@ void green_led_on(void)
}
#endif
+static int get_led_gpio(led_id_t mask)
+{
+#ifdef STATUS_LED_BIT
+ if (STATUS_LED_BIT & mask)
+ return BEAGLE_LED_USR0;
+#endif
+#ifdef STATUS_LED_BIT1
+ if (STATUS_LED_BIT1 & mask)
+ return BEAGLE_LED_USR1;
+#endif
+
+ return 0;
+}
+
void __led_init (led_id_t mask, int state)
{
- __led_set (mask, state);
+ int toggle_gpio;
+
+ toggle_gpio = get_led_gpio(mask);
+
+ if (toggle_gpio && !gpio_request(toggle_gpio, "led"))
+ __led_set(mask, state);
}
void __led_toggle (led_id_t mask)
{
- int state, toggle_gpio = 0;
-#ifdef STATUS_LED_BIT
- if (!toggle_gpio && STATUS_LED_BIT & mask)
- toggle_gpio = BEAGLE_LED_USR0;
-#endif
-#ifdef STATUS_LED_BIT1
- if (!toggle_gpio && STATUS_LED_BIT1 & mask)
- toggle_gpio = BEAGLE_LED_USR1;
-#endif
+ int state, toggle_gpio;
+
+ toggle_gpio = get_led_gpio(mask);
if (toggle_gpio) {
- if (!gpio_request(toggle_gpio, "")) {
- gpio_direction_output(toggle_gpio, 0);
- state = gpio_get_value(toggle_gpio);
- gpio_set_value(toggle_gpio, !state);
- }
+ state = gpio_get_value(toggle_gpio);
+ gpio_direction_output(toggle_gpio, !state);
}
}
void __led_set (led_id_t mask, int state)
{
-#ifdef STATUS_LED_BIT
- if (STATUS_LED_BIT & mask) {
- if (!gpio_request(BEAGLE_LED_USR0, "")) {
- gpio_direction_output(BEAGLE_LED_USR0, 0);
- gpio_set_value(BEAGLE_LED_USR0, state);
- }
- }
-#endif
-#ifdef STATUS_LED_BIT1
- if (STATUS_LED_BIT1 & mask) {
- if (!gpio_request(BEAGLE_LED_USR1, "")) {
- gpio_direction_output(BEAGLE_LED_USR1, 0);
- gpio_set_value(BEAGLE_LED_USR1, state);
- }
- }
-#endif
+ int toggle_gpio;
+
+ toggle_gpio = get_led_gpio(mask);
+ if (toggle_gpio)
+ gpio_direction_output(toggle_gpio, state);
}
diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c
index 8d946f4..65d6df4 100644
--- a/common/cmd_gpio.c
+++ b/common/cmd_gpio.c
@@ -25,13 +25,6 @@ enum gpio_cmd {
};
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
-static const char * const gpio_function[GPIOF_COUNT] = {
- "input",
- "output",
- "unused",
- "unknown",
- "func",
-};
/* A few flags used by show_gpio() */
enum {
@@ -40,22 +33,16 @@ enum {
FLAG_SHOW_NEWLINE = 1 << 2,
};
-static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
- int *flagsp)
+static void gpio_get_description(struct udevice *dev, const char *bank_name,
+ int offset, int *flagsp)
{
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
- int func = GPIOF_UNKNOWN;
char buf[80];
int ret;
- BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
-
- if (ops->get_function) {
- ret = ops->get_function(dev, offset);
- if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
- func = ret;
- }
- if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
+ ret = gpio_get_function(dev, offset, NULL);
+ if (ret < 0)
+ goto err;
+ if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
return;
if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
if (*flagsp & FLAG_SHOW_NEWLINE) {
@@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
printf("Bank %s:\n", bank_name);
*flagsp &= ~FLAG_SHOW_BANK;
}
- *buf = '\0';
- if (ops->get_state) {
- ret = ops->get_state(dev, offset, buf, sizeof(buf));
- if (ret) {
- puts("<unknown>");
- return;
- }
- } else {
- sprintf(buf, "%s%u: %8s %d", bank_name, offset,
- gpio_function[func], ops->get_value(dev, offset));
- }
- puts(buf);
- puts("\n");
+ ret = gpio_get_status(dev, offset, buf, sizeof(buf));
+ if (ret)
+ goto err;
+
+ printf("%s\n", buf);
+ return;
+err:
+ printf("Error %d\n", ret);
}
static int do_gpio_status(bool all, const char *gpio_name)
@@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name)
if (all)
flags |= FLAG_SHOW_ALL;
bank_name = gpio_get_bank_info(dev, &num_bits);
- if (!num_bits)
+ if (!num_bits) {
+ debug("GPIO device %s has no bits\n", dev->name);
continue;
+ }
banklen = bank_name ? strlen(bank_name) : 0;
if (!gpio_name || !bank_name ||
@@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name)
p = gpio_name + banklen;
if (gpio_name && *p) {
offset = simple_strtoul(p, NULL, 10);
- show_gpio(dev, bank_name, offset, &flags);
+ gpio_get_description(dev, bank_name, offset,
+ &flags);
} else {
for (offset = 0; offset < num_bits; offset++) {
- show_gpio(dev, bank_name, offset,
- &flags);
+ gpio_get_description(dev, bank_name,
+ offset, &flags);
}
}
}
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index 38450c0..b631c41 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -1,4 +1,4 @@
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT"
+CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_AM335X_EVM=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index e257143..5837a0a 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -1,5 +1,5 @@
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT,ENABLE_VBOOT"
+CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_AM335X_EVM=y
CONFIG_OF_CONTROL=y
diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig
index 53f3126..e6aba42 100644
--- a/configs/ph1_ld4_defconfig
+++ b/configs/ph1_ld4_defconfig
@@ -2,7 +2,10 @@ CONFIG_SPL=y
+S:CONFIG_ARM=y
+S:CONFIG_ARCH_UNIPHIER=y
+S:CONFIG_MACH_PH1_LD4=y
+CONFIG_DM=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
S:CONFIG_SPL_NAND_DENALI=y
diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig
index 209466e..334ec4b 100644
--- a/configs/ph1_pro4_defconfig
+++ b/configs/ph1_pro4_defconfig
@@ -2,7 +2,10 @@ CONFIG_SPL=y
+S:CONFIG_ARM=y
+S:CONFIG_ARCH_UNIPHIER=y
+S:CONFIG_MACH_PH1_PRO4=y
+CONFIG_DM=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
S:CONFIG_SPL_NAND_DENALI=y
diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig
index 658977b..4e8f354 100644
--- a/configs/ph1_sld8_defconfig
+++ b/configs/ph1_sld8_defconfig
@@ -2,7 +2,10 @@ CONFIG_SPL=y
+S:CONFIG_ARM=y
+S:CONFIG_ARCH_UNIPHIER=y
+S:CONFIG_MACH_PH1_SLD8=y
+CONFIG_DM=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
S:CONFIG_SPL_NAND_DENALI=y
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index 8dfcf75..0278dda 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -95,7 +95,7 @@ are provided in test/dm. To run them, try:
You should see something like this:
<...U-Boot banner...>
- Running 22 driver model tests
+ Running 29 driver model tests
Test: dm_test_autobind
Test: dm_test_autoprobe
Test: dm_test_bus_children
@@ -115,7 +115,12 @@ You should see something like this:
Device 'd-test': seq 3 is in use by 'b-test'
Device 'a-test': seq 0 is in use by 'd-test'
Test: dm_test_gpio
- sandbox_gpio: sb_gpio_get_value: error: offset 4 not reserved
+ extra-gpios: get_value: error: gpio b5 not reserved
+ Test: dm_test_gpio_anon
+ Test: dm_test_gpio_copy
+ Test: dm_test_gpio_leak
+ extra-gpios: get_value: error: gpio b5 not reserved
+ Test: dm_test_gpio_requestf
Test: dm_test_leak
Test: dm_test_lifecycle
Test: dm_test_operations
@@ -123,6 +128,26 @@ You should see something like this:
Test: dm_test_platdata
Test: dm_test_pre_reloc
Test: dm_test_remove
+ Test: dm_test_spi_find
+ Invalid chip select 0:0 (err=-19)
+ SF: Failed to get idcodes
+ Device 'name-emul': seq 0 is in use by 'name-emul'
+ SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+ Test: dm_test_spi_flash
+ 2097152 bytes written in 0 ms
+ SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+ SPI flash test:
+ 0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ Test passed
+ 0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ 3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+ Test: dm_test_spi_xfer
+ SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
Test: dm_test_uclass
Test: dm_test_uclass_before_ready
Failures: 0
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index e69de29..d2799dc 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -0,0 +1,6 @@
+config DM
+ bool "Enable Driver Model"
+ depends on !SPL_BUILD
+ help
+ This config option enables Driver Model.
+ To use legacy drivers, say N.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e69de29..d21302f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -0,0 +1,6 @@
+config DM_GPIO
+ bool "Enable Driver Model for GPIO drivers"
+ depends on DM
+ help
+ If you want to use driver model for GPIO drivers, say Y.
+ To use legacy GPIO drivers, say N.
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
index 332cfc2..0244c01 100644
--- a/drivers/gpio/bcm2835_gpio.c
+++ b/drivers/gpio/bcm2835_gpio.c
@@ -11,67 +11,10 @@
#include <asm/gpio.h>
#include <asm/io.h>
-#define GPIO_NAME_SIZE 20
-
struct bcm2835_gpios {
- char label[BCM2835_GPIO_COUNT][GPIO_NAME_SIZE];
struct bcm2835_gpio_regs *reg;
};
-/**
- * gpio_is_requested() - check if a GPIO has been requested
- *
- * @bank: Bank to check
- * @offset: GPIO offset within bank to check
- * @return true if marked as requested, false if not
- */
-static inline bool gpio_is_requested(struct bcm2835_gpios *gpios, int offset)
-{
- return *gpios->label[offset] != '\0';
-}
-
-static int check_requested(struct udevice *dev, unsigned offset,
- const char *func)
-{
- struct bcm2835_gpios *gpios = dev_get_priv(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
- if (!gpio_is_requested(gpios, offset)) {
- printf("omap_gpio: %s: error: gpio %s%d not requested\n",
- func, uc_priv->bank_name, offset);
- return -EPERM;
- }
-
- return 0;
-}
-
-static int bcm2835_gpio_request(struct udevice *dev, unsigned offset,
- const char *label)
-{
- struct bcm2835_gpios *gpios = dev_get_priv(dev);
-
- if (gpio_is_requested(gpios, offset))
- return -EBUSY;
-
- strncpy(gpios->label[offset], label, GPIO_NAME_SIZE);
- gpios->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
- return 0;
-}
-
-static int bcm2835_gpio_free(struct udevice *dev, unsigned offset)
-{
- struct bcm2835_gpios *gpios = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
- gpios->label[offset][0] = '\0';
-
- return 0;
-}
-
static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio)
{
struct bcm2835_gpios *gpios = dev_get_priv(dev);
@@ -142,9 +85,6 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
{
struct bcm2835_gpios *gpios = dev_get_priv(dev);
- if (!gpio_is_requested(gpios, offset))
- return GPIOF_UNUSED;
-
/* GPIOF_FUNC is not implemented yet */
if (bcm2835_gpio_is_output(gpios, offset))
return GPIOF_OUTPUT;
@@ -152,42 +92,13 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
-static int bcm2835_gpio_get_state(struct udevice *dev, unsigned int offset,
- char *buf, int bufsize)
-{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct bcm2835_gpios *gpios = dev_get_priv(dev);
- const char *label;
- bool requested;
- bool is_output;
- int size;
-
- label = gpios->label[offset];
- is_output = bcm2835_gpio_is_output(gpios, offset);
- size = snprintf(buf, bufsize, "%s%d: ",
- uc_priv->bank_name ? uc_priv->bank_name : "", offset);
- buf += size;
- bufsize -= size;
- requested = gpio_is_requested(gpios, offset);
- snprintf(buf, bufsize, "%s: %d [%c]%s%s",
- is_output ? "out" : " in",
- bcm2835_get_value(gpios, offset),
- requested ? 'x' : ' ',
- requested ? " " : "",
- label);
-
- return 0;
-}
static const struct dm_gpio_ops gpio_bcm2835_ops = {
- .request = bcm2835_gpio_request,
- .free = bcm2835_gpio_free,
.direction_input = bcm2835_gpio_direction_input,
.direction_output = bcm2835_gpio_direction_output,
.get_value = bcm2835_gpio_get_value,
.set_value = bcm2835_gpio_set_value,
.get_function = bcm2835_gpio_get_function,
- .get_state = bcm2835_gpio_get_state,
};
static int bcm2835_gpio_probe(struct udevice *dev)
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index f1bbc58..45e9a5a 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -7,7 +7,9 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
+#include <malloc.h>
#include <asm/gpio.h>
+#include <linux/ctype.h>
/**
* gpio_to_device() - Convert global GPIO number to device, number
@@ -43,35 +45,47 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp,
int gpio_lookup_name(const char *name, struct udevice **devp,
unsigned int *offsetp, unsigned int *gpiop)
{
- struct gpio_dev_priv *uc_priv;
+ struct gpio_dev_priv *uc_priv = NULL;
struct udevice *dev;
+ ulong offset;
+ int numeric;
int ret;
if (devp)
*devp = NULL;
+ numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
dev;
ret = uclass_next_device(&dev)) {
- ulong offset;
int len;
uc_priv = dev->uclass_priv;
+ if (numeric != -1) {
+ offset = numeric - uc_priv->gpio_base;
+ /* Allow GPIOs to be numbered from 0 */
+ if (offset >= 0 && offset < uc_priv->gpio_count)
+ break;
+ }
+
len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
if (!strncasecmp(name, uc_priv->bank_name, len)) {
- if (strict_strtoul(name + len, 10, &offset))
- continue;
- if (devp)
- *devp = dev;
- if (offsetp)
- *offsetp = offset;
- if (gpiop)
- *gpiop = uc_priv->gpio_base + offset;
- return 0;
+ if (!strict_strtoul(name + len, 10, &offset))
+ break;
}
}
- return ret ? ret : -EINVAL;
+ if (!dev)
+ return ret ? ret : -EINVAL;
+
+ if (devp)
+ *devp = dev;
+ if (offsetp)
+ *offsetp = offset;
+ if (gpiop)
+ *gpiop = uc_priv->gpio_base + offset;
+
+ return 0;
}
/**
@@ -79,24 +93,62 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
* gpio: GPIO number
* label: Name for the requested GPIO
*
+ * The label is copied and allocated so the caller does not need to keep
+ * the pointer around.
+ *
* This function implements the API that's compatible with current
* GPIO API used in U-Boot. The request is forwarded to particular
* GPIO driver. Returns 0 on success, negative value on error.
*/
int gpio_request(unsigned gpio, const char *label)
{
+ struct gpio_dev_priv *uc_priv;
unsigned int offset;
struct udevice *dev;
+ char *str;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
if (ret)
return ret;
- if (!gpio_get_ops(dev)->request)
- return 0;
+ uc_priv = dev->uclass_priv;
+ if (uc_priv->name[offset])
+ return -EBUSY;
+ str = strdup(label);
+ if (!str)
+ return -ENOMEM;
+ if (gpio_get_ops(dev)->request) {
+ ret = gpio_get_ops(dev)->request(dev, offset, label);
+ if (ret) {
+ free(str);
+ return ret;
+ }
+ }
+ uc_priv->name[offset] = str;
+
+ return 0;
+}
+
+/**
+ * gpio_requestf() - [COMPAT] Request GPIO
+ * @gpio: GPIO number
+ * @fmt: Format string for the requested GPIO
+ * @...: Arguments for the printf() format string
+ *
+ * This function implements the API that's compatible with current
+ * GPIO API used in U-Boot. The request is forwarded to particular
+ * GPIO driver. Returns 0 on success, negative value on error.
+ */
+int gpio_requestf(unsigned gpio, const char *fmt, ...)
+{
+ va_list args;
+ char buf[40];
- return gpio_get_ops(dev)->request(dev, offset, label);
+ va_start(args, fmt);
+ vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ return gpio_request(gpio, buf);
}
/**
@@ -109,6 +161,7 @@ int gpio_request(unsigned gpio, const char *label)
*/
int gpio_free(unsigned gpio)
{
+ struct gpio_dev_priv *uc_priv;
unsigned int offset;
struct udevice *dev;
int ret;
@@ -117,9 +170,34 @@ int gpio_free(unsigned gpio)
if (ret)
return ret;
- if (!gpio_get_ops(dev)->free)
- return 0;
- return gpio_get_ops(dev)->free(dev, offset);
+ uc_priv = dev->uclass_priv;
+ if (!uc_priv->name[offset])
+ return -ENXIO;
+ if (gpio_get_ops(dev)->free) {
+ ret = gpio_get_ops(dev)->free(dev, offset);
+ if (ret)
+ return ret;
+ }
+
+ free(uc_priv->name[offset]);
+ uc_priv->name[offset] = NULL;
+
+ return 0;
+}
+
+static int check_reserved(struct udevice *dev, unsigned offset,
+ const char *func)
+{
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+ if (!uc_priv->name[offset]) {
+ printf("%s: %s: error: gpio %s%d not reserved\n",
+ dev->name, func,
+ uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+ return -EBUSY;
+ }
+
+ return 0;
}
/**
@@ -139,8 +217,9 @@ int gpio_direction_input(unsigned gpio)
ret = gpio_to_device(gpio, &dev, &offset);
if (ret)
return ret;
+ ret = check_reserved(dev, offset, "dir_input");
- return gpio_get_ops(dev)->direction_input(dev, offset);
+ return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
}
/**
@@ -161,8 +240,10 @@ int gpio_direction_output(unsigned gpio, int value)
ret = gpio_to_device(gpio, &dev, &offset);
if (ret)
return ret;
+ ret = check_reserved(dev, offset, "dir_output");
- return gpio_get_ops(dev)->direction_output(dev, offset, value);
+ return ret ? ret :
+ gpio_get_ops(dev)->direction_output(dev, offset, value);
}
/**
@@ -183,8 +264,9 @@ int gpio_get_value(unsigned gpio)
ret = gpio_to_device(gpio, &dev, &offset);
if (ret)
return ret;
+ ret = check_reserved(dev, offset, "get_value");
- return gpio_get_ops(dev)->get_value(dev, offset);
+ return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
}
/**
@@ -205,8 +287,9 @@ int gpio_set_value(unsigned gpio, int value)
ret = gpio_to_device(gpio, &dev, &offset);
if (ret)
return ret;
+ ret = check_reserved(dev, offset, "set_value");
- return gpio_get_ops(dev)->set_value(dev, offset, value);
+ return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
}
const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
@@ -221,8 +304,94 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
return priv->bank_name;
}
+static const char * const gpio_function[GPIOF_COUNT] = {
+ "input",
+ "output",
+ "unused",
+ "unknown",
+ "func",
+};
+
+int get_function(struct udevice *dev, int offset, bool skip_unused,
+ const char **namep)
+{
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct dm_gpio_ops *ops = gpio_get_ops(dev);
+
+ BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+ if (!device_active(dev))
+ return -ENODEV;
+ if (offset < 0 || offset >= uc_priv->gpio_count)
+ return -EINVAL;
+ if (namep)
+ *namep = uc_priv->name[offset];
+ if (skip_unused && !uc_priv->name[offset])
+ return GPIOF_UNUSED;
+ if (ops->get_function) {
+ int ret;
+
+ ret = ops->get_function(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret >= ARRAY_SIZE(gpio_function))
+ return -ENODATA;
+ return ret;
+ }
+
+ return GPIOF_UNKNOWN;
+}
+
+int gpio_get_function(struct udevice *dev, int offset, const char **namep)
+{
+ return get_function(dev, offset, true, namep);
+}
+
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
+{
+ return get_function(dev, offset, false, namep);
+}
+
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
+{
+ struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ struct gpio_dev_priv *priv;
+ char *str = buf;
+ int func;
+ int ret;
+ int len;
+
+ BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+
+ *buf = 0;
+ priv = dev->uclass_priv;
+ ret = gpio_get_raw_function(dev, offset, NULL);
+ if (ret < 0)
+ return ret;
+ func = ret;
+ len = snprintf(str, buffsize, "%s%d: %s",
+ priv->bank_name ? priv->bank_name : "",
+ offset, gpio_function[func]);
+ if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
+ func == GPIOF_UNUSED) {
+ const char *label;
+ bool used;
+
+ ret = ops->get_value(dev, offset);
+ if (ret < 0)
+ return ret;
+ used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
+ snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
+ ret,
+ used ? 'x' : ' ',
+ used ? " " : "",
+ label ? label : "");
+ }
+
+ return 0;
+}
+
/* We need to renumber the GPIOs when any driver is probed/removed */
-static int gpio_renumber(void)
+static int gpio_renumber(struct udevice *removed_dev)
{
struct gpio_dev_priv *uc_priv;
struct udevice *dev;
@@ -237,7 +406,7 @@ static int gpio_renumber(void)
/* Ensure that we have a base for each bank */
base = 0;
uclass_foreach_dev(dev, uc) {
- if (device_active(dev)) {
+ if (device_active(dev) && dev != removed_dev) {
uc_priv = dev->uclass_priv;
uc_priv->gpio_base = base;
base += uc_priv->gpio_count;
@@ -249,12 +418,27 @@ static int gpio_renumber(void)
static int gpio_post_probe(struct udevice *dev)
{
- return gpio_renumber();
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+ uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
+ if (!uc_priv->name)
+ return -ENOMEM;
+
+ return gpio_renumber(NULL);
}
static int gpio_pre_remove(struct udevice *dev)
{
- return gpio_renumber();
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ int i;
+
+ for (i = 0; i < uc_priv->gpio_count; i++) {
+ if (uc_priv->name[i])
+ free(uc_priv->name[i]);
+ }
+ free(uc_priv->name);
+
+ return gpio_renumber(dev);
}
UCLASS_DRIVER(gpio) = {
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7d9fac7..d3381b0 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -27,88 +27,46 @@
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
#include <pci.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#define GPIO_PER_BANK 32
+
/* Where in config space is the register that points to the GPIO registers? */
#define PCI_CFG_GPIOBASE 0x48
-#define NUM_BANKS 3
-
-/* Within the I/O space, where are the registers to control the GPIOs? */
-static struct {
- u8 use_sel;
- u8 io_sel;
- u8 lvl;
-} gpio_bank[NUM_BANKS] = {
- { 0x00, 0x04, 0x0c }, /* Bank 0 */
- { 0x30, 0x34, 0x38 }, /* Bank 1 */
- { 0x40, 0x44, 0x48 } /* Bank 2 */
+struct ich6_bank_priv {
+ /* These are I/O addresses */
+ uint32_t use_sel;
+ uint32_t io_sel;
+ uint32_t lvl;
};
-static pci_dev_t dev; /* handle for 0:1f:0 */
-static u32 gpiobase; /* offset into I/O space */
-static int found_it_once; /* valid GPIO device? */
-static u32 lock[NUM_BANKS]; /* "lock" for access to pins */
-
-static int bad_arg(int num, int *bank, int *bitnum)
-{
- int i = num / 32;
- int j = num % 32;
-
- if (num < 0 || i > NUM_BANKS) {
- debug("%s: bogus gpio num: %d\n", __func__, num);
- return -1;
- }
- *bank = i;
- *bitnum = j;
- return 0;
-}
-
-static int mark_gpio(int bank, int bitnum)
-{
- if (lock[bank] & (1UL << bitnum)) {
- debug("%s: %d.%d already marked\n", __func__, bank, bitnum);
- return -1;
- }
- lock[bank] |= (1 << bitnum);
- return 0;
-}
-
-static void clear_gpio(int bank, int bitnum)
-{
- lock[bank] &= ~(1 << bitnum);
-}
-
-static int notmine(int num, int *bank, int *bitnum)
-{
- if (bad_arg(num, bank, bitnum))
- return -1;
- return !(lock[*bank] & (1UL << *bitnum));
-}
-
-static int gpio_init(void)
+static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
{
+ struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+ pci_dev_t pci_dev; /* handle for 0:1f:0 */
u8 tmpbyte;
u16 tmpword;
u32 tmplong;
-
- /* Have we already done this? */
- if (found_it_once)
- return 0;
+ u32 gpiobase;
+ int offset;
/* Where should it be? */
- dev = PCI_BDF(0, 0x1f, 0);
+ pci_dev = PCI_BDF(0, 0x1f, 0);
/* Is the device present? */
- pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword);
+ pci_read_config_word(pci_dev, PCI_VENDOR_ID, &tmpword);
if (tmpword != PCI_VENDOR_ID_INTEL) {
debug("%s: wrong VendorID\n", __func__);
- return -1;
+ return -ENODEV;
}
- pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword);
+ pci_read_config_word(pci_dev, PCI_DEVICE_ID, &tmpword);
debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
/*
* We'd like to validate the Device ID too, but pretty much any
@@ -118,37 +76,37 @@ static int gpio_init(void)
*/
/* I/O should already be enabled (it's a RO bit). */
- pci_read_config_word(dev, PCI_COMMAND, &tmpword);
+ pci_read_config_word(pci_dev, PCI_COMMAND, &tmpword);
if (!(tmpword & PCI_COMMAND_IO)) {
debug("%s: device IO not enabled\n", __func__);
- return -1;
+ return -ENODEV;
}
/* Header Type must be normal (bits 6-0 only; see spec.) */
- pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte);
+ pci_read_config_byte(pci_dev, PCI_HEADER_TYPE, &tmpbyte);
if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
debug("%s: invalid Header type\n", __func__);
- return -1;
+ return -ENODEV;
}
/* Base Class must be a bridge device */
- pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte);
+ pci_read_config_byte(pci_dev, PCI_CLASS_CODE, &tmpbyte);
if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
debug("%s: invalid class\n", __func__);
- return -1;
+ return -ENODEV;
}
/* Sub Class must be ISA */
- pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte);
+ pci_read_config_byte(pci_dev, PCI_CLASS_SUB_CODE, &tmpbyte);
if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
debug("%s: invalid subclass\n", __func__);
- return -1;
+ return -ENODEV;
}
/* Programming Interface must be 0x00 (no others exist) */
- pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte);
+ pci_read_config_byte(pci_dev, PCI_CLASS_PROG, &tmpbyte);
if (tmpbyte != 0x00) {
debug("%s: invalid interface type\n", __func__);
- return -1;
+ return -ENODEV;
}
/*
@@ -156,11 +114,11 @@ static int gpio_init(void)
* that it was unused (or undocumented). Check that it looks
* okay: not all ones or zeros, and mapped to I/O space (bit 0).
*/
- pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong);
+ pci_read_config_dword(pci_dev, PCI_CFG_GPIOBASE, &tmplong);
if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
!(tmplong & 0x00000001)) {
debug("%s: unexpected GPIOBASE value\n", __func__);
- return -1;
+ return -ENODEV;
}
/*
@@ -170,105 +128,137 @@ static int gpio_init(void)
* an I/O address, not a memory address, so mask that off.
*/
gpiobase = tmplong & 0xfffffffe;
+ offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+ if (offset == -1) {
+ debug("%s: Invalid register offset %d\n", __func__, offset);
+ return -EINVAL;
+ }
+ plat->base_addr = gpiobase + offset;
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "bank-name", NULL);
- /* Finally. These are the droids we're looking for. */
- found_it_once = 1;
return 0;
}
-int gpio_request(unsigned num, const char *label /* UNUSED */)
+int ich6_gpio_probe(struct udevice *dev)
{
- u32 tmplong;
- int i = 0, j = 0;
+ struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
+
+ uc_priv->gpio_count = GPIO_PER_BANK;
+ uc_priv->bank_name = plat->bank_name;
+ bank->use_sel = plat->base_addr;
+ bank->io_sel = plat->base_addr + 4;
+ bank->lvl = plat->base_addr + 8;
- /* Is the hardware ready? */
- if (gpio_init())
- return -1;
+ return 0;
+}
- if (bad_arg(num, &i, &j))
- return -1;
+int ich6_gpio_request(struct udevice *dev, unsigned offset, const char *label)
+{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
+ u32 tmplong;
/*
* Make sure that the GPIO pin we want isn't already in use for some
* built-in hardware function. We have to check this for every
* requested pin.
*/
- tmplong = inl(gpiobase + gpio_bank[i].use_sel);
- if (!(tmplong & (1UL << j))) {
+ tmplong = inl(bank->use_sel);
+ if (!(tmplong & (1UL << offset))) {
debug("%s: gpio %d is reserved for internal use\n", __func__,
- num);
- return -1;
+ offset);
+ return -EPERM;
}
- return mark_gpio(i, j);
-}
-
-int gpio_free(unsigned num)
-{
- int i = 0, j = 0;
-
- if (notmine(num, &i, &j))
- return -1;
-
- clear_gpio(i, j);
return 0;
}
-int gpio_direction_input(unsigned num)
+static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
u32 tmplong;
- int i = 0, j = 0;
-
- if (notmine(num, &i, &j))
- return -1;
- tmplong = inl(gpiobase + gpio_bank[i].io_sel);
- tmplong |= (1UL << j);
- outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+ tmplong = inl(bank->io_sel);
+ tmplong |= (1UL << offset);
+ outl(bank->io_sel, tmplong);
return 0;
}
-int gpio_direction_output(unsigned num, int value)
+static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
u32 tmplong;
- int i = 0, j = 0;
- if (notmine(num, &i, &j))
- return -1;
-
- tmplong = inl(gpiobase + gpio_bank[i].io_sel);
- tmplong &= ~(1UL << j);
- outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+ tmplong = inl(bank->io_sel);
+ tmplong &= ~(1UL << offset);
+ outl(bank->io_sel, tmplong);
return 0;
}
-int gpio_get_value(unsigned num)
+static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
+
{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
u32 tmplong;
- int i = 0, j = 0;
int r;
- if (notmine(num, &i, &j))
- return -1;
-
- tmplong = inl(gpiobase + gpio_bank[i].lvl);
- r = (tmplong & (1UL << j)) ? 1 : 0;
+ tmplong = inl(bank->lvl);
+ r = (tmplong & (1UL << offset)) ? 1 : 0;
return r;
}
-int gpio_set_value(unsigned num, int value)
+static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
+ int value)
{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
u32 tmplong;
- int i = 0, j = 0;
- if (notmine(num, &i, &j))
- return -1;
-
- tmplong = inl(gpiobase + gpio_bank[i].lvl);
+ tmplong = inl(bank->lvl);
if (value)
- tmplong |= (1UL << j);
+ tmplong |= (1UL << offset);
else
- tmplong &= ~(1UL << j);
- outl(gpiobase + gpio_bank[i].lvl, tmplong);
+ tmplong &= ~(1UL << offset);
+ outl(bank->lvl, tmplong);
return 0;
}
+
+static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+ struct ich6_bank_priv *bank = dev_get_priv(dev);
+ u32 mask = 1UL << offset;
+
+ if (!(inl(bank->use_sel) & mask))
+ return GPIOF_FUNC;
+ if (inl(bank->io_sel) & mask)
+ return GPIOF_INPUT;
+ else
+ return GPIOF_OUTPUT;
+}
+
+static const struct dm_gpio_ops gpio_ich6_ops = {
+ .request = ich6_gpio_request,
+ .direction_input = ich6_gpio_direction_input,
+ .direction_output = ich6_gpio_direction_output,
+ .get_value = ich6_gpio_get_value,
+ .set_value = ich6_gpio_set_value,
+ .get_function = ich6_gpio_get_function,
+};
+
+static const struct udevice_id intel_ich6_gpio_ids[] = {
+ { .compatible = "intel,ich6-gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(gpio_ich6) = {
+ .name = "gpio_ich6",
+ .id = UCLASS_GPIO,
+ .of_match = intel_ich6_gpio_ids,
+ .ops = &gpio_ich6_ops,
+ .ofdata_to_platdata = gpio_ich6_ofdata_to_platdata,
+ .probe = ich6_gpio_probe,
+ .priv_auto_alloc_size = sizeof(struct ich6_bank_priv),
+ .platdata_auto_alloc_size = sizeof(struct ich6_bank_platdata),
+};
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 3f7b7d2..8bb9e39 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -20,7 +20,6 @@ enum mxc_gpio_direction {
MXC_GPIO_DIRECTION_OUT,
};
-#define GPIO_NAME_SIZE 20
#define GPIO_PER_BANK 32
struct mxc_gpio_plat {
@@ -28,7 +27,6 @@ struct mxc_gpio_plat {
};
struct mxc_bank_info {
- char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
struct gpio_regs *regs;
};
@@ -152,18 +150,6 @@ int gpio_direction_output(unsigned gpio, int value)
#endif
#ifdef CONFIG_DM_GPIO
-/**
- * gpio_is_requested() - check if a GPIO has been requested
- *
- * @bank: Bank to check
- * @offset: GPIO offset within bank to check
- * @return true if marked as requested, false if not
- */
-static inline bool gpio_is_requested(struct mxc_bank_info *bank, int offset)
-{
- return *bank->label[offset] != '\0';
-}
-
static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
{
u32 val;
@@ -208,35 +194,10 @@ static int mxc_gpio_bank_get_value(struct gpio_regs *regs, int offset)
return (readl(&regs->gpio_psr) >> offset) & 0x01;
}
-static int mxc_gpio_bank_get_output_value(struct gpio_regs *regs, int offset)
-{
- return (readl(&regs->gpio_dr) >> offset) & 0x01;
-}
-
-static int check_requested(struct udevice *dev, unsigned offset,
- const char *func)
-{
- struct mxc_bank_info *bank = dev_get_priv(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
- if (!gpio_is_requested(bank, offset)) {
- printf("mxc_gpio: %s: error: gpio %s%d not requested\n",
- func, uc_priv->bank_name, offset);
- return -EPERM;
- }
-
- return 0;
-}
-
/* set GPIO pin 'gpio' as an input */
static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO direction as input. */
mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_IN);
@@ -249,11 +210,6 @@ static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO output value. */
mxc_gpio_bank_set_value(bank->regs, offset, value);
@@ -268,11 +224,6 @@ static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset,
static int mxc_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
return mxc_gpio_bank_get_value(bank->regs, offset);
}
@@ -282,80 +233,16 @@ static int mxc_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
mxc_gpio_bank_set_value(bank->regs, offset, value);
return 0;
}
-static int mxc_gpio_get_state(struct udevice *dev, unsigned int offset,
- char *buf, int bufsize)
-{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct mxc_bank_info *bank = dev_get_priv(dev);
- const char *label;
- bool requested;
- bool is_output;
- int size;
-
- label = bank->label[offset];
- is_output = mxc_gpio_is_output(bank->regs, offset);
- size = snprintf(buf, bufsize, "%s%d: ",
- uc_priv->bank_name ? uc_priv->bank_name : "", offset);
- buf += size;
- bufsize -= size;
- requested = gpio_is_requested(bank, offset);
- snprintf(buf, bufsize, "%s: %d [%c]%s%s",
- is_output ? "out" : " in",
- is_output ?
- mxc_gpio_bank_get_output_value(bank->regs, offset) :
- mxc_gpio_bank_get_value(bank->regs, offset),
- requested ? 'x' : ' ',
- requested ? " " : "",
- label);
-
- return 0;
-}
-
-static int mxc_gpio_request(struct udevice *dev, unsigned offset,
- const char *label)
-{
- struct mxc_bank_info *bank = dev_get_priv(dev);
-
- if (gpio_is_requested(bank, offset))
- return -EBUSY;
-
- strncpy(bank->label[offset], label, GPIO_NAME_SIZE);
- bank->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
- return 0;
-}
-
-static int mxc_gpio_free(struct udevice *dev, unsigned offset)
-{
- struct mxc_bank_info *bank = dev_get_priv(dev);
- int ret;
-
- ret = check_requested(dev, offset, __func__);
- if (ret)
- return ret;
- bank->label[offset][0] = '\0';
-
- return 0;
-}
-
static int mxc_gpio_get_function(struct udevice *dev, unsigned offset)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
- if (!gpio_is_requested(bank, offset))
- return GPIOF_UNUSED;
-
/* GPIOF_FUNC is not implemented yet */
if (mxc_gpio_is_output(bank->regs, offset))
return GPIOF_OUTPUT;
@@ -364,14 +251,11 @@ static int mxc_gpio_get_function(struct udevice *dev, unsigned offset)
}
static const struct dm_gpio_ops gpio_mxc_ops = {
- .request = mxc_gpio_request,
- .free = mxc_gpio_free,
.direction_input = mxc_gpio_direction_input,
.direction_output = mxc_gpio_direction_output,
.get_value = mxc_gpio_get_value,
.set_value = mxc_gpio_set_value,
.get_function = mxc_gpio_get_function,
- .get_state = mxc_gpio_get_state,
};
static const struct mxc_gpio_plat mxc_plat[] = {
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 13dcf79..f3a7ccb 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -19,6 +19,7 @@
* Written by Juha Yrjölä <juha.yrjola@nokia.com>
*/
#include <common.h>
+#include <dm.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/errno.h>
@@ -26,10 +27,17 @@
#define OMAP_GPIO_DIR_OUT 0
#define OMAP_GPIO_DIR_IN 1
-static inline const struct gpio_bank *get_gpio_bank(int gpio)
-{
- return &omap_gpio_bank[gpio >> 5];
-}
+#ifdef CONFIG_DM_GPIO
+
+#define GPIO_PER_BANK 32
+
+struct gpio_bank {
+ /* TODO(sjg@chromium.org): Can we use a struct here? */
+ void *base; /* address of registers in physical memory */
+ enum gpio_method method;
+};
+
+#endif
static inline int get_gpio_index(int gpio)
{
@@ -41,15 +49,6 @@ int gpio_is_valid(int gpio)
return (gpio >= 0) && (gpio < OMAP_MAX_GPIO);
}
-static int check_gpio(int gpio)
-{
- if (!gpio_is_valid(gpio)) {
- printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
- return -1;
- }
- return 0;
-}
-
static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
int is_input)
{
@@ -118,6 +117,48 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
__raw_writel(l, reg);
}
+static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
+{
+ void *reg = bank->base;
+ int input;
+
+ switch (bank->method) {
+ case METHOD_GPIO_24XX:
+ input = _get_gpio_direction(bank, gpio);
+ switch (input) {
+ case OMAP_GPIO_DIR_IN:
+ reg += OMAP_GPIO_DATAIN;
+ break;
+ case OMAP_GPIO_DIR_OUT:
+ reg += OMAP_GPIO_DATAOUT;
+ break;
+ default:
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ return (__raw_readl(reg) & (1 << gpio)) != 0;
+}
+
+#ifndef CONFIG_DM_GPIO
+
+static inline const struct gpio_bank *get_gpio_bank(int gpio)
+{
+ return &omap_gpio_bank[gpio >> 5];
+}
+
+static int check_gpio(int gpio)
+{
+ if (!gpio_is_valid(gpio)) {
+ printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
+ return -1;
+ }
+ return 0;
+}
+
/**
* Set value of the specified gpio
*/
@@ -139,32 +180,12 @@ int gpio_set_value(unsigned gpio, int value)
int gpio_get_value(unsigned gpio)
{
const struct gpio_bank *bank;
- void *reg;
- int input;
if (check_gpio(gpio) < 0)
return -1;
bank = get_gpio_bank(gpio);
- reg = bank->base;
- switch (bank->method) {
- case METHOD_GPIO_24XX:
- input = _get_gpio_direction(bank, get_gpio_index(gpio));
- switch (input) {
- case OMAP_GPIO_DIR_IN:
- reg += OMAP_GPIO_DATAIN;
- break;
- case OMAP_GPIO_DIR_OUT:
- reg += OMAP_GPIO_DATAOUT;
- break;
- default:
- return -1;
- }
- break;
- default:
- return -1;
- }
- return (__raw_readl(reg)
- & (1 << get_gpio_index(gpio))) != 0;
+
+ return _get_gpio_value(bank, get_gpio_index(gpio));
}
/**
@@ -220,3 +241,95 @@ int gpio_free(unsigned gpio)
{
return 0;
}
+
+#else /* new driver model interface CONFIG_DM_GPIO */
+
+/* set GPIO pin 'gpio' as an input */
+static int omap_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+
+ /* Configure GPIO direction as input. */
+ _set_gpio_direction(bank, offset, 1);
+
+ return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+static int omap_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+
+ _set_gpio_dataout(bank, offset, value);
+ _set_gpio_direction(bank, offset, 0);
+
+ return 0;
+}
+
+/* read GPIO IN value of pin 'gpio' */
+static int omap_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+
+ return _get_gpio_value(bank, offset);
+}
+
+/* write GPIO OUT value to pin 'gpio' */
+static int omap_gpio_set_value(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+
+ _set_gpio_dataout(bank, offset, value);
+
+ return 0;
+}
+
+static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+
+ /* GPIOF_FUNC is not implemented yet */
+ if (_get_gpio_direction(bank->base, offset) == OMAP_GPIO_DIR_OUT)
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops gpio_omap_ops = {
+ .direction_input = omap_gpio_direction_input,
+ .direction_output = omap_gpio_direction_output,
+ .get_value = omap_gpio_get_value,
+ .set_value = omap_gpio_set_value,
+ .get_function = omap_gpio_get_function,
+};
+
+static int omap_gpio_probe(struct udevice *dev)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+ struct omap_gpio_platdata *plat = dev_get_platdata(dev);
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ char name[18], *str;
+
+ sprintf(name, "GPIO%d_", plat->bank_index);
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ uc_priv->bank_name = str;
+ uc_priv->gpio_count = GPIO_PER_BANK;
+ bank->base = (void *)plat->base;
+ bank->method = plat->method;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(gpio_omap) = {
+ .name = "gpio_omap",
+ .id = UCLASS_GPIO,
+ .ops = &gpio_omap_ops,
+ .probe = omap_gpio_probe,
+ .priv_auto_alloc_size = sizeof(struct gpio_bank),
+};
+
+#endif /* CONFIG_DM_GPIO */
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 13d74eb..6c41a42 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -33,8 +33,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define RATE_MASK(gpio) (0x1 << (gpio + 16))
#define RATE_SET(gpio) (0x1 << (gpio + 16))
-#define GPIO_NAME_SIZE 20
-
/* Platform data for each bank */
struct exynos_gpio_platdata {
struct s5p_gpio_bank *bank;
@@ -43,7 +41,6 @@ struct exynos_gpio_platdata {
/* Information about each bank at run-time */
struct exynos_bank_info {
- char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
struct s5p_gpio_bank *bank;
};
@@ -189,61 +186,10 @@ int s5p_gpio_get_pin(unsigned gpio)
/* Driver model interface */
#ifndef CONFIG_SPL_BUILD
-static int exynos_gpio_get_state(struct udevice *dev, unsigned int offset,
- char *buf, int bufsize)
-{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct exynos_bank_info *state = dev_get_priv(dev);
- const char *label;
- bool is_output;
- int size;
- int cfg;
-
- label = state->label[offset];
- cfg = s5p_gpio_get_cfg_pin(state->bank, offset);
- is_output = cfg == S5P_GPIO_OUTPUT;
- size = snprintf(buf, bufsize, "%s%d: ",
- uc_priv->bank_name ? uc_priv->bank_name : "", offset);
- buf += size;
- bufsize -= size;
- if (is_output || cfg == S5P_GPIO_INPUT) {
- snprintf(buf, bufsize, "%s: %d [%c]%s%s",
- is_output ? "out" : " in",
- s5p_gpio_get_value(state->bank, offset),
- *label ? 'x' : ' ',
- *label ? " " : "",
- label);
- } else {
- snprintf(buf, bufsize, "sfpio");
- }
-
- return 0;
-}
-
-static int check_reserved(struct udevice *dev, unsigned offset,
- const char *func)
-{
- struct exynos_bank_info *state = dev_get_priv(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
- if (!*state->label[offset]) {
- printf("exynos_gpio: %s: error: gpio %s%d not reserved\n",
- func, uc_priv->bank_name, offset);
- return -EPERM;
- }
-
- return 0;
-}
-
/* set GPIO pin 'gpio' as an input */
static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct exynos_bank_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO direction as input. */
s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_INPUT);
@@ -256,11 +202,6 @@ static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
struct exynos_bank_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO output value. */
s5p_gpio_set_value(state->bank, offset, value);
@@ -275,11 +216,6 @@ static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset,
static int exynos_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct exynos_bank_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
return s5p_gpio_get_value(state->bank, offset);
}
@@ -289,43 +225,11 @@ static int exynos_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct exynos_bank_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
s5p_gpio_set_value(state->bank, offset, value);
return 0;
}
-
-static int exynos_gpio_request(struct udevice *dev, unsigned offset,
- const char *label)
-{
- struct exynos_bank_info *state = dev_get_priv(dev);
-
- if (*state->label[offset])
- return -EBUSY;
-
- strncpy(state->label[offset], label, GPIO_NAME_SIZE);
- state->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
- return 0;
-}
-
-static int exynos_gpio_free(struct udevice *dev, unsigned offset)
-{
- struct exynos_bank_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
- state->label[offset][0] = '\0';
-
- return 0;
-}
#endif /* nCONFIG_SPL_BUILD */
/*
@@ -362,8 +266,6 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
struct exynos_bank_info *state = dev_get_priv(dev);
int cfg;
- if (!*state->label[offset])
- return GPIOF_UNUSED;
cfg = s5p_gpio_get_cfg_pin(state->bank, offset);
if (cfg == S5P_GPIO_OUTPUT)
return GPIOF_OUTPUT;
@@ -374,14 +276,11 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
}
static const struct dm_gpio_ops gpio_exynos_ops = {
- .request = exynos_gpio_request,
- .free = exynos_gpio_free,
.direction_input = exynos_gpio_direction_input,
.direction_output = exynos_gpio_direction_output,
.get_value = exynos_gpio_get_value,
.set_value = exynos_gpio_set_value,
.get_function = exynos_gpio_get_function,
- .get_state = exynos_gpio_get_state,
};
static int gpio_exynos_probe(struct udevice *dev)
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 75ada5d..53c80d5 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -14,7 +14,6 @@ DECLARE_GLOBAL_DATA_PTR;
/* Flags for each GPIO */
#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
#define GPIOF_HIGH (1 << 1) /* Currently set high */
-#define GPIOF_RESERVED (1 << 2) /* Is in use / requested */
struct gpio_state {
const char *label; /* label given by requester */
@@ -54,18 +53,6 @@ static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag,
return 0;
}
-static int check_reserved(struct udevice *dev, unsigned offset,
- const char *func)
-{
- if (!get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
- printf("sandbox_gpio: %s: error: offset %u not reserved\n",
- func, offset);
- return -1;
- }
-
- return 0;
-}
-
/*
* Back-channel sandbox-internal-only access to GPIO state
*/
@@ -101,9 +88,6 @@ static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
{
debug("%s: offset:%u\n", __func__, offset);
- if (check_reserved(dev, offset, __func__))
- return -1;
-
return sandbox_gpio_set_direction(dev, offset, 0);
}
@@ -113,9 +97,6 @@ static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
{
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
- if (check_reserved(dev, offset, __func__))
- return -1;
-
return sandbox_gpio_set_direction(dev, offset, 1) |
sandbox_gpio_set_value(dev, offset, value);
}
@@ -125,9 +106,6 @@ static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
{
debug("%s: offset:%u\n", __func__, offset);
- if (check_reserved(dev, offset, __func__))
- return -1;
-
return sandbox_gpio_get_value(dev, offset);
}
@@ -136,9 +114,6 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
- if (check_reserved(dev, offset, __func__))
- return -1;
-
if (!sandbox_gpio_get_direction(dev, offset)) {
printf("sandbox_gpio: error: set_value on input gpio %u\n",
offset);
@@ -148,69 +123,19 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
return sandbox_gpio_set_value(dev, offset, value);
}
-static int sb_gpio_request(struct udevice *dev, unsigned offset,
- const char *label)
+static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct gpio_state *state = dev_get_priv(dev);
-
- debug("%s: offset:%u, label:%s\n", __func__, offset, label);
-
- if (offset >= uc_priv->gpio_count) {
- printf("sandbox_gpio: error: invalid gpio %u\n", offset);
- return -1;
- }
-
- if (get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
- printf("sandbox_gpio: error: gpio %u already reserved\n",
- offset);
- return -1;
- }
-
- state[offset].label = label;
- return set_gpio_flag(dev, offset, GPIOF_RESERVED, 1);
-}
-
-static int sb_gpio_free(struct udevice *dev, unsigned offset)
-{
- struct gpio_state *state = dev_get_priv(dev);
-
- debug("%s: offset:%u\n", __func__, offset);
-
- if (check_reserved(dev, offset, __func__))
- return -1;
-
- state[offset].label = NULL;
- return set_gpio_flag(dev, offset, GPIOF_RESERVED, 0);
-}
-
-static int sb_gpio_get_state(struct udevice *dev, unsigned int offset,
- char *buf, int bufsize)
-{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct gpio_state *state = dev_get_priv(dev);
- const char *label;
-
- label = state[offset].label;
- snprintf(buf, bufsize, "%s%d: %s: %d [%c]%s%s",
- uc_priv->bank_name ? uc_priv->bank_name : "", offset,
- sandbox_gpio_get_direction(dev, offset) ? "out" : " in",
- sandbox_gpio_get_value(dev, offset),
- get_gpio_flag(dev, offset, GPIOF_RESERVED) ? 'x' : ' ',
- label ? " " : "",
- label ? label : "");
-
- return 0;
+ if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
+ return GPIOF_OUTPUT;
+ return GPIOF_INPUT;
}
static const struct dm_gpio_ops gpio_sandbox_ops = {
- .request = sb_gpio_request,
- .free = sb_gpio_free,
.direction_input = sb_gpio_direction_input,
.direction_output = sb_gpio_direction_output,
.get_value = sb_gpio_get_value,
.set_value = sb_gpio_set_value,
- .get_state = sb_gpio_get_state,
+ .get_function = sb_gpio_get_function,
};
static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
@@ -239,6 +164,13 @@ static int gpio_sandbox_probe(struct udevice *dev)
return 0;
}
+static int gpio_sandbox_remove(struct udevice *dev)
+{
+ free(dev->priv);
+
+ return 0;
+}
+
static const struct udevice_id sandbox_gpio_ids[] = {
{ .compatible = "sandbox,gpio" },
{ }
@@ -250,5 +182,6 @@ U_BOOT_DRIVER(gpio_sandbox) = {
.of_match = sandbox_gpio_ids,
.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
.probe = gpio_sandbox_probe,
+ .remove = gpio_sandbox_remove,
.ops = &gpio_sandbox_ops,
};
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 70663fc..88f7ef5 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -39,7 +39,6 @@ struct tegra_gpio_platdata {
/* Information about each port at run-time */
struct tegra_port_info {
- char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE];
struct gpio_ctlr_bank *bank;
int base_gpio; /* Port number for this port (0, 1,.., n-1) */
};
@@ -132,21 +131,6 @@ static void set_level(unsigned gpio, int high)
writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
}
-static int check_reserved(struct udevice *dev, unsigned offset,
- const char *func)
-{
- struct tegra_port_info *state = dev_get_priv(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
- if (!*state->label[offset]) {
- printf("tegra_gpio: %s: error: gpio %s%d not reserved\n",
- func, uc_priv->bank_name, offset);
- return -EBUSY;
- }
-
- return 0;
-}
-
/* set GPIO pin 'gpio' as an output, with polarity 'value' */
int tegra_spl_gpio_direction_output(int gpio, int value)
{
@@ -171,59 +155,16 @@ static int tegra_gpio_request(struct udevice *dev, unsigned offset,
{
struct tegra_port_info *state = dev_get_priv(dev);
- if (!label)
- return -EINVAL;
-
- if (*state->label[offset])
- return -EBUSY;
-
- strncpy(state->label[offset], label, GPIO_NAME_SIZE);
- state->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
/* Configure as a GPIO */
set_config(state->base_gpio + offset, 1);
return 0;
}
-static int tegra_gpio_free(struct udevice *dev, unsigned offset)
-{
- struct tegra_port_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
- state->label[offset][0] = '\0';
-
- return 0;
-}
-
-/* read GPIO OUT value of pin 'gpio' */
-static int tegra_gpio_get_output_value(unsigned gpio)
-{
- struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
- struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
- int val;
-
- debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
- gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
-
- val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
-
- return (val >> GPIO_BIT(gpio)) & 1;
-}
-
-
/* set GPIO pin 'gpio' as an input */
static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct tegra_port_info *state = dev_get_priv(dev);
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO direction as input. */
set_direction(state->base_gpio + offset, 0);
@@ -237,11 +178,6 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset,
{
struct tegra_port_info *state = dev_get_priv(dev);
int gpio = state->base_gpio + offset;
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
/* Configure GPIO output value. */
set_level(gpio, value);
@@ -257,13 +193,8 @@ static int tegra_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct tegra_port_info *state = dev_get_priv(dev);
int gpio = state->base_gpio + offset;
- int ret;
int val;
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
-
debug("%s: pin = %d (port %d:bit %d)\n", __func__,
gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
@@ -277,11 +208,6 @@ static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
struct tegra_port_info *state = dev_get_priv(dev);
int gpio = state->base_gpio + offset;
- int ret;
-
- ret = check_reserved(dev, offset, __func__);
- if (ret)
- return ret;
debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
@@ -317,8 +243,6 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
struct tegra_port_info *state = dev_get_priv(dev);
int gpio = state->base_gpio + offset;
- if (!*state->label[offset])
- return GPIOF_UNUSED;
if (!get_config(gpio))
return GPIOF_FUNC;
else if (get_direction(gpio))
@@ -327,50 +251,13 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
-static int tegra_gpio_get_state(struct udevice *dev, unsigned int offset,
- char *buf, int bufsize)
-{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- struct tegra_port_info *state = dev_get_priv(dev);
- int gpio = state->base_gpio + offset;
- const char *label;
- int is_output;
- int is_gpio;
- int size;
-
- label = state->label[offset];
- is_gpio = get_config(gpio); /* GPIO, not SFPIO */
- size = snprintf(buf, bufsize, "%s%d: ",
- uc_priv->bank_name ? uc_priv->bank_name : "", offset);
- buf += size;
- bufsize -= size;
- if (is_gpio) {
- is_output = get_direction(gpio);
-
- snprintf(buf, bufsize, "%s: %d [%c]%s%s",
- is_output ? "out" : " in",
- is_output ?
- tegra_gpio_get_output_value(gpio) :
- tegra_gpio_get_value(dev, offset),
- *label ? 'x' : ' ',
- *label ? " " : "",
- label);
- } else {
- snprintf(buf, bufsize, "sfpio");
- }
-
- return 0;
-}
-
static const struct dm_gpio_ops gpio_tegra_ops = {
.request = tegra_gpio_request,
- .free = tegra_gpio_free,
.direction_input = tegra_gpio_direction_input,
.direction_output = tegra_gpio_direction_output,
.get_value = tegra_gpio_get_value,
.set_value = tegra_gpio_set_value,
.get_function = tegra_gpio_get_function,
- .get_state = tegra_gpio_get_state,
};
/**
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 5b0c302..ef2cbf9 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -67,14 +67,19 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
#ifdef OMAP_HSMMC_USE_GPIO
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
{
- if (!gpio_is_valid(gpio))
- return -1;
+ int ret;
- if (gpio_request(gpio, label) < 0)
+#ifndef CONFIG_DM_GPIO
+ if (!gpio_is_valid(gpio))
return -1;
+#endif
+ ret = gpio_request(gpio, label);
+ if (ret)
+ return ret;
- if (gpio_direction_input(gpio) < 0)
- return -1;
+ ret = gpio_direction_input(gpio);
+ if (ret)
+ return ret;
return gpio;
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e69de29..a0b6e02 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -0,0 +1,12 @@
+config DM_SERIAL
+ bool "Enable Driver Model for serial drivers"
+ depends on DM
+ help
+ If you want to use driver model for serial drivers, say Y.
+ To use legacy serial drivers, say N.
+
+config UNIPHIER_SERIAL
+ bool "UniPhier on-chip UART support"
+ depends on ARCH_UNIPHIER && DM_SERIAL
+ help
+ Support for the on-chip UARTs on the Panasonic UniPhier platform.
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 17c56ea..2c19ebc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -41,6 +41,8 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o
obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
+obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
+obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 63a9ef6..8f05191 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -61,13 +61,13 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = plat->base + offset;
+ 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.
*/
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
- outb(value, addr);
+ outb(value, (ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
out_le32(addr, value);
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -85,9 +85,9 @@ static int ns16550_readb(NS16550_t port, int offset)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = plat->base + offset;
+ addr = map_sysmem(plat->base, 0) + offset;
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
- return inb(addr);
+ return inb((ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
return in_le32(addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -253,7 +253,7 @@ static int ns16550_serial_getc(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
- if (!serial_in(&com_port->lsr) & UART_LSR_DR)
+ if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
return -EAGAIN;
return serial_in(&com_port->rbr);
@@ -276,14 +276,15 @@ int ns16550_serial_probe(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
+ com_port->plat = dev_get_platdata(dev);
NS16550_init(com_port, -1);
return 0;
}
+#ifdef CONFIG_OF_CONTROL
int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
{
- struct NS16550 *const com_port = dev_get_priv(dev);
struct ns16550_platdata *plat = dev->platdata;
fdt_addr_t addr;
@@ -291,13 +292,13 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
- plat->base = (unsigned char *)addr;
+ plat->base = addr;
plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"reg-shift", 1);
- com_port->plat = plat;
return 0;
}
+#endif
const struct dm_serial_ops ns16550_serial_ops = {
.putc = ns16550_serial_putc,
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 1a75950..71f1a5c 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -11,9 +11,12 @@
#include <os.h>
#include <serial.h>
#include <stdio_dev.h>
+#include <watchdog.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
+#include <ns16550.h>
+
DECLARE_GLOBAL_DATA_PTR;
/* The currently-selected console serial device */
@@ -47,13 +50,22 @@ static void serial_find_console_or_panic(void)
}
#endif
/*
+ * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
+ *
* Failing that, get the device with sequence number 0, or in extremis
* just the first serial device we can find. But we insist on having
* a console (even if it is silent).
*/
- if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
+#ifdef CONFIG_CONS_INDEX
+#define INDEX (CONFIG_CONS_INDEX - 1)
+#else
+#define INDEX 0
+#endif
+ if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) &&
+ uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) &&
(uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
panic("No serial driver found");
+#undef INDEX
}
/* Called prior to relocation */
@@ -71,62 +83,74 @@ void serial_initialize(void)
serial_find_console_or_panic();
}
-static void serial_putc_dev(struct udevice *dev, char ch)
+static void _serial_putc(struct udevice *dev, char ch)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
int err;
do {
- err = ops->putc(cur_dev, ch);
+ err = ops->putc(dev, ch);
} while (err == -EAGAIN);
if (ch == '\n')
- serial_putc('\r');
+ _serial_putc(dev, '\r');
}
-void serial_putc(char ch)
+static void _serial_puts(struct udevice *dev, const char *str)
{
- serial_putc_dev(cur_dev, ch);
+ while (*str)
+ _serial_putc(dev, *str++);
}
-void serial_setbrg(void)
+static int _serial_getc(struct udevice *dev)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+ int err;
- if (ops->setbrg)
- ops->setbrg(cur_dev, gd->baudrate);
-}
+ do {
+ err = ops->getc(dev);
+ if (err == -EAGAIN)
+ WATCHDOG_RESET();
+ } while (err == -EAGAIN);
-void serial_puts(const char *str)
-{
- while (*str)
- serial_putc(*str++);
+ return err >= 0 ? err : 0;
}
-int serial_tstc(void)
+static int _serial_tstc(struct udevice *dev)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
if (ops->pending)
- return ops->pending(cur_dev, true);
+ return ops->pending(dev, true);
return 1;
}
-static int serial_getc_dev(struct udevice *dev)
+void serial_putc(char ch)
{
- struct dm_serial_ops *ops = serial_get_ops(dev);
- int err;
-
- do {
- err = ops->getc(dev);
- } while (err == -EAGAIN);
+ _serial_putc(cur_dev, ch);
+}
- return err >= 0 ? err : 0;
+void serial_puts(const char *str)
+{
+ _serial_puts(cur_dev, str);
}
int serial_getc(void)
{
- return serial_getc_dev(cur_dev);
+ return _serial_getc(cur_dev);
+}
+
+int serial_tstc(void)
+{
+ return _serial_tstc(cur_dev);
+}
+
+void serial_setbrg(void)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+
+ if (ops->setbrg)
+ ops->setbrg(cur_dev, gd->baudrate);
}
void serial_stdio_init(void)
@@ -135,33 +159,22 @@ void serial_stdio_init(void)
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
{
- struct udevice *dev = sdev->priv;
-
- serial_putc_dev(dev, ch);
+ _serial_putc(sdev->priv, ch);
}
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
{
- while (*str)
- serial_stub_putc(sdev, *str++);
+ _serial_puts(sdev->priv, str);
}
int serial_stub_getc(struct stdio_dev *sdev)
{
- struct udevice *dev = sdev->priv;
-
- return serial_getc_dev(dev);
+ return _serial_getc(sdev->priv);
}
int serial_stub_tstc(struct stdio_dev *sdev)
{
- struct udevice *dev = sdev->priv;
- struct dm_serial_ops *ops = serial_get_ops(dev);
-
- if (ops->pending)
- return ops->pending(dev, true);
-
- return 1;
+ return _serial_tstc(sdev->priv);
}
static int serial_post_probe(struct udevice *dev)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 71cb97d..18e41b2 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -157,7 +157,6 @@ serial_initfunc(sh_serial_initialize);
serial_initfunc(arm_dcc_initialize);
serial_initfunc(mxs_auart_initialize);
serial_initfunc(arc_serial_initialize);
-serial_initfunc(uniphier_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@@ -251,7 +250,6 @@ void serial_initialize(void)
arm_dcc_initialize();
mxs_auart_initialize();
arc_serial_initialize();
- uniphier_serial_initialize();
serial_assign(default_serial_console()->name);
}
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644
index 0000000..5c6a76c
--- /dev/null
+++ b/drivers/serial/serial_coreboot.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id coreboot_serial_ids[] = {
+ { .compatible = "coreboot-uart" },
+ { }
+};
+
+static int coreboot_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = 1843200;
+
+ return 0;
+}
+U_BOOT_DRIVER(serial_ns16550) = {
+ .name = "serial_coreboot",
+ .id = UCLASS_SERIAL,
+ .of_match = coreboot_serial_ids,
+ .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+};
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 9ce24f9..d6cf1d8 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -7,10 +7,10 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <serial_mxc.h>
#include <watchdog.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
+#include <dm/platform_data/serial_mxc.h>
#include <serial.h>
#include <linux/compiler.h>
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 632da4c..799ef6a 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = {
.puts = eserial##port##_puts, \
}
-void
-_serial_putc(const char c,const int port)
+static void _serial_putc(const char c, const int port)
{
if (c == '\n')
NS16550_putc(PORT, '\r');
@@ -128,35 +127,29 @@ _serial_putc(const char c,const int port)
NS16550_putc(PORT, c);
}
-void
-_serial_putc_raw(const char c,const int port)
+static void _serial_putc_raw(const char c, const int port)
{
NS16550_putc(PORT, c);
}
-void
-_serial_puts (const char *s,const int port)
+static void _serial_puts(const char *s, const int port)
{
while (*s) {
- _serial_putc (*s++,port);
+ _serial_putc(*s++, port);
}
}
-
-int
-_serial_getc(const int port)
+static int _serial_getc(const int port)
{
return NS16550_getc(PORT);
}
-int
-_serial_tstc(const int port)
+static int _serial_tstc(const int port)
{
return NS16550_tstc(PORT);
}
-void
-_serial_setbrg (const int port)
+static void _serial_setbrg(const int port)
{
int clock_divisor;
diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
new file mode 100644
index 0000000..265fe00
--- /dev/null
+++ b/drivers/serial/serial_omap.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ns16550.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id omap_serial_ids[] = {
+ { .compatible = "ti,omap3-uart" },
+ { }
+};
+
+static int omap_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "clock-frequency", -1);
+ plat->reg_shift = 2;
+
+ return 0;
+}
+#endif
+
+U_BOOT_DRIVER(serial_omap_ns16550) = {
+ .name = "serial_omap",
+ .id = UCLASS_SERIAL,
+ .of_match = of_match_ptr(omap_serial_ids),
+ .ofdata_to_platdata = of_match_ptr(omap_serial_ofdata_to_platdata),
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index e6313ad..38dda91 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -17,7 +17,7 @@
#include <watchdog.h>
#include <asm/io.h>
#include <serial.h>
-#include <serial_pl01x.h>
+#include <dm/platform_data/serial_pl01x.h>
#include <linux/compiler.h>
#include "serial_pl01x_internal.h"
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index c07f4c9..7afc504 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int hwflow;
#endif
-void _serial_setbrg(const int dev_index)
+static void _serial_setbrg(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
unsigned int reg = 0;
@@ -131,7 +131,7 @@ static int serial_init_dev(const int dev_index)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int _serial_getc(const int dev_index)
+static int _serial_getc(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
@@ -181,7 +181,7 @@ void enable_putc(void)
/*
* Output a single byte to the serial port.
*/
-void _serial_putc(const char c, const int dev_index)
+static void _serial_putc(const char c, const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
#ifdef CONFIG_MODEM_SUPPORT
@@ -212,7 +212,7 @@ static inline void serial_putc_dev(unsigned int dev_index, const char c)
/*
* Test whether a character is in the RX buffer
*/
-int _serial_tstc(const int dev_index)
+static int _serial_tstc(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
@@ -224,7 +224,7 @@ static inline int serial_tstc_dev(unsigned int dev_index)
return _serial_tstc(dev_index);
}
-void _serial_puts(const char *s, const int dev_index)
+static void _serial_puts(const char *s, const int dev_index)
{
while (*s) {
_serial_putc(*s++, dev_index);
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index f8c9d92..9114b3e 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -2,14 +2,14 @@
* Copyright (C) 2012-2014 Panasonic Corporation
* Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
*
- * Based on serial_ns16550.c
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/platform_data/serial-uniphier.h>
#include <serial.h>
#define UART_REG(x) \
@@ -48,157 +48,104 @@ struct uniphier_serial {
#define UART_LSR_DR 0x01 /* Data ready */
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
-DECLARE_GLOBAL_DATA_PTR;
+struct uniphier_serial_private_data {
+ struct uniphier_serial __iomem *membase;
+};
+
+#define uniphier_serial_port(dev) \
+ ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
-static void uniphier_serial_init(struct uniphier_serial *port)
+int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
{
+ struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
const unsigned int mode_x_div = 16;
unsigned int divisor;
writeb(UART_LCR_WLS_8, &port->lcr);
- divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK,
- mode_x_div * gd->baudrate);
+ divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate);
writew(divisor, &port->dlr);
-}
-static void uniphier_serial_setbrg(struct uniphier_serial *port)
-{
- uniphier_serial_init(port);
+ return 0;
}
-static int uniphier_serial_tstc(struct uniphier_serial *port)
+static int uniphier_serial_getc(struct udevice *dev)
{
- return (readb(&port->lsr) & UART_LSR_DR) != 0;
-}
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
-static int uniphier_serial_getc(struct uniphier_serial *port)
-{
- while (!uniphier_serial_tstc(port))
- ;
+ if (!(readb(&port->lsr) & UART_LSR_DR))
+ return -EAGAIN;
return readb(&port->rbr);
}
-static void uniphier_serial_putc(struct uniphier_serial *port, const char c)
+static int uniphier_serial_putc(struct udevice *dev, const char c)
{
- if (c == '\n')
- uniphier_serial_putc(port, '\r');
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
- while (!(readb(&port->lsr) & UART_LSR_THRE))
- ;
+ if (!(readb(&port->lsr) & UART_LSR_THRE))
+ return -EAGAIN;
writeb(c, &port->thr);
+
+ return 0;
}
-static struct uniphier_serial *serial_ports[4] = {
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3,
-#else
- NULL,
-#endif
-};
+int uniphier_serial_probe(struct udevice *dev)
+{
+ struct uniphier_serial_private_data *priv = dev_get_priv(dev);
+ struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
- static int eserial##port##_init(void) \
- { \
- uniphier_serial_init(serial_ports[port]); \
- return 0 ; \
- } \
- static void eserial##port##_setbrg(void) \
- { \
- uniphier_serial_setbrg(serial_ports[port]); \
- } \
- static int eserial##port##_getc(void) \
- { \
- return uniphier_serial_getc(serial_ports[port]); \
- } \
- static int eserial##port##_tstc(void) \
- { \
- return uniphier_serial_tstc(serial_ports[port]); \
- } \
- static void eserial##port##_putc(const char c) \
- { \
- uniphier_serial_putc(serial_ports[port], c); \
- }
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, __name) { \
- .name = __name, \
- .start = eserial##port##_init, \
- .stop = NULL, \
- .setbrg = eserial##port##_setbrg, \
- .getc = eserial##port##_getc, \
- .tstc = eserial##port##_tstc, \
- .putc = eserial##port##_putc, \
- .puts = default_serial_puts, \
-}
+ priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial));
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
-DECLARE_ESERIAL_FUNCTIONS(0);
-struct serial_device uniphier_serial0_device =
- INIT_ESERIAL_STRUCTURE(0, "ttyS0");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device uniphier_serial1_device =
- INIT_ESERIAL_STRUCTURE(1, "ttyS1");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device uniphier_serial2_device =
- INIT_ESERIAL_STRUCTURE(2, "ttyS2");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device uniphier_serial3_device =
- INIT_ESERIAL_STRUCTURE(3, "ttyS3");
-#endif
+ if (!priv->membase)
+ return -ENOMEM;
-__weak struct serial_device *default_serial_console(void)
+ return 0;
+}
+
+int uniphier_serial_remove(struct udevice *dev)
{
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
- return &uniphier_serial0_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
- return &uniphier_serial1_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
- return &uniphier_serial2_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
- return &uniphier_serial3_device;
-#else
-#error "No uniphier serial ports configured."
-#endif
+ unmap_sysmem(uniphier_serial_port(dev));
+
+ return 0;
}
-void uniphier_serial_initialize(void)
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id uniphier_uart_of_match = {
+ { .compatible = "panasonic,uniphier-uart"},
+ {},
+};
+
+static int uniphier_serial_ofdata_to_platdata(struct udevice *dev)
{
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
- serial_register(&uniphier_serial0_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
- serial_register(&uniphier_serial1_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
- serial_register(&uniphier_serial2_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
- serial_register(&uniphier_serial3_device);
-#endif
+ /*
+ * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com)
+ *
+ * Implement conversion code from DTB to platform data
+ * when supporting CONFIG_OF_CONTROL on UniPhir platform.
+ */
}
+#endif
+
+static const struct dm_serial_ops uniphier_serial_ops = {
+ .setbrg = uniphier_serial_setbrg,
+ .getc = uniphier_serial_getc,
+ .putc = uniphier_serial_putc,
+};
+
+U_BOOT_DRIVER(uniphier_serial) = {
+ .name = DRIVER_NAME,
+ .id = UCLASS_SERIAL,
+ .of_match = of_match_ptr(uniphier_uart_of_match),
+ .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata),
+ .probe = uniphier_serial_probe,
+ .remove = uniphier_serial_remove,
+ .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data),
+ .platdata_auto_alloc_size =
+ sizeof(struct uniphier_serial_platform_data),
+ .ops = &uniphier_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index e69de29..e1678e6 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -0,0 +1,6 @@
+config DM_SPI
+ bool "Enable Driver Model for SPI drivers"
+ depends on DM
+ help
+ If you want to use driver model for SPI drivers, say Y.
+ To use legacy SPI drivers, say N.
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 347805e..f81b51a 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -29,6 +29,9 @@
* Request a GPIO. This should be called before any of the other functions
* are used on this GPIO.
*
+ * Note: With driver model, the label is allocated so there is no need for
+ * the caller to preserve it.
+ *
* @param gp GPIO number
* @param label User label for this GPIO
* @return 0 if ok, -1 on error
@@ -80,7 +83,7 @@ int gpio_get_value(unsigned gpio);
int gpio_set_value(unsigned gpio, int value);
/* State of a GPIO, as reported by get_function() */
-enum {
+enum gpio_func_t {
GPIOF_INPUT = 0,
GPIOF_OUTPUT,
GPIOF_UNUSED, /* Not claimed */
@@ -93,6 +96,66 @@ enum {
struct udevice;
/**
+ * gpio_get_status() - get the current GPIO status as a string
+ *
+ * Obtain the current GPIO status as a string which can be presented to the
+ * user. A typical string is:
+ *
+ * "b4: in: 1 [x] sdmmc_cd"
+ *
+ * which means this is GPIO bank b, offset 4, currently set to input, current
+ * value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @buf: Place to put string
+ * @buffsize: Size of string including \0
+ */
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
+
+/**
+ * gpio_get_function() - get the current function for a GPIO pin
+ *
+ * Note this returns GPIOF_UNUSED if the GPIO is not requested.
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @namep: If non-NULL, this is set to the nane given when the GPIO
+ * was requested, or -1 if it has not been requested
+ * @return -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the
+ * function from enum gpio_func_t.
+ */
+int gpio_get_function(struct udevice *dev, int offset, const char **namep);
+
+/**
+ * gpio_get_raw_function() - get the current raw function for a GPIO pin
+ *
+ * Note this does not return GPIOF_UNUSED - it will always return the GPIO
+ * driver's view of a pin function, even if it is not correctly set up.
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @namep: If non-NULL, this is set to the nane given when the GPIO
+ * was requested, or -1 if it has not been requested
+ * @return -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * Otherwise returns the function from enum gpio_func_t.
+ */
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep);
+
+/**
+ * gpio_requestf() - request a GPIO using a format string for the owner
+ *
+ * This is a helper function for gpio_request(). It allows you to provide
+ * a printf()-format string for the GPIO owner. It calls gpio_request() with
+ * the string that is created
+ */
+int gpio_requestf(unsigned gpio, const char *fmt, ...)
+ __attribute__ ((format (__printf__, 2, 3)));
+
+/**
* struct struct dm_gpio_ops - Driver model GPIO operations
*
* Refer to functions above for description. These function largely copy
@@ -135,8 +198,6 @@ struct dm_gpio_ops {
* @return current function - GPIOF_...
*/
int (*get_function)(struct udevice *dev, unsigned offset);
- int (*get_state)(struct udevice *dev, unsigned offset, char *state,
- int maxlen);
};
/**
@@ -157,11 +218,14 @@ struct dm_gpio_ops {
* @gpio_base: Base GPIO number for this device. For the first active device
* this will be 0; the numbering for others will follow sequentially so that
* @gpio_base for device 1 will equal the number of GPIOs in device 0.
+ * @name: Array of pointers to the name for each GPIO in this bank. The
+ * value of the pointer will be NULL if the GPIO has not been claimed.
*/
struct gpio_dev_priv {
const char *bank_name;
unsigned gpio_count;
unsigned gpio_base;
+ char **name;
};
/* Access the GPIO operations for a device */
diff --git a/include/common.h b/include/common.h
index d5020c8..bcf6c7e 100644
--- a/include/common.h
+++ b/include/common.h
@@ -636,13 +636,6 @@ struct stdio_dev;
int serial_stub_getc(struct stdio_dev *sdev);
int serial_stub_tstc(struct stdio_dev *sdev);
-void _serial_setbrg (const int);
-void _serial_putc (const char, const int);
-void _serial_putc_raw(const char, const int);
-void _serial_puts (const char *, const int);
-int _serial_getc (const int);
-int _serial_tstc (const int);
-
/* $(CPU)/speed.c */
int get_clocks (void);
int get_clocks_866 (void);
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index 200b744..4b90dc2 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -27,6 +27,11 @@
#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_DISPLAY_BOARDINFO_LATE
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+#define CONFIG_DM_SERIAL
+
#define CONFIG_LMB
#define CONFIG_OF_LIBFDT
@@ -88,21 +93,16 @@
/*-----------------------------------------------------------------------
* Serial Configuration
*/
-#define CONFIG_CONS_INDEX 1
+#define CONFIG_COREBOOT_SERIAL
#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE 1
-#define CONFIG_SYS_NS16550_CLK 1843200
-#define CONFIG_BAUDRATE 9600
+#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE {300, 600, 1200, 2400, 4800, \
9600, 19200, 38400, 115200}
-#define CONFIG_SYS_NS16550_COM1 UART0_BASE
-#define CONFIG_SYS_NS16550_COM2 UART1_BASE
#define CONFIG_SYS_NS16550_PORT_MAPPED
-#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,eserial0\0" \
- "stdout=vga,eserial0,cbmem\0" \
- "stderr=vga,eserial0,cbmem\0"
+#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
+ "stdout=vga,serial,cbmem\0" \
+ "stderr=vga,serial,cbmem\0"
#define CONFIG_CONSOLE_MUX
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
@@ -256,7 +256,7 @@
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
#define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024)
-
+#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
diff --git a/include/configs/ph1_ld4.h b/include/configs/ph1_ld4.h
index a28d7b5..005a853 100644
--- a/include/configs/ph1_ld4.h
+++ b/include/configs/ph1_ld4.h
@@ -28,14 +28,10 @@
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
*/
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
#define CONFIG_SYS_NS16550_SERIAL
#endif
-#define CONFIG_SYS_UNIPHIER_UART_CLK 36864000
-
#define CONFIG_SMC911X
#define CONFIG_DDR_NUM_CH0 1
diff --git a/include/configs/ph1_pro4.h b/include/configs/ph1_pro4.h
index b79967f..7dd6fd2 100644
--- a/include/configs/ph1_pro4.h
+++ b/include/configs/ph1_pro4.h
@@ -28,14 +28,10 @@
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
*/
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
#define CONFIG_SYS_NS16550_SERIAL
#endif
-#define CONFIG_SYS_UNIPHIER_UART_CLK 73728000
-
#define CONFIG_SMC911X
#define CONFIG_DDR_NUM_CH0 2
diff --git a/include/configs/ph1_sld8.h b/include/configs/ph1_sld8.h
index 9d391f1..1062aac 100644
--- a/include/configs/ph1_sld8.h
+++ b/include/configs/ph1_sld8.h
@@ -28,14 +28,10 @@
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
*/
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
#define CONFIG_SYS_NS16550_SERIAL
#endif
-#define CONFIG_SYS_UNIPHIER_UART_CLK 80000000
-
#define CONFIG_SMC911X
#define CONFIG_DDR_NUM_CH0 1
diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h
index 80976e7..5ed86d9 100644
--- a/include/configs/ti_am335x_common.h
+++ b/include/configs/ti_am335x_common.h
@@ -19,12 +19,23 @@
#define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */
#define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_DM
+# define CONFIG_CMD_DM
+# define CONFIG_DM_GPIO
+# define CONFIG_DM_SERIAL
+# define CONFIG_OMAP_SERIAL
+# define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
+#endif
+
#include <asm/arch/omap.h>
/* NS16550 Configuration */
#define CONFIG_SYS_NS16550
+#ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE (-4)
+#endif
#define CONFIG_SYS_NS16550_CLK 48000000
/* Network defines. */
diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h
index 3b19d3d..3c634ee 100644
--- a/include/configs/ti_omap3_common.h
+++ b/include/configs/ti_omap3_common.h
@@ -18,6 +18,15 @@
#include <asm/arch/cpu.h>
#include <asm/arch/omap3.h>
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_DM
+# define CONFIG_CMD_DM
+# define CONFIG_DM_GPIO
+# define CONFIG_DM_SERIAL
+# define CONFIG_OMAP_SERIAL
+# define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
+#endif
+
/* The chip has SDRC controller */
#define CONFIG_SDRC
@@ -28,16 +37,20 @@
/* NS16550 Configuration */
#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE (-4)
-#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
+#ifdef CONFIG_SPL_BUILD
+# define CONFIG_SYS_NS16550_SERIAL
+# define CONFIG_SYS_NS16550_REG_SIZE (-4)
+# define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
+#endif
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \
115200}
/* Select serial console configuration */
#define CONFIG_CONS_INDEX 3
+#ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
#define CONFIG_SERIAL3 3
+#endif
/* Physical Memory Map */
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
diff --git a/include/configs/uniphier-common.h b/include/configs/uniphier-common.h
index 18fe277..b18ae6d 100644
--- a/include/configs/uniphier-common.h
+++ b/include/configs/uniphier-common.h
@@ -33,18 +33,17 @@ are defined. Select only one of them."
# define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000)
#endif
+#ifdef CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550
#define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE
#define CONFIG_SYS_NS16550_CLK 12288000
#define CONFIG_SYS_NS16550_REG_SIZE -2
+#endif
#define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE
#define CONFIG_SMC911X_32_BIT
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE0 0x54006800
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE1 0x54006900
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE2 0x54006a00
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE3 0x54006b00
+#define CONFIG_SYS_MALLOC_F_LEN 0x7000
/*-----------------------------------------------------------------------
* MMU and Cache Setting
diff --git a/include/dm/platform_data/serial-uniphier.h b/include/dm/platform_data/serial-uniphier.h
new file mode 100644
index 0000000..52343e3
--- /dev/null
+++ b/include/dm/platform_data/serial-uniphier.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PLAT_UNIPHIER_SERIAL_H
+#define __PLAT_UNIPHIER_SERIAL_H
+
+#define DRIVER_NAME "uniphier-uart"
+
+struct uniphier_serial_platform_data {
+ unsigned long base;
+ unsigned int uartclk;
+};
+
+#endif /* __PLAT_UNIPHIER_SERIAL_H */
diff --git a/include/serial_mxc.h b/include/dm/platform_data/serial_mxc.h
index 7d3ace2..7d3ace2 100644
--- a/include/serial_mxc.h
+++ b/include/dm/platform_data/serial_mxc.h
diff --git a/include/serial_pl01x.h b/include/dm/platform_data/serial_pl01x.h
index 5e068f3..5e068f3 100644
--- a/include/serial_pl01x.h
+++ b/include/dm/platform_data/serial_pl01x.h
diff --git a/include/dm/test.h b/include/dm/test.h
index 235d728..f08c05d 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -8,6 +8,7 @@
#define __DM_TEST_H
#include <dm.h>
+#include <malloc.h>
/**
* struct dm_test_cdata - configuration data for test instance
@@ -120,6 +121,7 @@ struct dm_test_state {
int force_fail_alloc;
int skip_post_probe;
struct udevice *removed;
+ struct mallinfo start;
};
/* Test flags for each test */
@@ -178,6 +180,27 @@ int dm_check_operations(struct dm_test_state *dms, struct udevice *dev,
int dm_check_devices(struct dm_test_state *dms, int num_devices);
/**
+ * dm_leak_check_start() - Prepare to check for a memory leak
+ *
+ * Call this before allocating memory to record the amount of memory being
+ * used.
+ *
+ * @dms: Overall test state
+ */
+void dm_leak_check_start(struct dm_test_state *dms);
+
+/**
+ * dm_leak_check_end() - Check that no memory has leaked
+ *
+ * Call this after dm_leak_check_start() and after you have hopefuilly freed
+ * all the memory that was allocated. This function will print an error if
+ * it sees a different amount of total memory allocated than before.
+ *
+ * @dms: Overall test state
+ */int dm_leak_check_end(struct dm_test_state *dms);
+
+
+/**
* dm_test_main() - Run all the tests
*
* This runs all available driver model tests
diff --git a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h b/include/dt-bindings/pinctrl/am33xx.h
index 2fbc804..2fbc804 100644
--- a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h
+++ b/include/dt-bindings/pinctrl/am33xx.h
diff --git a/arch/arm/dts/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h
index edbd250..edbd250 100644
--- a/arch/arm/dts/dt-bindings/pinctrl/omap.h
+++ b/include/dt-bindings/pinctrl/omap.h
diff --git a/include/ns16550.h b/include/ns16550.h
index 5784cfd..0607379 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -53,7 +53,7 @@
* @clock: UART base clock speed in Hz
*/
struct ns16550_platdata {
- unsigned char *base;
+ unsigned long base;
int reg_shift;
int clock;
};
diff --git a/test/dm/core.c b/test/dm/core.c
index b0cfb42..ff5c2a7 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -67,6 +67,34 @@ static struct driver_info driver_info_pre_reloc = {
.platdata = &test_pdata_manual,
};
+void dm_leak_check_start(struct dm_test_state *dms)
+{
+ dms->start = mallinfo();
+ if (!dms->start.uordblks)
+ puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
+}
+
+int dm_leak_check_end(struct dm_test_state *dms)
+{
+ struct mallinfo end;
+ int id;
+
+ /* Don't delete the root class, since we started with that */
+ for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
+ struct uclass *uc;
+
+ uc = uclass_find(id);
+ if (!uc)
+ continue;
+ ut_assertok(uclass_destroy(uc));
+ }
+
+ end = mallinfo();
+ ut_asserteq(dms->start.uordblks, end.uordblks);
+
+ return 0;
+}
+
/* Test that binding with platdata occurs correctly */
static int dm_test_autobind(struct dm_test_state *dms)
{
@@ -377,14 +405,11 @@ static int dm_test_leak(struct dm_test_state *dms)
int i;
for (i = 0; i < 2; i++) {
- struct mallinfo start, end;
struct udevice *dev;
int ret;
int id;
- start = mallinfo();
- if (!start.uordblks)
- puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
+ dm_leak_check_start(dms);
ut_assertok(dm_scan_platdata(false));
ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
@@ -398,18 +423,7 @@ static int dm_test_leak(struct dm_test_state *dms)
ut_assertok(ret);
}
- /* Don't delete the root class, since we started with that */
- for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
- struct uclass *uc;
-
- uc = uclass_find(id);
- if (!uc)
- continue;
- ut_assertok(uclass_destroy(uc));
- }
-
- end = mallinfo();
- ut_asserteq(start.uordblks, end.uordblks);
+ ut_assertok(dm_leak_check_end(dms));
}
return 0;
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 2b2b0b5..94bd0d9 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -7,11 +7,14 @@
#include <common.h>
#include <fdtdec.h>
#include <dm.h>
+#include <dm/root.h>
#include <dm/ut.h>
#include <dm/test.h>
#include <dm/util.h>
#include <asm/gpio.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/* Test that sandbox GPIOs work correctly */
static int dm_test_gpio(struct dm_test_state *dms)
{
@@ -39,52 +42,51 @@ static int dm_test_gpio(struct dm_test_state *dms)
/* Get the operations for this device */
ops = gpio_get_ops(dev);
- ut_assert(ops->get_state);
+ ut_assert(ops->get_function);
/* Cannot get a value until it is reserved */
- ut_asserteq(-1, ops->get_value(dev, offset));
-
+ ut_asserteq(-EBUSY, gpio_get_value(gpio + 1));
/*
* Now some tests that use the 'sandbox' back door. All GPIOs
* should default to input, include b4 that we are using here.
*/
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: in: 0 [ ]", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: input: 0 [ ]", buf);
/* Change it to an output */
sandbox_gpio_set_direction(dev, offset, 1);
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: out: 0 [ ]", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: output: 0 [ ]", buf);
sandbox_gpio_set_value(dev, offset, 1);
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: out: 1 [ ]", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: output: 1 [ ]", buf);
- ut_assertok(ops->request(dev, offset, "testing"));
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: out: 1 [x] testing", buf);
+ ut_assertok(gpio_request(gpio, "testing"));
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: output: 1 [x] testing", buf);
/* Change the value a bit */
ut_asserteq(1, ops->get_value(dev, offset));
ut_assertok(ops->set_value(dev, offset, 0));
ut_asserteq(0, ops->get_value(dev, offset));
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: out: 0 [x] testing", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: output: 0 [x] testing", buf);
ut_assertok(ops->set_value(dev, offset, 1));
ut_asserteq(1, ops->get_value(dev, offset));
/* Make it an input */
ut_assertok(ops->direction_input(dev, offset));
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: in: 1 [x] testing", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: input: 1 [x] testing", buf);
sandbox_gpio_set_value(dev, offset, 0);
ut_asserteq(0, sandbox_gpio_get_value(dev, offset));
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: in: 0 [x] testing", buf);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: input: 0 [x] testing", buf);
- ut_assertok(ops->free(dev, offset));
- ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
- ut_asserteq_str("b4: in: 0 [ ]", buf);
+ ut_assertok(gpio_free(gpio));
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b4: input: 0 [ ]", buf);
/* Check the 'a' bank also */
ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio));
@@ -96,6 +98,18 @@ static int dm_test_gpio(struct dm_test_state *dms)
ut_asserteq_str("a", name);
ut_asserteq(20, offset_count);
+ return 0;
+}
+DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that sandbox anonymous GPIOs work correctly */
+static int dm_test_gpio_anon(struct dm_test_state *dms)
+{
+ unsigned int offset, gpio;
+ struct udevice *dev;
+ const char *name;
+ int offset_count;
+
/* And the anonymous bank */
ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
ut_asserteq_str(dev->name, "gpio_sandbox");
@@ -108,4 +122,57 @@ static int dm_test_gpio(struct dm_test_state *dms)
return 0;
}
-DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+DM_TEST(dm_test_gpio_anon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that gpio_requestf() works as expected */
+static int dm_test_gpio_requestf(struct dm_test_state *dms)
+{
+ unsigned int offset, gpio;
+ struct udevice *dev;
+ char buf[80];
+
+ ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio));
+ ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi"));
+ sandbox_gpio_set_direction(dev, offset, 1);
+ sandbox_gpio_set_value(dev, offset, 1);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf);
+
+ return 0;
+}
+DM_TEST(dm_test_gpio_requestf, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that gpio_request() copies its string */
+static int dm_test_gpio_copy(struct dm_test_state *dms)
+{
+ unsigned int offset, gpio;
+ struct udevice *dev;
+ char buf[80], name[10];
+
+ ut_assertok(gpio_lookup_name("b6", &dev, &offset, &gpio));
+ strcpy(name, "odd_name");
+ ut_assertok(gpio_request(gpio, name));
+ sandbox_gpio_set_direction(dev, offset, 1);
+ sandbox_gpio_set_value(dev, offset, 1);
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
+ strcpy(name, "nothing");
+ ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+ ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
+
+ return 0;
+}
+DM_TEST(dm_test_gpio_copy, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we don't leak memory with GPIOs */
+static int dm_test_gpio_leak(struct dm_test_state *dms)
+{
+ ut_assertok(dm_test_gpio(dms));
+ ut_assertok(dm_test_gpio_anon(dms));
+ ut_assertok(dm_test_gpio_requestf(dms));
+ ut_assertok(dm_leak_check_end(dms));
+
+ return 0;
+}
+
+DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 94ce72a..90ca810 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
+#include <malloc.h>
#include <dm/test.h>
#include <dm/root.h>
#include <dm/uclass-internal.h>
@@ -88,6 +89,7 @@ int dm_test_main(void)
printf("Test: %s\n", test->name);
ut_assertok(dm_test_init(dms));
+ dms->start = mallinfo();
if (test->flags & DM_TESTF_SCAN_PDATA)
ut_assertok(dm_scan_platdata(false));
if (test->flags & DM_TESTF_PROBE_TEST)