Merge http://git.denx.de/u-boot-sunxi
authorTom Rini <trini@ti.com>
Sun, 26 Oct 2014 18:13:24 +0000 (14:13 -0400)
committerTom Rini <trini@ti.com>
Sun, 26 Oct 2014 18:13:24 +0000 (14:13 -0400)
148 files changed:
README
arch/arm/cpu/arm926ejs/at91/led.c
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap3/board.c
arch/arm/cpu/armv7/omap3/emif4.c
arch/arm/cpu/armv7/omap3/sys_info.c
arch/arm/cpu/armv7/tegra20/display.c
arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile
arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c [new file with mode: 0644]
arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile
arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c [new file with mode: 0644]
arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile
arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c [new file with mode: 0644]
arch/arm/cpu/tegra-common/sys_info.c
arch/arm/dts/am335x-bone-common.dtsi
arch/arm/dts/dt-bindings/gpio/gpio.h [deleted file]
arch/arm/imx-common/cpu.c
arch/arm/imx-common/misc.c
arch/arm/include/asm/arch-bcm2835/mbox.h
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/arch-omap3/sys_proto.h
arch/arm/include/asm/arch-tegra/board.h
arch/arm/include/asm/arch-uniphier/platdevice.h [new file with mode: 0644]
arch/arm/include/asm/omap_gpio.h
arch/arm/include/asm/u-boot-arm.h
arch/arm/lib/board.c
arch/arm/lib/bootm.c
arch/arm/lib/interrupts.c
arch/x86/cpu/start.S
arch/x86/dts/coreboot.dtsi
arch/x86/dts/link.dts
arch/x86/include/asm/arch-coreboot/gpio.h [new file with mode: 0644]
arch/x86/include/asm/gpio.h
arch/x86/include/asm/ibmpc.h
arch/x86/lib/zimage.c
board/atmel/at91rm9200ek/led.c
board/atmel/at91sam9260ek/led.c
board/compulab/cm_fx6/cm_fx6.c
board/isee/igep00x0/igep00x0.c
board/logicpd/zoom1/zoom1.c
board/nvidia/common/board.c
board/nvidia/common/emc.c
board/nvidia/seaboard/seaboard.c
board/overo/overo.c
board/raspberrypi/rpi_b/rpi_b.c
board/samsung/common/board.c
board/technexion/twister/twister.c
board/ti/beagle/beagle.c
board/ti/beagle/led.c
board/w7o/fsboot.c
common/board_f.c
common/board_r.c
common/cmd_elf.c
common/cmd_gpio.c
common/console.c
common/env_nand.c
common/image-fit.c
common/menu.c
common/modem.c
common/stdio.c
configs/am335x_boneblack_defconfig
configs/am335x_boneblack_vboot_defconfig
configs/ph1_ld4_defconfig
configs/ph1_pro4_defconfig
configs/ph1_sld8_defconfig
disk/part.c
doc/driver-model/README.txt
drivers/core/Kconfig
drivers/gpio/Kconfig
drivers/gpio/bcm2835_gpio.c
drivers/gpio/gpio-uclass.c
drivers/gpio/intel_ich6_gpio.c
drivers/gpio/kw_gpio.c
drivers/gpio/mxc_gpio.c
drivers/gpio/omap_gpio.c
drivers/gpio/s5p_gpio.c
drivers/gpio/sandbox.c
drivers/gpio/tegra_gpio.c
drivers/i2c/designware_i2c.c
drivers/i2c/tegra_i2c.c
drivers/input/tegra-kbc.c
drivers/mmc/bcm2835_sdhci.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/sdhci.c
drivers/mmc/tegra_mmc.c
drivers/mtd/cfi_flash.c
drivers/mtd/nand/omap_gpmc.c
drivers/net/davinci_emac.c
drivers/net/fec_mxc.c
drivers/net/phy/phy.c
drivers/pci/pci.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/ns16550.c
drivers/serial/serial-uclass.c
drivers/serial/serial.c
drivers/serial/serial_coreboot.c [new file with mode: 0644]
drivers/serial/serial_mxc.c
drivers/serial/serial_ns16550.c
drivers/serial/serial_omap.c [new file with mode: 0644]
drivers/serial/serial_pl01x.c
drivers/serial/serial_s3c24x0.c
drivers/serial/serial_sh.c
drivers/serial/serial_uniphier.c
drivers/spi/Kconfig
drivers/usb/eth/asix.c
drivers/usb/host/Makefile
drivers/usb/host/dwc2.c [new file with mode: 0644]
drivers/usb/host/dwc2.h [new file with mode: 0644]
drivers/usb/host/ehci-hcd.c
drivers/video/cfb_console.c
drivers/video/exynos_fb.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/mxc_ipuv3_fb.c
include/asm-generic/gpio.h
include/bootm.h
include/common.h
include/configs/coreboot.h
include/configs/ph1_ld4.h
include/configs/ph1_pro4.h
include/configs/ph1_sld8.h
include/configs/rpi_b.h
include/configs/ti_am335x_common.h
include/configs/ti_omap3_common.h
include/configs/uniphier-common.h
include/dm/platform_data/serial-uniphier.h [new file with mode: 0644]
include/dm/platform_data/serial_mxc.h [moved from include/serial_mxc.h with 100% similarity]
include/dm/platform_data/serial_pl01x.h [moved from include/serial_pl01x.h with 100% similarity]
include/dm/test.h
include/dt-bindings/pinctrl/am33xx.h [moved from arch/arm/dts/dt-bindings/pinctrl/am33xx.h with 100% similarity]
include/dt-bindings/pinctrl/omap.h [moved from arch/arm/dts/dt-bindings/pinctrl/omap.h with 100% similarity]
include/elf.h
include/fdt_support.h
include/ide.h
include/linux/string.h
include/linux/usb/musb.h
include/mmc.h
include/ns16550.h
include/spl.h
include/usb.h
lib/lmb.c
net/eth.c
post/post.c
test/dm/core.c
test/dm/gpio.c
test/dm/test-main.c

diff --git a/README b/README
index 3ff7932..2808dd1 100644 (file)
--- a/README
+++ b/README
@@ -1458,6 +1458,9 @@ The following options need to be configured:
                CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
                txfilltuning field in the EHCI controller on reset.
 
+               CONFIG_USB_DWC2_REG_ADDR the physical CPU address of the DWC2
+               HW module registers.
+
 - USB Device:
                Define the below if you wish to use the USB console.
                Once firmware is rebuilt from a serial console issue the
index 46ed055..b8d5c78 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <asm/gpio.h>
 #include <asm/arch/gpio.h>
+#include <status_led.h>
 
 #ifdef CONFIG_RED_LED
 void red_led_on(void)
index 828d10b..29b1d73 100644 (file)
@@ -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>
 
 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)
 {
index 6352422..a202b03 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <asm/armv7.h>
+#include <asm/bootm.h>
 #include <asm/pl310.h>
 #include <asm/errno.h>
 #include <asm/io.h>
index 667e77f..c942fe6 100644 (file)
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <mmc.h>
 #include <spl.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
 #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>
@@ -38,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 },
@@ -49,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.
@@ -266,7 +291,7 @@ int __weak misc_init_r(void)
  * Routine: wait_for_command_complete
  * Description: Wait for posting to finish on watchdog
  *****************************************************************************/
-void wait_for_command_complete(struct watchdog *wd_base)
+static void wait_for_command_complete(struct watchdog *wd_base)
 {
        int pending = 1;
        do {
index 6c7330a..a2aadc9 100644 (file)
@@ -61,7 +61,7 @@ u32 get_sdr_cs_offset(u32 cs)
  *  - Init the emif4 module for DDR access
  *  - Early init routines, called from flash or SRAM.
  */
-void do_emif4_init(void)
+static void do_emif4_init(void)
 {
        unsigned int regval;
        /* Set the DDR PHY parameters in PHY ctrl registers */
index bef5f05..bbb65bb 100644 (file)
@@ -16,6 +16,8 @@
 #include <asm/io.h>
 #include <asm/arch/mem.h>      /* get mem tables */
 #include <asm/arch/sys_proto.h>
+#include <asm/bootm.h>
+
 #include <i2c.h>
 #include <linux/compiler.h>
 
@@ -202,7 +204,7 @@ u32 __weak get_board_rev(void)
 /********************************************************
  *  get_base(); get upper addr of current execution
  *******************************************************/
-u32 get_base(void)
+static u32 get_base(void)
 {
        u32 val;
 
index fd77f3f..d98cec9 100644 (file)
@@ -194,7 +194,8 @@ static void rgb_enable(struct dc_com_reg *com)
                writel(rgb_sel_tab[i], &com->pin_output_sel[i]);
 }
 
-int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
+static int setup_window(struct disp_ctl_win *win,
+                       struct fdt_disp_config *config)
 {
        win->x = 0;
        win->y = 0;
index b385e19..781b511 100644 (file)
@@ -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 (file)
index 0000000..0047223
--- /dev/null
@@ -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)
index 712afd1..e11f4f6 100644 (file)
@@ -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 (file)
index 0000000..6da921e
--- /dev/null
@@ -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)
index b385e19..781b511 100644 (file)
@@ -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 (file)
index 0000000..59d054a
--- /dev/null
@@ -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)
index de20325..5933c35 100644 (file)
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <linux/ctype.h>
 
-void upstring(char *s)
+static void upstring(char *s)
 {
        while (*s) {
                *s = toupper(*s);
index 2f66ded..e70b4d1 100644 (file)
        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 (file)
index e6b1e0a..0000000
+++ /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
index ed826a0..09fc227 100644 (file)
@@ -7,7 +7,9 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <bootm.h>
 #include <common.h>
+#include <netdev.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
index dbecf4e..12256a3 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/sys_proto.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/imx-common/regs-common.h>
index dded857..61f427d 100644 (file)
@@ -119,6 +119,20 @@ struct bcm2835_mbox_tag_hdr {
  * };
  */
 
+#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS       0x00010003
+
+struct bcm2835_mbox_tag_get_mac_address {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u8 mac[6];
+                       u8 pad[2];
+               } resp;
+       } body;
+};
+
 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY                0x00010005
 
 struct bcm2835_mbox_tag_get_arm_mem {
index 09dfc90..062f3de 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __SYS_PROTO_H__
 #define __SYS_PROTO_H__
 
+#include <asm/imx-common/regs-common.h>
+
 int mxs_reset_block(struct mxs_register_32 *reg);
 int mxs_wait_mask_set(struct mxs_register_32 *reg,
                       uint32_t mask,
index 5866bf2..34bd8c5 100644 (file)
@@ -64,6 +64,7 @@ void try_unlock_memory(void);
 u32 get_boot_type(void);
 void invalidate_dcache(u32);
 u32 wait_on_value(u32, u32, void *, u32);
+void cancel_out(u32 *num, u32 *den, u32 den_limit);
 void sdelay(unsigned long);
 void make_cs1_contiguous(void);
 void omap_nand_switch_ecc(uint32_t, uint32_t);
index ff77364..783bb3c 100644 (file)
@@ -24,10 +24,11 @@ void gpio_early_init(void);  /* overrideable GPIO config        */
  * an empty stub function will be called.
  */
 
-void pinmux_init(void);      /* overrideable general pinmux setup */
-void pin_mux_usb(void);      /* overrideable USB pinmux setup     */
-void pin_mux_spi(void);      /* overrideable SPI pinmux setup     */
-void pin_mux_nand(void);     /* overrideable NAND pinmux setup    */
-void pin_mux_display(void);  /* overrideable DISPLAY pinmux setup */
+void pinmux_init(void);      /* overridable general pinmux setup */
+void pin_mux_usb(void);      /* overridable USB pinmux setup     */
+void pin_mux_spi(void);      /* overridable SPI pinmux setup     */
+void pin_mux_nand(void);     /* overridable NAND pinmux setup    */
+void pin_mux_mmc(void);      /* overridable mmc pinmux setup     */
+void pin_mux_display(void);  /* overridable DISPLAY pinmux setup */
 
 #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 (file)
index 0000000..cdf7d13
--- /dev/null
@@ -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 */
index 5d25d04..839af54 100644 (file)
 
 #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_ */
index b16694c..f97f3dd 100644 (file)
@@ -45,4 +45,19 @@ void reset_timer_masked      (void);
 ulong  get_timer_masked        (void);
 void   udelay_masked           (unsigned long usec);
 
+/* calls to c from vectors.S */
+void bad_mode(void);
+void do_undefined_instruction(struct pt_regs *pt_regs);
+void do_software_interrupt(struct pt_regs *pt_regs);
+void do_prefetch_abort(struct pt_regs *pt_regs);
+void do_data_abort(struct pt_regs *pt_regs);
+void do_not_used(struct pt_regs *pt_regs);
+#ifdef CONFIG_ARM64
+void do_fiq(struct pt_regs *pt_regs, unsigned int esr);
+void do_irq(struct pt_regs *pt_regs, unsigned int esr);
+#else
+void do_fiq(struct pt_regs *pt_regs);
+void do_irq(struct pt_regs *pt_regswq);
+#endif
+
 #endif /* _U_BOOT_ARM_H_ */
index 76adaf3..f606255 100644 (file)
@@ -34,6 +34,7 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 #include <scsi.h>
+#include <status_led.h>
 #include <libfdt.h>
 #include <fdtdec.h>
 #include <post.h>
@@ -63,25 +64,15 @@ extern void dataflash_print_info(void);
  ************************************************************************
  * May be supplied by boards if desired
  */
-inline void __coloured_LED_init(void) {}
-void coloured_LED_init(void)
-       __attribute__((weak, alias("__coloured_LED_init")));
-inline void __red_led_on(void) {}
-void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
-inline void __red_led_off(void) {}
-void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
-inline void __green_led_on(void) {}
-void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
-inline void __green_led_off(void) {}
-void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
-inline void __yellow_led_on(void) {}
-void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
-inline void __yellow_led_off(void) {}
-void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
-inline void __blue_led_on(void) {}
-void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
-inline void __blue_led_off(void) {}
-void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
+__weak void coloured_LED_init(void) {}
+__weak void red_led_on(void) {}
+__weak void red_led_off(void) {}
+__weak void green_led_on(void) {}
+__weak void green_led_off(void) {}
+__weak void yellow_led_on(void) {}
+__weak void yellow_led_off(void) {}
+__weak void blue_led_on(void) {}
+__weak void blue_led_off(void) {}
 
 /*
  ************************************************************************
@@ -198,27 +189,21 @@ static int arm_pci_init(void)
  */
 typedef int (init_fnc_t) (void);
 
-void __dram_init_banksize(void)
+__weak void dram_init_banksize(void)
 {
        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
        gd->bd->bi_dram[0].size =  gd->ram_size;
 }
-void dram_init_banksize(void)
-       __attribute__((weak, alias("__dram_init_banksize")));
 
-int __arch_cpu_init(void)
+__weak int arch_cpu_init(void)
 {
        return 0;
 }
-int arch_cpu_init(void)
-       __attribute__((weak, alias("__arch_cpu_init")));
 
-int __power_init_board(void)
+__weak int power_init_board(void)
 {
        return 0;
 }
-int power_init_board(void)
-       __attribute__((weak, alias("__power_init_board")));
 
        /* Record the board_init_f() bootstage (after arch_cpu_init()) */
 static int mark_bootstage(void)
index 39fe7a1..0d19c8a 100644 (file)
@@ -15,6 +15,7 @@
 #include <common.h>
 #include <command.h>
 #include <image.h>
+#include <vxworks.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
 #include <libfdt.h>
index f6b7c03..9019736 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <asm/proc-armv/ptrace.h>
+#include <asm/u-boot-arm.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
index 329bb3a..338bab1 100644 (file)
@@ -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
 
index 4862a59..c8dc4ce 100644 (file)
@@ -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>;
index 67ce52a..f2fcb39 100644 (file)
               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 (file)
index 0000000..3ec1816
--- /dev/null
@@ -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_ */
index fe09f31..8bda414 100644 (file)
@@ -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_ */
index 0f9665f..e6d183b 100644 (file)
 #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
index 2f0e92f..b190283 100644 (file)
@@ -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"
        );
 }
 
index 2298e36..6761b14 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/at91_pmc.h>
 #include <asm/arch/at91_pio.h>
+#include <status_led.h>
 
 /* bit mask in PIO port B */
 #define        GREEN_LED       (1<<0)
index 56d811c..fbe15af 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/gpio.h>
+#include <status_led.h>
 
 void coloured_LED_init(void)
 {
index f77ff48..82681b1 100644 (file)
@@ -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"
 
index 3b2b1f1..7b87cc2 100644 (file)
@@ -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.
index 461a852..9ef0026 100644 (file)
@@ -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.
index 03f055d..51125df 100644 (file)
@@ -47,46 +47,19 @@ const struct tegra_sysinfo sysinfo = {
        CONFIG_TEGRA_BOARD_STRING
 };
 
-void __pinmux_init(void)
-{
-}
-
-void pinmux_init(void) __attribute__((weak, alias("__pinmux_init")));
-
-void __pin_mux_usb(void)
-{
-}
-
-void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb")));
-
-void __pin_mux_spi(void)
-{
-}
-
-void pin_mux_spi(void) __attribute__((weak, alias("__pin_mux_spi")));
-
-void __gpio_early_init_uart(void)
-{
-}
-
-void gpio_early_init_uart(void)
-__attribute__((weak, alias("__gpio_early_init_uart")));
+__weak void pinmux_init(void) {}
+__weak void pin_mux_usb(void) {}
+__weak void pin_mux_spi(void) {}
+__weak void gpio_early_init_uart(void) {}
+__weak void pin_mux_display(void) {}
 
 #if defined(CONFIG_TEGRA_NAND)
-void __pin_mux_nand(void)
+__weak void pin_mux_nand(void)
 {
        funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
 }
-
-void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand")));
 #endif
 
-void __pin_mux_display(void)
-{
-}
-
-void pin_mux_display(void) __attribute__((weak, alias("__pin_mux_display")));
-
 /*
  * Routine: power_det_init
  * Description: turn off power detects
@@ -204,12 +177,10 @@ int board_late_init(void)
 }
 
 #if defined(CONFIG_TEGRA_MMC)
-void __pin_mux_mmc(void)
+__weak void pin_mux_mmc(void)
 {
 }
 
-void pin_mux_mmc(void) __attribute__((weak, alias("__pin_mux_mmc")));
-
 /* this is a weak define that we are overriding */
 int board_mmc_init(bd_t *bd)
 {
index 8124f8a..8c62f36 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include "emc.h"
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/emc.h>
index 6a243f0..11472eb 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/tegra.h>
+#include <asm/arch-tegra/board.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
 #include <asm/arch/gpio.h>
index 13220c5..7506820 100644 (file)
@@ -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.
index 447c940..7445f53 100644 (file)
@@ -42,6 +42,12 @@ struct msg_get_arm_mem {
        u32 end_tag;
 };
 
+struct msg_get_mac_address {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_mac_address get_mac_address;
+       u32 end_tag;
+};
+
 struct msg_set_power_state {
        struct bcm2835_mbox_hdr hdr;
        struct bcm2835_mbox_tag_set_power_state set_power_state;
@@ -73,6 +79,29 @@ int dram_init(void)
        return 0;
 }
 
+int misc_init_r(void)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16);
+       int ret;
+
+       if (getenv("usbethaddr"))
+               return 0;
+
+       BCM2835_MBOX_INIT_HDR(msg);
+       BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS);
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query MAC address\n");
+               /* Ignore error; not critical */
+               return 0;
+       }
+
+       eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac);
+
+       return 0;
+}
+
 static int power_on_module(u32 module)
 {
        ALLOC_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1, 16);
index e1fc123..8b4c8e9 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int __exynos_early_init_f(void)
+__weak int exynos_early_init_f(void)
 {
        return 0;
 }
-int exynos_early_init_f(void)
-       __attribute__((weak, alias("__exynos_early_init_f")));
 
-int __exynos_power_init(void)
+__weak int exynos_power_init(void)
 {
        return 0;
 }
-int exynos_power_init(void)
-       __attribute__((weak, alias("__exynos_power_init")));
 
 #if defined CONFIG_EXYNOS_TMU
 /* Boot Time Thermal Analysis for SoC temperature threshold breach */
index 054e7cc..a4aed3b 100644 (file)
@@ -16,6 +16,8 @@
 #include <asm/omap_gpio.h>
 #include <asm/arch/mmc_host_def.h>
 #include <i2c.h>
+#include <spl.h>
+#include <mmc.h>
 #include <asm/gpio.h>
 #ifdef CONFIG_USB_EHCI
 #include <usb.h>
index 94b99bf..4c5e381 100644 (file)
@@ -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;
index 89b8dd3..a913a4c 100644 (file)
@@ -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);
 }
index 25fbb55..8f4fe31 100644 (file)
@@ -8,12 +8,11 @@
 #include <common.h>
 #include <config.h>
 #include <command.h>
+#include <elf.h>
 
 /*
  * FIXME: Add code to test image and it's header.
  */
-extern int valid_elf_image (unsigned long addr);
-
 static int
 image_check(ulong addr)
 {
index e6aa298..b5bebc9 100644 (file)
@@ -128,14 +128,11 @@ int init_func_watchdog_reset(void)
 }
 #endif /* CONFIG_WATCHDOG */
 
-void __board_add_ram_info(int use_default)
+__weak void board_add_ram_info(int use_default)
 {
        /* please define platform specific board_add_ram_info() */
 }
 
-void board_add_ram_info(int)
-       __attribute__ ((weak, alias("__board_add_ram_info")));
-
 static int init_baud_rate(void)
 {
        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
@@ -221,7 +218,7 @@ static int show_dram_config(void)
        return 0;
 }
 
-void __dram_init_banksize(void)
+__weak void dram_init_banksize(void)
 {
 #if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
@@ -229,9 +226,6 @@ void __dram_init_banksize(void)
 #endif
 }
 
-void dram_init_banksize(void)
-       __attribute__((weak, alias("__dram_init_banksize")));
-
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 static int init_func_i2c(void)
 {
index 3affb63..7c33900 100644 (file)
@@ -60,7 +60,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
 
-int __board_flash_wp_on(void)
+__weak int board_flash_wp_on(void)
 {
        /*
         * Most flashes can't be detected when write protection is enabled,
@@ -70,16 +70,10 @@ int __board_flash_wp_on(void)
        return 0;
 }
 
-int board_flash_wp_on(void)
-       __attribute__ ((weak, alias("__board_flash_wp_on")));
-
-void __cpu_secondary_init_r(void)
+__weak void cpu_secondary_init_r(void)
 {
 }
 
-void cpu_secondary_init_r(void)
-       __attribute__ ((weak, alias("__cpu_secondary_init_r")));
-
 static int initr_secondary_cpu(void)
 {
        /*
@@ -370,7 +364,7 @@ static int initr_spi(void)
 
 #ifdef CONFIG_CMD_NAND
 /* go init the NAND */
-int initr_nand(void)
+static int initr_nand(void)
 {
        puts("NAND:  ");
        nand_init();
@@ -380,7 +374,7 @@ int initr_nand(void)
 
 #if defined(CONFIG_CMD_ONENAND)
 /* go init the NAND */
-int initr_onenand(void)
+static int initr_onenand(void)
 {
        puts("NAND:  ");
        onenand_init();
@@ -389,7 +383,7 @@ int initr_onenand(void)
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
-int initr_mmc(void)
+static int initr_mmc(void)
 {
        puts("MMC:   ");
        mmc_initialize(gd->bd);
@@ -398,7 +392,7 @@ int initr_mmc(void)
 #endif
 
 #ifdef CONFIG_HAS_DATAFLASH
-int initr_dataflash(void)
+static int initr_dataflash(void)
 {
        AT91F_DataflashInit();
        dataflash_print_info();
index ab9c7e3..42a5296 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <bootm.h>
 #include <command.h>
 #include <linux/ctype.h>
 #include <net.h>
@@ -28,8 +29,7 @@ static unsigned long load_elf_image_phdr(unsigned long addr);
 static unsigned long load_elf_image_shdr(unsigned long addr);
 
 /* Allow ports to override the default behavior */
-__attribute__((weak))
-unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
+static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
                               int argc, char * const argv[])
 {
        unsigned long ret;
index 11f4e40..65d6df4 100644 (file)
@@ -12,7 +12,7 @@
 #include <dm.h>
 #include <asm/gpio.h>
 
-int __weak name_to_gpio(const char *name)
+__weak int name_to_gpio(const char *name)
 {
        return simple_strtoul(name, NULL, 10);
 }
@@ -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);
                                }
                        }
                }
index 5a2f411..4695386 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <stdarg.h>
+#include <iomux.h>
 #include <malloc.h>
 #include <os.h>
 #include <serial.h>
@@ -621,7 +622,7 @@ inline void dbg(const char *fmt, ...)
 
 }
 #else
-inline void dbg(const char *fmt, ...)
+static inline void dbg(const char *fmt, ...)
 {
 }
 #endif
index 5a734a9..749605f 100644 (file)
@@ -124,7 +124,7 @@ int env_init(void)
  * The legacy NAND code saved the environment in the first NAND device i.e.,
  * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
  */
-int writeenv(size_t offset, u_char *buf)
+static int writeenv(size_t offset, u_char *buf)
 {
        size_t end = offset + CONFIG_ENV_RANGE;
        size_t amount_saved = 0;
@@ -233,7 +233,7 @@ int saveenv(void)
 }
 #endif /* CMD_SAVEENV */
 
-int readenv(size_t offset, u_char *buf)
+static int readenv(size_t offset, u_char *buf)
 {
        size_t end = offset + CONFIG_ENV_RANGE;
        size_t amount_loaded = 0;
index 2016d1e..a272ea2 100644 (file)
@@ -1434,7 +1434,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
                printf("%s  FDT:          %s\n", p, uname);
 }
 
-int fit_image_select(const void *fit, int rd_noffset, int verify)
+static int fit_image_select(const void *fit, int rd_noffset, int verify)
 {
        fit_image_print(fit, rd_noffset, "   ");
 
index 94afeb2..e81c074 100644 (file)
@@ -105,12 +105,9 @@ static inline void *menu_item_destroy(struct menu *m,
        return NULL;
 }
 
-void __menu_display_statusline(struct menu *m)
+__weak void menu_display_statusline(struct menu *m)
 {
-       return;
 }
-void menu_display_statusline(struct menu *m)
-       __attribute__ ((weak, alias("__menu_display_statusline")));
 
 /*
  * Display a menu so the user can make a choice of an item. First display its
index be54b10..96b1064 100644 (file)
@@ -19,7 +19,7 @@ static inline void mdm_readline(char *buf, int bufsiz)
        for(;;) {
                c = serial_getc();
 
-               /*              dbg("(%c)", c); */
+               debug("(%c)", c);
 
                switch(c) {
                case '\r':
@@ -40,7 +40,6 @@ static inline void mdm_readline(char *buf, int bufsiz)
        }
 }
 
-extern void  dbg(const char *fmt, ...);
 int mdm_init (void)
 {
        char env_str[16];
@@ -66,15 +65,15 @@ int mdm_init (void)
                        serial_puts("\n");
                        for(;;) {
                                mdm_readline(console_buffer, CONFIG_SYS_CBSIZE);
-                               dbg("ini%d: [%s]", i, console_buffer);
+                               debug("ini%d: [%s]", i, console_buffer);
 
                                if ((strcmp(console_buffer, "OK") == 0) ||
                                        (strcmp(console_buffer, "ERROR") == 0)) {
-                                       dbg("ini%d: cmd done", i);
+                                       debug("ini%d: cmd done", i);
                                        break;
                                } else /* in case we are originating call ... */
                                        if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-                                               dbg("ini%d: connect", i);
+                                               debug("ini%d: connect", i);
                                                return 0;
                                        }
                        }
@@ -90,9 +89,9 @@ int mdm_init (void)
        for(;i > 1;) { /* if 'i' > 1 - wait for connection
                                  message from modem */
                mdm_readline(console_buffer, CONFIG_SYS_CBSIZE);
-               dbg("ini_f: [%s]", console_buffer);
+               debug("ini_f: [%s]", console_buffer);
                if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-                       dbg("ini_f: connected");
+                       debug("ini_f: connected");
                        return 0;
                }
        }
index 8232815..68c595d 100644 (file)
@@ -39,39 +39,39 @@ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
 #endif
 
 #ifdef CONFIG_SYS_DEVICE_NULLDEV
-void nulldev_putc(struct stdio_dev *dev, const char c)
+static void nulldev_putc(struct stdio_dev *dev, const char c)
 {
        /* nulldev is empty! */
 }
 
-void nulldev_puts(struct stdio_dev *dev, const char *s)
+static void nulldev_puts(struct stdio_dev *dev, const char *s)
 {
        /* nulldev is empty! */
 }
 
-int nulldev_input(struct stdio_dev *dev)
+static int nulldev_input(struct stdio_dev *dev)
 {
        /* nulldev is empty! */
        return 0;
 }
 #endif
 
-void stdio_serial_putc(struct stdio_dev *dev, const char c)
+static void stdio_serial_putc(struct stdio_dev *dev, const char c)
 {
        serial_putc(c);
 }
 
-void stdio_serial_puts(struct stdio_dev *dev, const char *s)
+static void stdio_serial_puts(struct stdio_dev *dev, const char *s)
 {
        serial_puts(s);
 }
 
-int stdio_serial_getc(struct stdio_dev *dev)
+static int stdio_serial_getc(struct stdio_dev *dev)
 {
        return serial_getc();
 }
 
-int stdio_serial_tstc(struct stdio_dev *dev)
+static int stdio_serial_tstc(struct stdio_dev *dev)
 {
        return serial_tstc();
 }
index 38450c0..b631c41 100644 (file)
@@ -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
index e257143..5837a0a 100644 (file)
@@ -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
index 53f3126..e6aba42 100644 (file)
@@ -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
index 209466e..334ec4b 100644 (file)
@@ -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
index 658977b..4e8f354 100644 (file)
@@ -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
index cfd77b0..43485c9 100644 (file)
@@ -57,7 +57,7 @@ static const struct block_drvr block_drvr[] = {
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef HAVE_BLOCK_DEVICE
-block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
+static block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 {
        const struct block_drvr *drvr = block_drvr;
        block_dev_desc_t* (*reloc_get_dev)(int dev);
index 8dfcf75..0278dda 100644 (file)
@@ -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
index e69de29..d2799dc 100644 (file)
@@ -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.
index e69de29..d21302f 100644 (file)
@@ -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.
index 332cfc2..0244c01 100644 (file)
 #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)
index f1bbc58..45e9a5a 100644 (file)
@@ -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) = {
index 7d9fac7..d3381b0 100644 (file)
  */
 
 #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),
+};
index 4fca089..43b27e3 100644 (file)
@@ -36,7 +36,7 @@ void __set_direction(unsigned pin, int input)
        u = readl(GPIO_IO_CONF(pin));
 }
 
-void __set_level(unsigned pin, int high)
+static void __set_level(unsigned pin, int high)
 {
        u32 u;
 
@@ -48,7 +48,7 @@ void __set_level(unsigned pin, int high)
        writel(u, GPIO_OUT(pin));
 }
 
-void __set_blinking(unsigned pin, int blink)
+static void __set_blinking(unsigned pin, int blink)
 {
        u32 u;
 
index 3f7b7d2..8bb9e39 100644 (file)
@@ -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[] = {
index 13dcf79..f3a7ccb 100644 (file)
@@ -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>
 #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 */
index 13d74eb..6c41a42 100644 (file)
@@ -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)
index 75ada5d..53c80d5 100644 (file)
@@ -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,
 };
index 70663fc..88f7ef5 100644 (file)
@@ -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,
 };
 
 /**
index c891ebd..e085a70 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include "designware_i2c.h"
+#include <i2c.h>
 
 #ifdef CONFIG_I2C_MULTI_BUS
 static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
@@ -76,16 +77,20 @@ static void set_speed(int i2c_spd)
  *
  * Set the i2c speed.
  */
-int i2c_set_bus_speed(int speed)
+int i2c_set_bus_speed(unsigned int speed)
 {
+       int i2c_spd;
+
        if (speed >= I2C_MAX_SPEED)
-               set_speed(IC_SPEED_MODE_MAX);
+               i2c_spd = IC_SPEED_MODE_MAX;
        else if (speed >= I2C_FAST_SPEED)
-               set_speed(IC_SPEED_MODE_FAST);
+               i2c_spd = IC_SPEED_MODE_FAST;
        else
-               set_speed(IC_SPEED_MODE_STANDARD);
+               i2c_spd = IC_SPEED_MODE_STANDARD;
 
-       return 0;
+       set_speed(i2c_spd);
+
+       return i2c_spd;
 }
 
 /*
@@ -93,7 +98,7 @@ int i2c_set_bus_speed(int speed)
  *
  * Gets the i2c speed.
  */
-int i2c_get_bus_speed(void)
+unsigned int i2c_get_bus_speed(void)
 {
        u32 cntl;
 
@@ -429,7 +434,7 @@ int i2c_set_bus_num(unsigned int bus)
        return 0;
 }
 
-int i2c_get_bus_num(void)
+unsigned int i2c_get_bus_num(void)
 {
        return current_bus;
 }
index 257b72f..562211e 100644 (file)
@@ -471,8 +471,8 @@ static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
 }
 
 /* i2c write version without the register address */
-int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
-                  bool end_with_repeated_start)
+static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
+                         int len, bool end_with_repeated_start)
 {
        int rc;
 
@@ -493,7 +493,8 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
 }
 
 /* i2c read version without the register address */
-int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
+static int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
+                               int len)
 {
        int rc;
 
index 7e36db0..0ef94f7 100644 (file)
@@ -181,7 +181,7 @@ static void kbd_wait_for_fifo_init(struct keyb *config)
  * @param input                Input configuration
  * @return 1, to indicate that we have something to look at
  */
-int tegra_kbc_check(struct input_config *input)
+static int tegra_kbc_check(struct input_config *input)
 {
        kbd_wait_for_fifo_init(&config);
        check_for_keys(&config);
index 82079d6..92f7d89 100644 (file)
@@ -40,6 +40,7 @@
 #include <malloc.h>
 #include <sdhci.h>
 #include <asm/arch/timer.h>
+#include <asm/arch-bcm2835/sdhci.h>
 
 /* 400KHz is max freq for card ID etc. Use that as min */
 #define MIN_FREQ 400000
index 5b0c302..ef2cbf9 100644 (file)
@@ -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;
 }
index 3125d13..de88e19 100644 (file)
@@ -124,7 +124,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 #endif
 #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT       100
 
-int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
+static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
                       struct mmc_data *data)
 {
        struct sdhci_host *host = mmc->priv;
@@ -355,7 +355,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
        sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 }
 
-void sdhci_set_ios(struct mmc *mmc)
+static void sdhci_set_ios(struct mmc *mmc)
 {
        u32 ctrl;
        struct sdhci_host *host = mmc->priv;
@@ -393,7 +393,7 @@ void sdhci_set_ios(struct mmc *mmc)
        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
-int sdhci_init(struct mmc *mmc)
+static int sdhci_init(struct mmc *mmc)
 {
        struct sdhci_host *host = mmc->priv;
 
index 2642fe2..2bd36b0 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/mmc.h>
 #include <asm/arch-tegra/tegra_mmc.h>
 #include <mmc.h>
 
@@ -508,7 +509,7 @@ static int tegra_mmc_core_init(struct mmc *mmc)
        return 0;
 }
 
-int tegra_mmc_getcd(struct mmc *mmc)
+static int tegra_mmc_getcd(struct mmc *mmc)
 {
        struct mmc_host *host = mmc->priv;
 
index 9b3175d..50983b8 100644 (file)
@@ -63,6 +63,12 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS];        /* FLASH chips info */
 #define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_8BIT
 #endif
 
+#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
+#define __maybe_weak __weak
+#else
+#define __maybe_weak static
+#endif
+
 /*
  * 0xffff is an undefined value for the configuration register. When
  * this value is returned, the configuration register shall not be
@@ -81,14 +87,12 @@ static u16 cfi_flash_config_reg(int i)
 int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT;
 #endif
 
-static phys_addr_t __cfi_flash_bank_addr(int i)
+__weak phys_addr_t cfi_flash_bank_addr(int i)
 {
        return ((phys_addr_t [])CONFIG_SYS_FLASH_BANKS_LIST)[i];
 }
-phys_addr_t cfi_flash_bank_addr(int i)
-       __attribute__((weak, alias("__cfi_flash_bank_addr")));
 
-static unsigned long __cfi_flash_bank_size(int i)
+__weak unsigned long cfi_flash_bank_size(int i)
 {
 #ifdef CONFIG_SYS_FLASH_BANKS_SIZES
        return ((unsigned long [])CONFIG_SYS_FLASH_BANKS_SIZES)[i];
@@ -96,71 +100,49 @@ static unsigned long __cfi_flash_bank_size(int i)
        return 0;
 #endif
 }
-unsigned long cfi_flash_bank_size(int i)
-       __attribute__((weak, alias("__cfi_flash_bank_size")));
 
-static void __flash_write8(u8 value, void *addr)
+__maybe_weak void flash_write8(u8 value, void *addr)
 {
        __raw_writeb(value, addr);
 }
 
-static void __flash_write16(u16 value, void *addr)
+__maybe_weak void flash_write16(u16 value, void *addr)
 {
        __raw_writew(value, addr);
 }
 
-static void __flash_write32(u32 value, void *addr)
+__maybe_weak void flash_write32(u32 value, void *addr)
 {
        __raw_writel(value, addr);
 }
 
-static void __flash_write64(u64 value, void *addr)
+__maybe_weak void flash_write64(u64 value, void *addr)
 {
        /* No architectures currently implement __raw_writeq() */
        *(volatile u64 *)addr = value;
 }
 
-static u8 __flash_read8(void *addr)
+__maybe_weak u8 flash_read8(void *addr)
 {
        return __raw_readb(addr);
 }
 
-static u16 __flash_read16(void *addr)
+__maybe_weak u16 flash_read16(void *addr)
 {
        return __raw_readw(addr);
 }
 
-static u32 __flash_read32(void *addr)
+__maybe_weak u32 flash_read32(void *addr)
 {
        return __raw_readl(addr);
 }
 
-static u64 __flash_read64(void *addr)
+__maybe_weak u64 flash_read64(void *addr)
 {
        /* No architectures currently implement __raw_readq() */
        return *(volatile u64 *)addr;
 }
 
-#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
-void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8")));
-void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16")));
-void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32")));
-void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64")));
-u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8")));
-u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16")));
-u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32")));
-u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
-#else
-#define flash_write8   __flash_write8
-#define flash_write16  __flash_write16
-#define flash_write32  __flash_write32
-#define flash_write64  __flash_write64
-#define flash_read8    __flash_read8
-#define flash_read16   __flash_read16
-#define flash_read32   __flash_read32
-#define flash_read64   __flash_read64
-#endif
-
 /*-----------------------------------------------------------------------
  */
 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
index db1599e..40d6705 100644 (file)
@@ -75,7 +75,7 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
 
 #ifdef CONFIG_SPL_BUILD
 /* Check wait pin as dev ready indicator */
-int omap_spl_dev_ready(struct mtd_info *mtd)
+static int omap_spl_dev_ready(struct mtd_info *mtd)
 {
        return gpmc_cfg->status & (1 << 8);
 }
@@ -161,23 +161,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
        return 0;
 }
 
-/*
- * omap_reverse_list - re-orders list elements in reverse order [internal]
- * @list:      pointer to start of list
- * @length:    length of list
-*/
-void omap_reverse_list(u8 *list, unsigned int length)
-{
-       unsigned int i, j;
-       unsigned int half_length = length / 2;
-       u8 tmp;
-       for (i = 0, j = length - 1; i < half_length; i++, j--) {
-               tmp = list[i];
-               list[i] = list[j];
-               list[j] = tmp;
-       }
-}
-
 /*
  * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
  * @mtd:       MTD device structure
@@ -350,6 +333,23 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
 }
 
 #ifdef CONFIG_NAND_OMAP_ELM
+/*
+ * omap_reverse_list - re-orders list elements in reverse order [internal]
+ * @list:      pointer to start of list
+ * @length:    length of list
+*/
+static void omap_reverse_list(u8 *list, unsigned int length)
+{
+       unsigned int i, j;
+       unsigned int half_length = length / 2;
+       u8 tmp;
+       for (i = 0, j = length - 1; i < half_length; i++, j--) {
+               tmp = list[i];
+               list[i] = list[j];
+               list[j] = tmp;
+       }
+}
+
 /*
  * omap_correct_data_bch - Compares the ecc read from nand spare area
  * with ECC registers values and corrects one bit error if it has occured
index 439f8ae..08bc1af 100644 (file)
@@ -27,6 +27,7 @@
 #include <net.h>
 #include <miiphy.h>
 #include <malloc.h>
+#include <netdev.h>
 #include <linux/compiler.h>
 #include <asm/arch/emac_defs.h>
 #include <asm/io.h>
index 549d648..b572470 100644 (file)
@@ -11,6 +11,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <net.h>
+#include <netdev.h>
 #include <miiphy.h>
 #include "fec_mxc.h"
 
@@ -179,13 +180,14 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
        return 0;
 }
 
-int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+static int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr,
+                       int regAddr)
 {
        return fec_mdio_read(bus->priv, phyAddr, regAddr);
 }
 
-int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
-               u16 data)
+static int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr,
+                        int regAddr, u16 data)
 {
        return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
 }
index 1d6c14f..f1ace3c 100644 (file)
@@ -575,7 +575,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
  * Description: Reads the ID registers of the PHY at @addr on the
  *   @bus, stores it in @phy_id and returns zero on success.
  */
-int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
 {
        int phy_reg;
 
@@ -785,16 +785,13 @@ int phy_startup(struct phy_device *phydev)
        return 0;
 }
 
-static int __board_phy_config(struct phy_device *phydev)
+__weak int board_phy_config(struct phy_device *phydev)
 {
        if (phydev->drv->config)
                return phydev->drv->config(phydev);
        return 0;
 }
 
-int board_phy_config(struct phy_device *phydev)
-       __attribute__((weak, alias("__board_phy_config")));
-
 int phy_config(struct phy_device *phydev)
 {
        /* Invoke an optional board-specific helper */
index 28859f3..60c333e 100644 (file)
@@ -572,7 +572,7 @@ const char * pci_class_str(u8 class)
 }
 #endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
 
-int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 {
        /*
         * Check if pci device should be skipped in configuration
@@ -591,19 +591,15 @@ int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 
        return 0;
 }
-int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
-       __attribute__((weak, alias("__pci_skip_dev")));
 
 #ifdef CONFIG_PCI_SCAN_SHOW
-int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
+__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 {
        if (dev == PCI_BDF(hose->first_busno, 0, 0))
                return 0;
 
        return 1;
 }
-int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
-       __attribute__((weak, alias("__pci_print_dev")));
 #endif /* CONFIG_PCI_SCAN_SHOW */
 
 int pci_hose_scan_bus(struct pci_controller *hose, int bus)
index e69de29..a0b6e02 100644 (file)
@@ -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.
index 17c56ea..2c19ebc 100644 (file)
@@ -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
index 63a9ef6..8f05191 100644 (file)
@@ -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,
index 1a75950..71f1a5c 100644 (file)
 #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)
index 82fbbd9..18e41b2 100644 (file)
@@ -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,33 +250,32 @@ void serial_initialize(void)
        arm_dcc_initialize();
        mxs_auart_initialize();
        arc_serial_initialize();
-       uniphier_serial_initialize();
 
        serial_assign(default_serial_console()->name);
 }
 
-int serial_stub_start(struct stdio_dev *sdev)
+static int serial_stub_start(struct stdio_dev *sdev)
 {
        struct serial_device *dev = sdev->priv;
 
        return dev->start();
 }
 
-int serial_stub_stop(struct stdio_dev *sdev)
+static int serial_stub_stop(struct stdio_dev *sdev)
 {
        struct serial_device *dev = sdev->priv;
 
        return dev->stop();
 }
 
-void serial_stub_putc(struct stdio_dev *sdev, const char ch)
+static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
 {
        struct serial_device *dev = sdev->priv;
 
        dev->putc(ch);
 }
 
-void serial_stub_puts(struct stdio_dev *sdev, const char *str)
+static void serial_stub_puts(struct stdio_dev *sdev, const char *str)
 {
        struct serial_device *dev = sdev->priv;
 
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644 (file)
index 0000000..5c6a76c
--- /dev/null
@@ -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,
+};
index 9ce24f9..d6cf1d8 100644 (file)
@@ -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>
 
index 632da4c..799ef6a 100644 (file)
@@ -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 (file)
index 0000000..265fe00
--- /dev/null
@@ -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,
+};
index e6313ad..38dda91 100644 (file)
@@ -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"
 
index c07f4c9..7afc504 100644 (file)
@@ -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);
index 144a925..7c1f271 100644 (file)
@@ -122,7 +122,7 @@ static void handle_error(void)
        sci_out(&sh_sci, SCLSR, 0x00);
 }
 
-void serial_raw_putc(const char c)
+static void serial_raw_putc(const char c)
 {
        while (1) {
                /* Tx fifo is empty */
@@ -152,7 +152,7 @@ static int sh_serial_tstc(void)
 }
 
 
-int serial_getc_check(void)
+static int serial_getc_check(void)
 {
        unsigned short status;
 
index f8c9d92..9114b3e 100644 (file)
@@ -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,
+};
index e69de29..e1678e6 100644 (file)
@@ -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.
index 6557055..1181109 100644 (file)
@@ -580,6 +580,7 @@ static const struct asix_dongle asix_dongles[] = {
        { 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
        /* ASIX 88772B */
        { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+       { 0x0b95, 0x7e2b, FLAG_TYPE_AX88772B },
        { 0x0000, 0x0000, FLAG_NONE }   /* END - Do not remove */
 };
 
index c4f5157..c9d2ed5 100644 (file)
@@ -45,3 +45,6 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
 obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
+
+# designware
+obj-$(CONFIG_USB_DWC2) += dwc2.o
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
new file mode 100644 (file)
index 0000000..2a5bbf5
--- /dev/null
@@ -0,0 +1,1053 @@
+/*
+ * Copyright (C) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <usb.h>
+#include <malloc.h>
+#include <usbroothubdes.h>
+#include <asm/io.h>
+
+#include "dwc2.h"
+
+/* Use only HC channel 0. */
+#define DWC2_HC_CHANNEL                        0
+
+#define DWC2_STATUS_BUF_SIZE           64
+#define DWC2_DATA_BUF_SIZE             (64 * 1024)
+
+/* We need doubleword-aligned buffers for DMA transfers */
+DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer, DWC2_DATA_BUF_SIZE, 8);
+DEFINE_ALIGN_BUFFER(uint8_t, status_buffer, DWC2_STATUS_BUF_SIZE, 8);
+
+#define MAX_DEVICE                     16
+#define MAX_ENDPOINT                   16
+static int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
+static int control_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
+
+static int root_hub_devnum;
+
+static struct dwc2_core_regs *regs =
+       (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR;
+
+/*
+ * DWC2 IP interface
+ */
+static int wait_for_bit(void *reg, const uint32_t mask, bool set)
+{
+       unsigned int timeout = 1000000;
+       uint32_t val;
+
+       while (--timeout) {
+               val = readl(reg);
+               if (!set)
+                       val = ~val;
+
+               if ((val & mask) == mask)
+                       return 0;
+
+               udelay(1);
+       }
+
+       debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
+             __func__, reg, mask, set);
+
+       return -ETIMEDOUT;
+}
+
+/*
+ * Initializes the FSLSPClkSel field of the HCFG register
+ * depending on the PHY type.
+ */
+static void init_fslspclksel(struct dwc2_core_regs *regs)
+{
+       uint32_t phyclk;
+
+#if (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
+       phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
+#else
+       /* High speed PHY running at full speed or high speed */
+       phyclk = DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ;
+#endif
+
+#ifdef CONFIG_DWC2_ULPI_FS_LS
+       uint32_t hwcfg2 = readl(&regs->ghwcfg2);
+       uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
+       uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
+
+       if (hval == 2 && fval == 1)
+               phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
+#endif
+
+       clrsetbits_le32(&regs->host_regs.hcfg,
+                       DWC2_HCFG_FSLSPCLKSEL_MASK,
+                       phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET);
+}
+
+/*
+ * Flush a Tx FIFO.
+ *
+ * @param regs Programming view of DWC_otg controller.
+ * @param num Tx FIFO to flush.
+ */
+static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
+{
+       int ret;
+
+       writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
+              &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Wait for 3 PHY Clocks */
+       udelay(1);
+}
+
+/*
+ * Flush Rx FIFO.
+ *
+ * @param regs Programming view of DWC_otg controller.
+ */
+static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs)
+{
+       int ret;
+
+       writel(DWC2_GRSTCTL_RXFFLSH, &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Wait for 3 PHY Clocks */
+       udelay(1);
+}
+
+/*
+ * Do core a soft reset of the core.  Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+static void dwc_otg_core_reset(struct dwc2_core_regs *regs)
+{
+       int ret;
+
+       /* Wait for AHB master IDLE state. */
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE, 1);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Core Soft Reset */
+       writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_CSFTRST, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /*
+        * Wait for core to come out of reset.
+        * NOTE: This long sleep is _very_ important, otherwise the core will
+        *       not stay in host mode after a connector ID change!
+        */
+       mdelay(100);
+}
+
+/*
+ * This function initializes the DWC_otg controller registers for
+ * host mode.
+ *
+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ * request queues. Host channels are reset to ensure that they are ready for
+ * performing transfers.
+ *
+ * @param regs Programming view of DWC_otg controller
+ *
+ */
+static void dwc_otg_core_host_init(struct dwc2_core_regs *regs)
+{
+       uint32_t nptxfifosize = 0;
+       uint32_t ptxfifosize = 0;
+       uint32_t hprt0 = 0;
+       int i, ret, num_channels;
+
+       /* Restart the Phy Clock */
+       writel(0, &regs->pcgcctl);
+
+       /* Initialize Host Configuration Register */
+       init_fslspclksel(regs);
+#ifdef CONFIG_DWC2_DFLT_SPEED_FULL
+       setbits_le32(&regs->host_regs.hcfg, DWC2_HCFG_FSLSSUPP);
+#endif
+
+       /* Configure data FIFO sizes */
+#ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO
+       if (readl(&regs->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) {
+               /* Rx FIFO */
+               writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, &regs->grxfsiz);
+
+               /* Non-periodic Tx FIFO */
+               nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_DEPTH_OFFSET;
+               nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_STARTADDR_OFFSET;
+               writel(nptxfifosize, &regs->gnptxfsiz);
+
+               /* Periodic Tx FIFO */
+               ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_DEPTH_OFFSET;
+               ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE +
+                               CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) <<
+                               DWC2_FIFOSIZE_STARTADDR_OFFSET;
+               writel(ptxfifosize, &regs->hptxfsiz);
+       }
+#endif
+
+       /* Clear Host Set HNP Enable in the OTG Control Register */
+       clrbits_le32(&regs->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN);
+
+       /* Make sure the FIFOs are flushed. */
+       dwc_otg_flush_tx_fifo(regs, 0x10);      /* All Tx FIFOs */
+       dwc_otg_flush_rx_fifo(regs);
+
+       /* Flush out any leftover queued requests. */
+       num_channels = readl(&regs->ghwcfg2);
+       num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK;
+       num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET;
+       num_channels += 1;
+
+       for (i = 0; i < num_channels; i++)
+               clrsetbits_le32(&regs->hc_regs[i].hcchar,
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR,
+                               DWC2_HCCHAR_CHDIS);
+
+       /* Halt all channels to put them into a known state. */
+       for (i = 0; i < num_channels; i++) {
+               clrsetbits_le32(&regs->hc_regs[i].hcchar,
+                               DWC2_HCCHAR_EPDIR,
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
+               ret = wait_for_bit(&regs->hc_regs[i].hcchar,
+                                  DWC2_HCCHAR_CHEN, 0);
+               if (ret)
+                       printf("%s: Timeout!\n", __func__);
+       }
+
+       /* Turn on the vbus power. */
+       if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST) {
+               hprt0 = readl(&regs->hprt0);
+               hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET);
+               hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG);
+               if (!(hprt0 & DWC2_HPRT0_PRTPWR)) {
+                       hprt0 |= DWC2_HPRT0_PRTPWR;
+                       writel(hprt0, &regs->hprt0);
+               }
+       }
+}
+
+/*
+ * This function initializes the DWC_otg controller registers and
+ * prepares the core for device mode or host mode operation.
+ *
+ * @param regs Programming view of the DWC_otg controller
+ */
+static void dwc_otg_core_init(struct dwc2_core_regs *regs)
+{
+       uint32_t ahbcfg = 0;
+       uint32_t usbcfg = 0;
+       uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE;
+
+       /* Common Initialization */
+       usbcfg = readl(&regs->gusbcfg);
+
+       /* Program the ULPI External VBUS bit if needed */
+#ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS
+       usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
+#else
+       usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
+#endif
+
+       /* Set external TS Dline pulsing */
+#ifdef CONFIG_DWC2_TS_DLINE
+       usbcfg |= DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
+#else
+       usbcfg &= ~DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
+#endif
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Reset the Controller */
+       dwc_otg_core_reset(regs);
+
+       /*
+        * This programming sequence needs to happen in FS mode before
+        * any other programming occurs
+        */
+#if defined(CONFIG_DWC2_DFLT_SPEED_FULL) && \
+       (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
+       /* If FS mode with FS PHY */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_PHYSEL);
+
+       /* Reset after a PHY select */
+       dwc_otg_core_reset(regs);
+
+       /*
+        * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.
+        * Also do this on HNP Dev/Host mode switches (done in dev_init
+        * and host_init).
+        */
+       if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST)
+               init_fslspclksel(regs);
+
+#ifdef CONFIG_DWC2_I2C_ENABLE
+       /* Program GUSBCFG.OtgUtmifsSel to I2C */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_OTGUTMIFSSEL);
+
+       /* Program GI2CCTL.I2CEn */
+       clrsetbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN |
+                       DWC2_GI2CCTL_I2CDEVADDR_MASK,
+                       1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET);
+       setbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN);
+#endif
+
+#else
+       /* High speed PHY. */
+
+       /*
+        * HS PHY parameters. These parameters are preserved during
+        * soft reset so only program the first time. Do a soft reset
+        * immediately after setting phyif.
+        */
+       usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF);
+       usbcfg |= CONFIG_DWC2_PHY_TYPE << DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET;
+
+       if (usbcfg & DWC2_GUSBCFG_ULPI_UTMI_SEL) {      /* ULPI interface */
+#ifdef CONFIG_DWC2_PHY_ULPI_DDR
+               usbcfg |= DWC2_GUSBCFG_DDRSEL;
+#else
+               usbcfg &= ~DWC2_GUSBCFG_DDRSEL;
+#endif
+       } else {        /* UTMI+ interface */
+#if (CONFIG_DWC2_UTMI_PHY_WIDTH == 16)
+               usbcfg |= DWC2_GUSBCFG_PHYIF;
+#endif
+       }
+
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Reset after setting the PHY parameters */
+       dwc_otg_core_reset(regs);
+#endif
+
+       usbcfg = readl(&regs->gusbcfg);
+       usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M);
+#ifdef CONFIG_DWC2_ULPI_FS_LS
+       uint32_t hwcfg2 = readl(&regs->ghwcfg2);
+       uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
+       uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
+       if (hval == 2 && fval == 1) {
+               usbcfg |= DWC2_GUSBCFG_ULPI_FSLS;
+               usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M;
+       }
+#endif
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Program the GAHBCFG Register. */
+       switch (readl(&regs->ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) {
+       case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY:
+               break;
+       case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA:
+               while (brst_sz > 1) {
+                       ahbcfg |= ahbcfg + (1 << DWC2_GAHBCFG_HBURSTLEN_OFFSET);
+                       ahbcfg &= DWC2_GAHBCFG_HBURSTLEN_MASK;
+                       brst_sz >>= 1;
+               }
+
+#ifdef CONFIG_DWC2_DMA_ENABLE
+               ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
+#endif
+               break;
+
+       case DWC2_HWCFG2_ARCHITECTURE_INT_DMA:
+               ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4;
+#ifdef CONFIG_DWC2_DMA_ENABLE
+               ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
+#endif
+               break;
+       }
+
+       writel(ahbcfg, &regs->gahbcfg);
+
+       /* Program the GUSBCFG register for HNP/SRP. */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP);
+
+#ifdef CONFIG_DWC2_IC_USB_CAP
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP);
+#endif
+}
+
+/*
+ * Prepares a host channel for transferring packets to/from a specific
+ * endpoint. The HCCHARn register is set up with the characteristics specified
+ * in _hc. Host channel interrupts that may need to be serviced while this
+ * transfer is in progress are enabled.
+ *
+ * @param regs Programming view of DWC_otg controller
+ * @param hc Information needed to initialize the host channel
+ */
+static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num,
+               uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in,
+               uint8_t ep_type, uint16_t max_packet)
+{
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[hc_num];
+       const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
+                               (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
+                               (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
+                               (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
+                               (max_packet << DWC2_HCCHAR_MPS_OFFSET);
+
+       /* Clear old interrupt conditions for this host channel. */
+       writel(0x3fff, &hc_regs->hcint);
+
+       /*
+        * Program the HCCHARn register with the endpoint characteristics
+        * for the current transfer.
+        */
+       writel(hcchar, &hc_regs->hcchar);
+
+       /* Program the HCSPLIT register for SPLITs */
+       writel(0, &hc_regs->hcsplt);
+}
+
+/*
+ * DWC2 to USB API interface
+ */
+/* Direction: In ; Request: Status */
+static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer,
+                                          int txlen, struct devrequest *cmd)
+{
+       uint32_t hprt0 = 0;
+       uint32_t port_status = 0;
+       uint32_t port_change = 0;
+       int len = 0;
+       int stat = 0;
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               *(uint16_t *)buffer = cpu_to_le16(1);
+               len = 2;
+               break;
+       case USB_RECIP_INTERFACE:
+       case USB_RECIP_ENDPOINT:
+               *(uint16_t *)buffer = cpu_to_le16(0);
+               len = 2;
+               break;
+       case USB_TYPE_CLASS:
+               *(uint32_t *)buffer = cpu_to_le32(0);
+               len = 4;
+               break;
+       case USB_RECIP_OTHER | USB_TYPE_CLASS:
+               hprt0 = readl(&regs->hprt0);
+               if (hprt0 & DWC2_HPRT0_PRTCONNSTS)
+                       port_status |= USB_PORT_STAT_CONNECTION;
+               if (hprt0 & DWC2_HPRT0_PRTENA)
+                       port_status |= USB_PORT_STAT_ENABLE;
+               if (hprt0 & DWC2_HPRT0_PRTSUSP)
+                       port_status |= USB_PORT_STAT_SUSPEND;
+               if (hprt0 & DWC2_HPRT0_PRTOVRCURRACT)
+                       port_status |= USB_PORT_STAT_OVERCURRENT;
+               if (hprt0 & DWC2_HPRT0_PRTRST)
+                       port_status |= USB_PORT_STAT_RESET;
+               if (hprt0 & DWC2_HPRT0_PRTPWR)
+                       port_status |= USB_PORT_STAT_POWER;
+
+               port_status |= USB_PORT_STAT_HIGH_SPEED;
+
+               if (hprt0 & DWC2_HPRT0_PRTENCHNG)
+                       port_change |= USB_PORT_STAT_C_ENABLE;
+               if (hprt0 & DWC2_HPRT0_PRTCONNDET)
+                       port_change |= USB_PORT_STAT_C_CONNECTION;
+               if (hprt0 & DWC2_HPRT0_PRTOVRCURRCHNG)
+                       port_change |= USB_PORT_STAT_C_OVERCURRENT;
+
+               *(uint32_t *)buffer = cpu_to_le32(port_status |
+                                       (port_change << 16));
+               len = 4;
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In ; Request: Descriptor */
+static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev,
+                                              void *buffer, int txlen,
+                                              struct devrequest *cmd)
+{
+       unsigned char data[32];
+       uint32_t dsc;
+       int len = 0;
+       int stat = 0;
+       uint16_t wValue = cpu_to_le16(cmd->value);
+       uint16_t wLength = cpu_to_le16(cmd->length);
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               switch (wValue & 0xff00) {
+               case 0x0100:    /* device descriptor */
+                       len = min3(txlen, sizeof(root_hub_dev_des), wLength);
+                       memcpy(buffer, root_hub_dev_des, len);
+                       break;
+               case 0x0200:    /* configuration descriptor */
+                       len = min3(txlen, sizeof(root_hub_config_des), wLength);
+                       memcpy(buffer, root_hub_config_des, len);
+                       break;
+               case 0x0300:    /* string descriptors */
+                       switch (wValue & 0xff) {
+                       case 0x00:
+                               len = min3(txlen, sizeof(root_hub_str_index0),
+                                          wLength);
+                               memcpy(buffer, root_hub_str_index0, len);
+                               break;
+                       case 0x01:
+                               len = min3(txlen, sizeof(root_hub_str_index1),
+                                          wLength);
+                               memcpy(buffer, root_hub_str_index1, len);
+                               break;
+                       }
+                       break;
+               default:
+                       stat = USB_ST_STALLED;
+               }
+               break;
+
+       case USB_TYPE_CLASS:
+               /* Root port config, set 1 port and nothing else. */
+               dsc = 0x00000001;
+
+               data[0] = 9;            /* min length; */
+               data[1] = 0x29;
+               data[2] = dsc & RH_A_NDP;
+               data[3] = 0;
+               if (dsc & RH_A_PSM)
+                       data[3] |= 0x1;
+               if (dsc & RH_A_NOCP)
+                       data[3] |= 0x10;
+               else if (dsc & RH_A_OCPM)
+                       data[3] |= 0x8;
+
+               /* corresponds to data[4-7] */
+               data[5] = (dsc & RH_A_POTPGT) >> 24;
+               data[7] = dsc & RH_B_DR;
+               if (data[2] < 7) {
+                       data[8] = 0xff;
+               } else {
+                       data[0] += 2;
+                       data[8] = (dsc & RH_B_DR) >> 8;
+                       data[9] = 0xff;
+                       data[10] = data[9];
+               }
+
+               len = min3(txlen, data[0], wLength);
+               memcpy(buffer, data, len);
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In ; Request: Configuration */
+static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev,
+                                                 void *buffer, int txlen,
+                                                 struct devrequest *cmd)
+{
+       int len = 0;
+       int stat = 0;
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               *(uint8_t *)buffer = 0x01;
+               len = 1;
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In */
+static int dwc_otg_submit_rh_msg_in(struct usb_device *dev,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       switch (cmd->request) {
+       case USB_REQ_GET_STATUS:
+               return dwc_otg_submit_rh_msg_in_status(dev, buffer,
+                                                      txlen, cmd);
+       case USB_REQ_GET_DESCRIPTOR:
+               return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer,
+                                                          txlen, cmd);
+       case USB_REQ_GET_CONFIGURATION:
+               return dwc_otg_submit_rh_msg_in_configuration(dev, buffer,
+                                                             txlen, cmd);
+       default:
+               puts("unsupported root hub command\n");
+               return USB_ST_STALLED;
+       }
+}
+
+/* Direction: Out */
+static int dwc_otg_submit_rh_msg_out(struct usb_device *dev,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       int len = 0;
+       int stat = 0;
+       uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8);
+       uint16_t wValue = cpu_to_le16(cmd->value);
+
+       switch (bmrtype_breq & ~USB_DIR_IN) {
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT:
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS:
+               break;
+
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_C_CONNECTION:
+                       setbits_le32(&regs->hprt0, DWC2_HPRT0_PRTCONNDET);
+                       break;
+               }
+               break;
+
+       case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_SUSPEND:
+                       break;
+
+               case USB_PORT_FEAT_RESET:
+                       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                                       DWC2_HPRT0_PRTCONNDET |
+                                       DWC2_HPRT0_PRTENCHNG |
+                                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                                       DWC2_HPRT0_PRTRST);
+                       mdelay(50);
+                       clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTRST);
+                       break;
+
+               case USB_PORT_FEAT_POWER:
+                       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                                       DWC2_HPRT0_PRTCONNDET |
+                                       DWC2_HPRT0_PRTENCHNG |
+                                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                                       DWC2_HPRT0_PRTRST);
+                       break;
+
+               case USB_PORT_FEAT_ENABLE:
+                       break;
+               }
+               break;
+       case (USB_REQ_SET_ADDRESS << 8):
+               root_hub_devnum = wValue;
+               break;
+       case (USB_REQ_SET_CONFIGURATION << 8):
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       len = min(len, txlen);
+
+       dev->act_len = len;
+       dev->status = stat;
+
+       return stat;
+}
+
+static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       int stat = 0;
+
+       if (usb_pipeint(pipe)) {
+               puts("Root-Hub submit IRQ: NOT implemented\n");
+               return 0;
+       }
+
+       if (cmd->requesttype & USB_DIR_IN)
+               stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd);
+       else
+               stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd);
+
+       mdelay(1);
+
+       return stat;
+}
+
+/* U-Boot USB transmission interface */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                   int len)
+{
+       int devnum = usb_pipedevice(pipe);
+       int ep = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       int done = 0;
+       uint32_t hctsiz, sub, tmp;
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
+       uint32_t hcint;
+       uint32_t xfer_len;
+       uint32_t num_packets;
+       int stop_transfer = 0;
+       unsigned int timeout = 1000000;
+
+       if (devnum == root_hub_devnum) {
+               dev->status = 0;
+               return -EINVAL;
+       }
+
+       if (len > DWC2_DATA_BUF_SIZE) {
+               printf("%s: %d is more then available buffer size (%d)\n",
+                      __func__, len, DWC2_DATA_BUF_SIZE);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       while ((done < len) && !stop_transfer) {
+               /* Initialize channel */
+               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                               usb_pipein(pipe), DWC2_HCCHAR_EPTYPE_BULK, max);
+
+               xfer_len = len - done;
+               /* Make sure that xfer_len is a multiple of max packet size. */
+               if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
+                       xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
+
+               if (xfer_len > 0) {
+                       num_packets = (xfer_len + max - 1) / max;
+                       if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
+                               num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
+                               xfer_len = num_packets * max;
+                       }
+               } else {
+                       num_packets = 1;
+               }
+
+               if (usb_pipein(pipe))
+                       xfer_len = num_packets * max;
+
+               writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+                      (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+                      (bulk_data_toggle[devnum][ep] <<
+                               DWC2_HCTSIZ_PID_OFFSET),
+                      &hc_regs->hctsiz);
+
+               memcpy(aligned_buffer, (char *)buffer + done, len - done);
+               writel((uint32_t)aligned_buffer, &hc_regs->hcdma);
+
+               /* Set host channel enable after all other setup is complete. */
+               clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                               (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
+                               DWC2_HCCHAR_CHEN);
+
+               while (1) {
+                       hcint = readl(&hc_regs->hcint);
+
+                       if (!(hcint & DWC2_HCINT_CHHLTD))
+                               continue;
+
+                       if (hcint & DWC2_HCINT_XFERCOMP) {
+                               hctsiz = readl(&hc_regs->hctsiz);
+                               done += xfer_len;
+
+                               sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
+                               sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
+
+                               if (usb_pipein(pipe)) {
+                                       done -= sub;
+                                       if (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK)
+                                               stop_transfer = 1;
+                               }
+
+                               tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
+                               tmp >>= DWC2_HCTSIZ_PID_OFFSET;
+                               if (tmp == DWC2_HC_PID_DATA1) {
+                                       bulk_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA1;
+                               } else {
+                                       bulk_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA0;
+                               }
+                               break;
+                       }
+
+                       if (hcint & DWC2_HCINT_STALL) {
+                               puts("DWC OTG: Channel halted\n");
+                               bulk_data_toggle[devnum][ep] =
+                                       DWC2_HC_PID_DATA0;
+
+                               stop_transfer = 1;
+                               break;
+                       }
+
+                       if (!--timeout) {
+                               printf("%s: Timeout!\n", __func__);
+                               break;
+                       }
+               }
+       }
+
+       if (done && usb_pipein(pipe))
+               memcpy(buffer, aligned_buffer, done);
+
+       writel(0, &hc_regs->hcintmsk);
+       writel(0xFFFFFFFF, &hc_regs->hcint);
+
+       dev->status = 0;
+       dev->act_len = done;
+
+       return 0;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                      int len, struct devrequest *setup)
+{
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
+       int done = 0;
+       int devnum = usb_pipedevice(pipe);
+       int ep = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       uint32_t hctsiz = 0, sub, tmp, ret;
+       uint32_t hcint;
+       const uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP |
+               DWC2_HCINT_CHHLTD | DWC2_HCINT_ACK;
+       unsigned int timeout = 1000000;
+
+       /* For CONTROL endpoint pid should start with DATA1 */
+       int status_direction;
+
+       if (devnum == root_hub_devnum) {
+               dev->status = 0;
+               dev->speed = USB_SPEED_HIGH;
+               return dwc_otg_submit_rh_msg(dev, pipe, buffer, len, setup);
+       }
+
+       if (len > DWC2_DATA_BUF_SIZE) {
+               printf("%s: %d is more then available buffer size(%d)\n",
+                      __func__, len, DWC2_DATA_BUF_SIZE);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       /* Initialize channel, OUT for setup buffer */
+       dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, 0,
+                       DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+       /* SETUP stage  */
+       writel((8 << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+              (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+              (DWC2_HC_PID_SETUP << DWC2_HCTSIZ_PID_OFFSET),
+              &hc_regs->hctsiz);
+
+       writel((uint32_t)setup, &hc_regs->hcdma);
+
+       /* Set host channel enable after all other setup is complete. */
+       clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                       DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                       (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
+
+       ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, 1);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       hcint = readl(&hc_regs->hcint);
+
+       if (!(hcint & DWC2_HCINT_CHHLTD) || !(hcint & DWC2_HCINT_XFERCOMP)) {
+               printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       /* Clear interrupts */
+       writel(0, &hc_regs->hcintmsk);
+       writel(0xFFFFFFFF, &hc_regs->hcint);
+
+       if (buffer) {
+               /* DATA stage */
+               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                               usb_pipein(pipe),
+                               DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+               /* TODO: check if len < 64 */
+               control_data_toggle[devnum][ep] = DWC2_HC_PID_DATA1;
+               writel((len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+                      (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+                      (control_data_toggle[devnum][ep] <<
+                               DWC2_HCTSIZ_PID_OFFSET),
+                      &hc_regs->hctsiz);
+
+               writel((uint32_t)buffer, &hc_regs->hcdma);
+
+               /* Set host channel enable after all other setup is complete */
+               clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                               (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
+                               DWC2_HCCHAR_CHEN);
+
+               while (1) {
+                       hcint = readl(&hc_regs->hcint);
+                       if (!(hcint & DWC2_HCINT_CHHLTD))
+                               continue;
+
+                       if (hcint & DWC2_HCINT_XFERCOMP) {
+                               hctsiz = readl(&hc_regs->hctsiz);
+                               done = len;
+
+                               sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
+                               sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
+
+                               if (usb_pipein(pipe))
+                                       done -= sub;
+                       }
+
+                       if (hcint & DWC2_HCINT_ACK) {
+                               tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
+                               tmp >>= DWC2_HCTSIZ_PID_OFFSET;
+                               if (tmp == DWC2_HC_PID_DATA0) {
+                                       control_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA0;
+                               } else {
+                                       control_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA1;
+                               }
+                       }
+
+                       if (hcint != hcint_comp_hlt_ack) {
+                               printf("%s: Error (HCINT=%08x)\n",
+                                      __func__, hcint);
+                               goto out;
+                       }
+
+                       if (!--timeout) {
+                               printf("%s: Timeout!\n", __func__);
+                               goto out;
+                       }
+
+                       break;
+               }
+       } /* End of DATA stage */
+
+       /* STATUS stage */
+       if ((len == 0) || usb_pipeout(pipe))
+               status_direction = 1;
+       else
+               status_direction = 0;
+
+       dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                       status_direction, DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+       writel((1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+              (DWC2_HC_PID_DATA1 << DWC2_HCTSIZ_PID_OFFSET),
+              &hc_regs->hctsiz);
+
+       writel((uint32_t)status_buffer, &hc_regs->hcdma);
+
+       /* Set host channel enable after all other setup is complete. */
+       clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                       DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                       (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
+
+       while (1) {
+               hcint = readl(&hc_regs->hcint);
+               if (hcint & DWC2_HCINT_CHHLTD)
+                       break;
+       }
+
+       if (hcint != hcint_comp_hlt_ack)
+               printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
+
+out:
+       dev->act_len = done;
+       dev->status = 0;
+
+       return done;
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                  int len, int interval)
+{
+       printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n",
+              dev, pipe, buffer, len, interval);
+       return -ENOSYS;
+}
+
+/* U-Boot USB control interface */
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
+       uint32_t snpsid;
+       int i, j;
+
+       root_hub_devnum = 0;
+
+       snpsid = readl(&regs->gsnpsid);
+       printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff);
+
+       if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx) {
+               printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid);
+               return -ENODEV;
+       }
+
+       dwc_otg_core_init(regs);
+       dwc_otg_core_host_init(regs);
+
+       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                       DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
+                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                       DWC2_HPRT0_PRTRST);
+       mdelay(50);
+       clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET |
+                    DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG |
+                    DWC2_HPRT0_PRTRST);
+
+       for (i = 0; i < MAX_DEVICE; i++) {
+               for (j = 0; j < MAX_ENDPOINT; j++) {
+                       control_data_toggle[i][j] = DWC2_HC_PID_DATA1;
+                       bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0;
+               }
+       }
+
+       return 0;
+}
+
+int usb_lowlevel_stop(int index)
+{
+       /* Put everything in reset. */
+       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                       DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
+                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                       DWC2_HPRT0_PRTRST);
+       return 0;
+}
diff --git a/drivers/usb/host/dwc2.h b/drivers/usb/host/dwc2.h
new file mode 100644 (file)
index 0000000..ba08fd5
--- /dev/null
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __DWC2_H__
+#define __DWC2_H__
+
+struct dwc2_hc_regs {
+       u32                     hcchar;         /* 0x00 */
+       u32                     hcsplt;
+       u32                     hcint;
+       u32                     hcintmsk;
+       u32                     hctsiz;         /* 0x10 */
+       u32                     hcdma;
+       u32                     reserved;
+       u32                     hcdmab;
+};
+
+struct dwc2_host_regs {
+       u32                     hcfg;           /* 0x00 */
+       u32                     hfir;
+       u32                     hfnum;
+       u32                     _pad_0x40c;
+       u32                     hptxsts;        /* 0x10 */
+       u32                     haint;
+       u32                     haintmsk;
+       u32                     hflbaddr;
+};
+
+struct dwc2_core_regs {
+       u32                     gotgctl;        /* 0x000 */
+       u32                     gotgint;
+       u32                     gahbcfg;
+       u32                     gusbcfg;
+       u32                     grstctl;        /* 0x010 */
+       u32                     gintsts;
+       u32                     gintmsk;
+       u32                     grxstsr;
+       u32                     grxstsp;        /* 0x020 */
+       u32                     grxfsiz;
+       u32                     gnptxfsiz;
+       u32                     gnptxsts;
+       u32                     gi2cctl;        /* 0x030 */
+       u32                     gpvndctl;
+       u32                     ggpio;
+       u32                     guid;
+       u32                     gsnpsid;        /* 0x040 */
+       u32                     ghwcfg1;
+       u32                     ghwcfg2;
+       u32                     ghwcfg3;
+       u32                     ghwcfg4;        /* 0x050 */
+       u32                     glpmcfg;
+       u32                     _pad_0x58_0x9c[42];
+       u32                     hptxfsiz;       /* 0x100 */
+       u32                     dptxfsiz_dieptxf[15];
+       u32                     _pad_0x140_0x3fc[176];
+       struct dwc2_host_regs   host_regs;      /* 0x400 */
+       u32                     _pad_0x420_0x43c[8];
+       u32                     hprt0;          /* 0x440 */
+       u32                     _pad_0x444_0x4fc[47];
+       struct dwc2_hc_regs     hc_regs[16];    /* 0x500 */
+       u32                     _pad_0x700_0xe00[448];
+       u32                     pcgcctl;        /* 0xe00 */
+};
+
+#define DWC2_GOTGCTL_SESREQSCS                         (1 << 0)
+#define DWC2_GOTGCTL_SESREQSCS_OFFSET                  0
+#define DWC2_GOTGCTL_SESREQ                            (1 << 1)
+#define DWC2_GOTGCTL_SESREQ_OFFSET                     1
+#define DWC2_GOTGCTL_HSTNEGSCS                         (1 << 8)
+#define DWC2_GOTGCTL_HSTNEGSCS_OFFSET                  8
+#define DWC2_GOTGCTL_HNPREQ                            (1 << 9)
+#define DWC2_GOTGCTL_HNPREQ_OFFSET                     9
+#define DWC2_GOTGCTL_HSTSETHNPEN                       (1 << 10)
+#define DWC2_GOTGCTL_HSTSETHNPEN_OFFSET                        10
+#define DWC2_GOTGCTL_DEVHNPEN                          (1 << 11)
+#define DWC2_GOTGCTL_DEVHNPEN_OFFSET                   11
+#define DWC2_GOTGCTL_CONIDSTS                          (1 << 16)
+#define DWC2_GOTGCTL_CONIDSTS_OFFSET                   16
+#define DWC2_GOTGCTL_DBNCTIME                          (1 << 17)
+#define DWC2_GOTGCTL_DBNCTIME_OFFSET                   17
+#define DWC2_GOTGCTL_ASESVLD                           (1 << 18)
+#define DWC2_GOTGCTL_ASESVLD_OFFSET                    18
+#define DWC2_GOTGCTL_BSESVLD                           (1 << 19)
+#define DWC2_GOTGCTL_BSESVLD_OFFSET                    19
+#define DWC2_GOTGCTL_OTGVER                            (1 << 20)
+#define DWC2_GOTGCTL_OTGVER_OFFSET                     20
+#define DWC2_GOTGINT_SESENDDET                         (1 << 2)
+#define DWC2_GOTGINT_SESENDDET_OFFSET                  2
+#define DWC2_GOTGINT_SESREQSUCSTSCHNG                  (1 << 8)
+#define DWC2_GOTGINT_SESREQSUCSTSCHNG_OFFSET           8
+#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG                  (1 << 9)
+#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG_OFFSET           9
+#define DWC2_GOTGINT_RESERVER10_16_MASK                        (0x7F << 10)
+#define DWC2_GOTGINT_RESERVER10_16_OFFSET              10
+#define DWC2_GOTGINT_HSTNEGDET                         (1 << 17)
+#define DWC2_GOTGINT_HSTNEGDET_OFFSET                  17
+#define DWC2_GOTGINT_ADEVTOUTCHNG                      (1 << 18)
+#define DWC2_GOTGINT_ADEVTOUTCHNG_OFFSET               18
+#define DWC2_GOTGINT_DEBDONE                           (1 << 19)
+#define DWC2_GOTGINT_DEBDONE_OFFSET                    19
+#define DWC2_GAHBCFG_GLBLINTRMSK                       (1 << 0)
+#define DWC2_GAHBCFG_GLBLINTRMSK_OFFSET                        0
+#define DWC2_GAHBCFG_HBURSTLEN_SINGLE                  (0 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR                    (1 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR4                   (3 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR8                   (5 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR16                  (7 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_MASK                    (0xF << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_OFFSET                  1
+#define DWC2_GAHBCFG_DMAENABLE                         (1 << 5)
+#define DWC2_GAHBCFG_DMAENABLE_OFFSET                  5
+#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL             (1 << 7)
+#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL_OFFSET      7
+#define DWC2_GAHBCFG_PTXFEMPLVL                                (1 << 8)
+#define DWC2_GAHBCFG_PTXFEMPLVL_OFFSET                 8
+#define DWC2_GUSBCFG_TOUTCAL_MASK                      (0x7 << 0)
+#define DWC2_GUSBCFG_TOUTCAL_OFFSET                    0
+#define DWC2_GUSBCFG_PHYIF                             (1 << 3)
+#define DWC2_GUSBCFG_PHYIF_OFFSET                      3
+#define DWC2_GUSBCFG_ULPI_UTMI_SEL                     (1 << 4)
+#define DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET              4
+#define DWC2_GUSBCFG_FSINTF                            (1 << 5)
+#define DWC2_GUSBCFG_FSINTF_OFFSET                     5
+#define DWC2_GUSBCFG_PHYSEL                            (1 << 6)
+#define DWC2_GUSBCFG_PHYSEL_OFFSET                     6
+#define DWC2_GUSBCFG_DDRSEL                            (1 << 7)
+#define DWC2_GUSBCFG_DDRSEL_OFFSET                     7
+#define DWC2_GUSBCFG_SRPCAP                            (1 << 8)
+#define DWC2_GUSBCFG_SRPCAP_OFFSET                     8
+#define DWC2_GUSBCFG_HNPCAP                            (1 << 9)
+#define DWC2_GUSBCFG_HNPCAP_OFFSET                     9
+#define DWC2_GUSBCFG_USBTRDTIM_MASK                    (0xF << 10)
+#define DWC2_GUSBCFG_USBTRDTIM_OFFSET                  10
+#define DWC2_GUSBCFG_NPTXFRWNDEN                       (1 << 14)
+#define DWC2_GUSBCFG_NPTXFRWNDEN_OFFSET                        14
+#define DWC2_GUSBCFG_PHYLPWRCLKSEL                     (1 << 15)
+#define DWC2_GUSBCFG_PHYLPWRCLKSEL_OFFSET              15
+#define DWC2_GUSBCFG_OTGUTMIFSSEL                      (1 << 16)
+#define DWC2_GUSBCFG_OTGUTMIFSSEL_OFFSET               16
+#define DWC2_GUSBCFG_ULPI_FSLS                         (1 << 17)
+#define DWC2_GUSBCFG_ULPI_FSLS_OFFSET                  17
+#define DWC2_GUSBCFG_ULPI_AUTO_RES                     (1 << 18)
+#define DWC2_GUSBCFG_ULPI_AUTO_RES_OFFSET              18
+#define DWC2_GUSBCFG_ULPI_CLK_SUS_M                    (1 << 19)
+#define DWC2_GUSBCFG_ULPI_CLK_SUS_M_OFFSET             19
+#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV                 (1 << 20)
+#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV_OFFSET          20
+#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR           (1 << 21)
+#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR_OFFSET    21
+#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE                 (1 << 22)
+#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE_OFFSET          22
+#define DWC2_GUSBCFG_IC_USB_CAP                                (1 << 26)
+#define DWC2_GUSBCFG_IC_USB_CAP_OFFSET                 26
+#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE            (1 << 27)
+#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE_OFFSET     27
+#define DWC2_GUSBCFG_TX_END_DELAY                      (1 << 28)
+#define DWC2_GUSBCFG_TX_END_DELAY_OFFSET               28
+#define DWC2_GUSBCFG_FORCEHOSTMODE                     (1 << 29)
+#define DWC2_GUSBCFG_FORCEHOSTMODE_OFFSET              29
+#define DWC2_GUSBCFG_FORCEDEVMODE                      (1 << 30)
+#define DWC2_GUSBCFG_FORCEDEVMODE_OFFSET               30
+#define DWC2_GLPMCTL_LPM_CAP_EN                                (1 << 0)
+#define DWC2_GLPMCTL_LPM_CAP_EN_OFFSET                 0
+#define DWC2_GLPMCTL_APPL_RESP                         (1 << 1)
+#define DWC2_GLPMCTL_APPL_RESP_OFFSET                  1
+#define DWC2_GLPMCTL_HIRD_MASK                         (0xF << 2)
+#define DWC2_GLPMCTL_HIRD_OFFSET                       2
+#define DWC2_GLPMCTL_REM_WKUP_EN                       (1 << 6)
+#define DWC2_GLPMCTL_REM_WKUP_EN_OFFSET                        6
+#define DWC2_GLPMCTL_EN_UTMI_SLEEP                     (1 << 7)
+#define DWC2_GLPMCTL_EN_UTMI_SLEEP_OFFSET              7
+#define DWC2_GLPMCTL_HIRD_THRES_MASK                   (0x1F << 8)
+#define DWC2_GLPMCTL_HIRD_THRES_OFFSET                 8
+#define DWC2_GLPMCTL_LPM_RESP_MASK                     (0x3 << 13)
+#define DWC2_GLPMCTL_LPM_RESP_OFFSET                   13
+#define DWC2_GLPMCTL_PRT_SLEEP_STS                     (1 << 15)
+#define DWC2_GLPMCTL_PRT_SLEEP_STS_OFFSET              15
+#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK              (1 << 16)
+#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK_OFFSET       16
+#define DWC2_GLPMCTL_LPM_CHAN_INDEX_MASK               (0xF << 17)
+#define DWC2_GLPMCTL_LPM_CHAN_INDEX_OFFSET             17
+#define DWC2_GLPMCTL_RETRY_COUNT_MASK                  (0x7 << 21)
+#define DWC2_GLPMCTL_RETRY_COUNT_OFFSET                        21
+#define DWC2_GLPMCTL_SEND_LPM                          (1 << 24)
+#define DWC2_GLPMCTL_SEND_LPM_OFFSET                   24
+#define DWC2_GLPMCTL_RETRY_COUNT_STS_MASK              (0x7 << 25)
+#define DWC2_GLPMCTL_RETRY_COUNT_STS_OFFSET            25
+#define DWC2_GLPMCTL_HSIC_CONNECT                      (1 << 30)
+#define DWC2_GLPMCTL_HSIC_CONNECT_OFFSET               30
+#define DWC2_GLPMCTL_INV_SEL_HSIC                      (1 << 31)
+#define DWC2_GLPMCTL_INV_SEL_HSIC_OFFSET               31
+#define DWC2_GRSTCTL_CSFTRST                           (1 << 0)
+#define DWC2_GRSTCTL_CSFTRST_OFFSET                    0
+#define DWC2_GRSTCTL_HSFTRST                           (1 << 1)
+#define DWC2_GRSTCTL_HSFTRST_OFFSET                    1
+#define DWC2_GRSTCTL_HSTFRM                            (1 << 2)
+#define DWC2_GRSTCTL_HSTFRM_OFFSET                     2
+#define DWC2_GRSTCTL_INTKNQFLSH                                (1 << 3)
+#define DWC2_GRSTCTL_INTKNQFLSH_OFFSET                 3
+#define DWC2_GRSTCTL_RXFFLSH                           (1 << 4)
+#define DWC2_GRSTCTL_RXFFLSH_OFFSET                    4
+#define DWC2_GRSTCTL_TXFFLSH                           (1 << 5)
+#define DWC2_GRSTCTL_TXFFLSH_OFFSET                    5
+#define DWC2_GRSTCTL_TXFNUM_MASK                       (0x1F << 6)
+#define DWC2_GRSTCTL_TXFNUM_OFFSET                     6
+#define DWC2_GRSTCTL_DMAREQ                            (1 << 30)
+#define DWC2_GRSTCTL_DMAREQ_OFFSET                     30
+#define DWC2_GRSTCTL_AHBIDLE                           (1 << 31)
+#define DWC2_GRSTCTL_AHBIDLE_OFFSET                    31
+#define DWC2_GINTMSK_MODEMISMATCH                      (1 << 1)
+#define DWC2_GINTMSK_MODEMISMATCH_OFFSET               1
+#define DWC2_GINTMSK_OTGINTR                           (1 << 2)
+#define DWC2_GINTMSK_OTGINTR_OFFSET                    2
+#define DWC2_GINTMSK_SOFINTR                           (1 << 3)
+#define DWC2_GINTMSK_SOFINTR_OFFSET                    3
+#define DWC2_GINTMSK_RXSTSQLVL                         (1 << 4)
+#define DWC2_GINTMSK_RXSTSQLVL_OFFSET                  4
+#define DWC2_GINTMSK_NPTXFEMPTY                                (1 << 5)
+#define DWC2_GINTMSK_NPTXFEMPTY_OFFSET                 5
+#define DWC2_GINTMSK_GINNAKEFF                         (1 << 6)
+#define DWC2_GINTMSK_GINNAKEFF_OFFSET                  6
+#define DWC2_GINTMSK_GOUTNAKEFF                                (1 << 7)
+#define DWC2_GINTMSK_GOUTNAKEFF_OFFSET                 7
+#define DWC2_GINTMSK_I2CINTR                           (1 << 9)
+#define DWC2_GINTMSK_I2CINTR_OFFSET                    9
+#define DWC2_GINTMSK_ERLYSUSPEND                       (1 << 10)
+#define DWC2_GINTMSK_ERLYSUSPEND_OFFSET                        10
+#define DWC2_GINTMSK_USBSUSPEND                                (1 << 11)
+#define DWC2_GINTMSK_USBSUSPEND_OFFSET                 11
+#define DWC2_GINTMSK_USBRESET                          (1 << 12)
+#define DWC2_GINTMSK_USBRESET_OFFSET                   12
+#define DWC2_GINTMSK_ENUMDONE                          (1 << 13)
+#define DWC2_GINTMSK_ENUMDONE_OFFSET                   13
+#define DWC2_GINTMSK_ISOOUTDROP                                (1 << 14)
+#define DWC2_GINTMSK_ISOOUTDROP_OFFSET                 14
+#define DWC2_GINTMSK_EOPFRAME                          (1 << 15)
+#define DWC2_GINTMSK_EOPFRAME_OFFSET                   15
+#define DWC2_GINTMSK_EPMISMATCH                                (1 << 17)
+#define DWC2_GINTMSK_EPMISMATCH_OFFSET                 17
+#define DWC2_GINTMSK_INEPINTR                          (1 << 18)
+#define DWC2_GINTMSK_INEPINTR_OFFSET                   18
+#define DWC2_GINTMSK_OUTEPINTR                         (1 << 19)
+#define DWC2_GINTMSK_OUTEPINTR_OFFSET                  19
+#define DWC2_GINTMSK_INCOMPLISOIN                      (1 << 20)
+#define DWC2_GINTMSK_INCOMPLISOIN_OFFSET               20
+#define DWC2_GINTMSK_INCOMPLISOOUT                     (1 << 21)
+#define DWC2_GINTMSK_INCOMPLISOOUT_OFFSET              21
+#define DWC2_GINTMSK_PORTINTR                          (1 << 24)
+#define DWC2_GINTMSK_PORTINTR_OFFSET                   24
+#define DWC2_GINTMSK_HCINTR                            (1 << 25)
+#define DWC2_GINTMSK_HCINTR_OFFSET                     25
+#define DWC2_GINTMSK_PTXFEMPTY                         (1 << 26)
+#define DWC2_GINTMSK_PTXFEMPTY_OFFSET                  26
+#define DWC2_GINTMSK_LPMTRANRCVD                       (1 << 27)
+#define DWC2_GINTMSK_LPMTRANRCVD_OFFSET                        27
+#define DWC2_GINTMSK_CONIDSTSCHNG                      (1 << 28)
+#define DWC2_GINTMSK_CONIDSTSCHNG_OFFSET               28
+#define DWC2_GINTMSK_DISCONNECT                                (1 << 29)
+#define DWC2_GINTMSK_DISCONNECT_OFFSET                 29
+#define DWC2_GINTMSK_SESSREQINTR                       (1 << 30)
+#define DWC2_GINTMSK_SESSREQINTR_OFFSET                        30
+#define DWC2_GINTMSK_WKUPINTR                          (1 << 31)
+#define DWC2_GINTMSK_WKUPINTR_OFFSET                   31
+#define DWC2_GINTSTS_CURMODE_DEVICE                    (0 << 0)
+#define DWC2_GINTSTS_CURMODE_HOST                      (1 << 0)
+#define DWC2_GINTSTS_CURMODE                           (1 << 0)
+#define DWC2_GINTSTS_CURMODE_OFFSET                    0
+#define DWC2_GINTSTS_MODEMISMATCH                      (1 << 1)
+#define DWC2_GINTSTS_MODEMISMATCH_OFFSET               1
+#define DWC2_GINTSTS_OTGINTR                           (1 << 2)
+#define DWC2_GINTSTS_OTGINTR_OFFSET                    2
+#define DWC2_GINTSTS_SOFINTR                           (1 << 3)
+#define DWC2_GINTSTS_SOFINTR_OFFSET                    3
+#define DWC2_GINTSTS_RXSTSQLVL                         (1 << 4)
+#define DWC2_GINTSTS_RXSTSQLVL_OFFSET                  4
+#define DWC2_GINTSTS_NPTXFEMPTY                                (1 << 5)
+#define DWC2_GINTSTS_NPTXFEMPTY_OFFSET                 5
+#define DWC2_GINTSTS_GINNAKEFF                         (1 << 6)
+#define DWC2_GINTSTS_GINNAKEFF_OFFSET                  6
+#define DWC2_GINTSTS_GOUTNAKEFF                                (1 << 7)
+#define DWC2_GINTSTS_GOUTNAKEFF_OFFSET                 7
+#define DWC2_GINTSTS_I2CINTR                           (1 << 9)
+#define DWC2_GINTSTS_I2CINTR_OFFSET                    9
+#define DWC2_GINTSTS_ERLYSUSPEND                       (1 << 10)
+#define DWC2_GINTSTS_ERLYSUSPEND_OFFSET                        10
+#define DWC2_GINTSTS_USBSUSPEND                                (1 << 11)
+#define DWC2_GINTSTS_USBSUSPEND_OFFSET                 11
+#define DWC2_GINTSTS_USBRESET                          (1 << 12)
+#define DWC2_GINTSTS_USBRESET_OFFSET                   12
+#define DWC2_GINTSTS_ENUMDONE                          (1 << 13)
+#define DWC2_GINTSTS_ENUMDONE_OFFSET                   13
+#define DWC2_GINTSTS_ISOOUTDROP                                (1 << 14)
+#define DWC2_GINTSTS_ISOOUTDROP_OFFSET                 14
+#define DWC2_GINTSTS_EOPFRAME                          (1 << 15)
+#define DWC2_GINTSTS_EOPFRAME_OFFSET                   15
+#define DWC2_GINTSTS_INTOKENRX                         (1 << 16)
+#define DWC2_GINTSTS_INTOKENRX_OFFSET                  16
+#define DWC2_GINTSTS_EPMISMATCH                                (1 << 17)
+#define DWC2_GINTSTS_EPMISMATCH_OFFSET                 17
+#define DWC2_GINTSTS_INEPINT                           (1 << 18)
+#define DWC2_GINTSTS_INEPINT_OFFSET                    18
+#define DWC2_GINTSTS_OUTEPINTR                         (1 << 19)
+#define DWC2_GINTSTS_OUTEPINTR_OFFSET                  19
+#define DWC2_GINTSTS_INCOMPLISOIN                      (1 << 20)
+#define DWC2_GINTSTS_INCOMPLISOIN_OFFSET               20
+#define DWC2_GINTSTS_INCOMPLISOOUT                     (1 << 21)
+#define DWC2_GINTSTS_INCOMPLISOOUT_OFFSET              21
+#define DWC2_GINTSTS_PORTINTR                          (1 << 24)
+#define DWC2_GINTSTS_PORTINTR_OFFSET                   24
+#define DWC2_GINTSTS_HCINTR                            (1 << 25)
+#define DWC2_GINTSTS_HCINTR_OFFSET                     25
+#define DWC2_GINTSTS_PTXFEMPTY                         (1 << 26)
+#define DWC2_GINTSTS_PTXFEMPTY_OFFSET                  26
+#define DWC2_GINTSTS_LPMTRANRCVD                       (1 << 27)
+#define DWC2_GINTSTS_LPMTRANRCVD_OFFSET                        27
+#define DWC2_GINTSTS_CONIDSTSCHNG                      (1 << 28)
+#define DWC2_GINTSTS_CONIDSTSCHNG_OFFSET               28
+#define DWC2_GINTSTS_DISCONNECT                                (1 << 29)
+#define DWC2_GINTSTS_DISCONNECT_OFFSET                 29
+#define DWC2_GINTSTS_SESSREQINTR                       (1 << 30)
+#define DWC2_GINTSTS_SESSREQINTR_OFFSET                        30
+#define DWC2_GINTSTS_WKUPINTR                          (1 << 31)
+#define DWC2_GINTSTS_WKUPINTR_OFFSET                   31
+#define DWC2_GRXSTS_EPNUM_MASK                         (0xF << 0)
+#define DWC2_GRXSTS_EPNUM_OFFSET                       0
+#define DWC2_GRXSTS_BCNT_MASK                          (0x7FF << 4)
+#define DWC2_GRXSTS_BCNT_OFFSET                                4
+#define DWC2_GRXSTS_DPID_MASK                          (0x3 << 15)
+#define DWC2_GRXSTS_DPID_OFFSET                                15
+#define DWC2_GRXSTS_PKTSTS_MASK                                (0xF << 17)
+#define DWC2_GRXSTS_PKTSTS_OFFSET                      17
+#define DWC2_GRXSTS_FN_MASK                            (0xF << 21)
+#define DWC2_GRXSTS_FN_OFFSET                          21
+#define DWC2_FIFOSIZE_STARTADDR_MASK                   (0xFFFF << 0)
+#define DWC2_FIFOSIZE_STARTADDR_OFFSET                 0
+#define DWC2_FIFOSIZE_DEPTH_MASK                       (0xFFFF << 16)
+#define DWC2_FIFOSIZE_DEPTH_OFFSET                     16
+#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_MASK               (0xFFFF << 0)
+#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_OFFSET             0
+#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_MASK               (0xFF << 16)
+#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_OFFSET             16
+#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE               (1 << 24)
+#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE_OFFSET                24
+#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_MASK              (0x3 << 25)
+#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_OFFSET            25
+#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_MASK              (0xF << 27)
+#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_OFFSET            27
+#define DWC2_DTXFSTS_TXFSPCAVAIL_MASK                  (0xFFFF << 0)
+#define DWC2_DTXFSTS_TXFSPCAVAIL_OFFSET                        0
+#define DWC2_GI2CCTL_RWDATA_MASK                       (0xFF << 0)
+#define DWC2_GI2CCTL_RWDATA_OFFSET                     0
+#define DWC2_GI2CCTL_REGADDR_MASK                      (0xFF << 8)
+#define DWC2_GI2CCTL_REGADDR_OFFSET                    8
+#define DWC2_GI2CCTL_ADDR_MASK                         (0x7F << 16)
+#define DWC2_GI2CCTL_ADDR_OFFSET                       16
+#define DWC2_GI2CCTL_I2CEN                             (1 << 23)
+#define DWC2_GI2CCTL_I2CEN_OFFSET                      23
+#define DWC2_GI2CCTL_ACK                               (1 << 24)
+#define DWC2_GI2CCTL_ACK_OFFSET                                24
+#define DWC2_GI2CCTL_I2CSUSPCTL                                (1 << 25)
+#define DWC2_GI2CCTL_I2CSUSPCTL_OFFSET                 25
+#define DWC2_GI2CCTL_I2CDEVADDR_MASK                   (0x3 << 26)
+#define DWC2_GI2CCTL_I2CDEVADDR_OFFSET                 26
+#define DWC2_GI2CCTL_RW                                        (1 << 30)
+#define DWC2_GI2CCTL_RW_OFFSET                         30
+#define DWC2_GI2CCTL_BSYDNE                            (1 << 31)
+#define DWC2_GI2CCTL_BSYDNE_OFFSET                     31
+#define DWC2_HWCFG1_EP_DIR0_MASK                       (0x3 << 0)
+#define DWC2_HWCFG1_EP_DIR0_OFFSET                     0
+#define DWC2_HWCFG1_EP_DIR1_MASK                       (0x3 << 2)
+#define DWC2_HWCFG1_EP_DIR1_OFFSET                     2
+#define DWC2_HWCFG1_EP_DIR2_MASK                       (0x3 << 4)
+#define DWC2_HWCFG1_EP_DIR2_OFFSET                     4
+#define DWC2_HWCFG1_EP_DIR3_MASK                       (0x3 << 6)
+#define DWC2_HWCFG1_EP_DIR3_OFFSET                     6
+#define DWC2_HWCFG1_EP_DIR4_MASK                       (0x3 << 8)
+#define DWC2_HWCFG1_EP_DIR4_OFFSET                     8
+#define DWC2_HWCFG1_EP_DIR5_MASK                       (0x3 << 10)
+#define DWC2_HWCFG1_EP_DIR5_OFFSET                     10
+#define DWC2_HWCFG1_EP_DIR6_MASK                       (0x3 << 12)
+#define DWC2_HWCFG1_EP_DIR6_OFFSET                     12
+#define DWC2_HWCFG1_EP_DIR7_MASK                       (0x3 << 14)
+#define DWC2_HWCFG1_EP_DIR7_OFFSET                     14
+#define DWC2_HWCFG1_EP_DIR8_MASK                       (0x3 << 16)
+#define DWC2_HWCFG1_EP_DIR8_OFFSET                     16
+#define DWC2_HWCFG1_EP_DIR9_MASK                       (0x3 << 18)
+#define DWC2_HWCFG1_EP_DIR9_OFFSET                     18
+#define DWC2_HWCFG1_EP_DIR10_MASK                      (0x3 << 20)
+#define DWC2_HWCFG1_EP_DIR10_OFFSET                    20
+#define DWC2_HWCFG1_EP_DIR11_MASK                      (0x3 << 22)
+#define DWC2_HWCFG1_EP_DIR11_OFFSET                    22
+#define DWC2_HWCFG1_EP_DIR12_MASK                      (0x3 << 24)
+#define DWC2_HWCFG1_EP_DIR12_OFFSET                    24
+#define DWC2_HWCFG1_EP_DIR13_MASK                      (0x3 << 26)
+#define DWC2_HWCFG1_EP_DIR13_OFFSET                    26
+#define DWC2_HWCFG1_EP_DIR14_MASK                      (0x3 << 28)
+#define DWC2_HWCFG1_EP_DIR14_OFFSET                    28
+#define DWC2_HWCFG1_EP_DIR15_MASK                      (0x3 << 30)
+#define DWC2_HWCFG1_EP_DIR15_OFFSET                    30
+#define DWC2_HWCFG2_OP_MODE_MASK                       (0x7 << 0)
+#define DWC2_HWCFG2_OP_MODE_OFFSET                     0
+#define DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY            (0x0 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_EXT_DMA               (0x1 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_INT_DMA               (0x2 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_MASK                  (0x3 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_OFFSET                        3
+#define DWC2_HWCFG2_POINT2POINT                                (1 << 5)
+#define DWC2_HWCFG2_POINT2POINT_OFFSET                 5
+#define DWC2_HWCFG2_HS_PHY_TYPE_MASK                   (0x3 << 6)
+#define DWC2_HWCFG2_HS_PHY_TYPE_OFFSET                 6
+#define DWC2_HWCFG2_FS_PHY_TYPE_MASK                   (0x3 << 8)
+#define DWC2_HWCFG2_FS_PHY_TYPE_OFFSET                 8
+#define DWC2_HWCFG2_NUM_DEV_EP_MASK                    (0xF << 10)
+#define DWC2_HWCFG2_NUM_DEV_EP_OFFSET                  10
+#define DWC2_HWCFG2_NUM_HOST_CHAN_MASK                 (0xF << 14)
+#define DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET               14
+#define DWC2_HWCFG2_PERIO_EP_SUPPORTED                 (1 << 18)
+#define DWC2_HWCFG2_PERIO_EP_SUPPORTED_OFFSET          18
+#define DWC2_HWCFG2_DYNAMIC_FIFO                       (1 << 19)
+#define DWC2_HWCFG2_DYNAMIC_FIFO_OFFSET                        19
+#define DWC2_HWCFG2_MULTI_PROC_INT                     (1 << 20)
+#define DWC2_HWCFG2_MULTI_PROC_INT_OFFSET              20
+#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_MASK           (0x3 << 22)
+#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_OFFSET         22
+#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK         (0x3 << 24)
+#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_OFFSET       24
+#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_MASK             (0x1F << 26)
+#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_OFFSET           26
+#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_MASK          (0xF << 0)
+#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_OFFSET                0
+#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK                (0x7 << 4)
+#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_OFFSET      4
+#define DWC2_HWCFG3_OTG_FUNC                           (1 << 7)
+#define DWC2_HWCFG3_OTG_FUNC_OFFSET                    7
+#define DWC2_HWCFG3_I2C                                        (1 << 8)
+#define DWC2_HWCFG3_I2C_OFFSET                         8
+#define DWC2_HWCFG3_VENDOR_CTRL_IF                     (1 << 9)
+#define DWC2_HWCFG3_VENDOR_CTRL_IF_OFFSET              9
+#define DWC2_HWCFG3_OPTIONAL_FEATURES                  (1 << 10)
+#define DWC2_HWCFG3_OPTIONAL_FEATURES_OFFSET           10
+#define DWC2_HWCFG3_SYNCH_RESET_TYPE                   (1 << 11)
+#define DWC2_HWCFG3_SYNCH_RESET_TYPE_OFFSET            11
+#define DWC2_HWCFG3_OTG_ENABLE_IC_USB                  (1 << 12)
+#define DWC2_HWCFG3_OTG_ENABLE_IC_USB_OFFSET           12
+#define DWC2_HWCFG3_OTG_ENABLE_HSIC                    (1 << 13)
+#define DWC2_HWCFG3_OTG_ENABLE_HSIC_OFFSET             13
+#define DWC2_HWCFG3_OTG_LPM_EN                         (1 << 15)
+#define DWC2_HWCFG3_OTG_LPM_EN_OFFSET                  15
+#define DWC2_HWCFG3_DFIFO_DEPTH_MASK                   (0xFFFF << 16)
+#define DWC2_HWCFG3_DFIFO_DEPTH_OFFSET                 16
+#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_MASK           (0xF << 0)
+#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_OFFSET         0
+#define DWC2_HWCFG4_POWER_OPTIMIZ                      (1 << 4)
+#define DWC2_HWCFG4_POWER_OPTIMIZ_OFFSET               4
+#define DWC2_HWCFG4_MIN_AHB_FREQ_MASK                  (0x1FF << 5)
+#define DWC2_HWCFG4_MIN_AHB_FREQ_OFFSET                        5
+#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_MASK           (0x3 << 14)
+#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_OFFSET         14
+#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_MASK          (0xF << 16)
+#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_OFFSET                16
+#define DWC2_HWCFG4_IDDIG_FILT_EN                      (1 << 20)
+#define DWC2_HWCFG4_IDDIG_FILT_EN_OFFSET               20
+#define DWC2_HWCFG4_VBUS_VALID_FILT_EN                 (1 << 21)
+#define DWC2_HWCFG4_VBUS_VALID_FILT_EN_OFFSET          21
+#define DWC2_HWCFG4_A_VALID_FILT_EN                    (1 << 22)
+#define DWC2_HWCFG4_A_VALID_FILT_EN_OFFSET             22
+#define DWC2_HWCFG4_B_VALID_FILT_EN                    (1 << 23)
+#define DWC2_HWCFG4_B_VALID_FILT_EN_OFFSET             23
+#define DWC2_HWCFG4_SESSION_END_FILT_EN                        (1 << 24)
+#define DWC2_HWCFG4_SESSION_END_FILT_EN_OFFSET         24
+#define DWC2_HWCFG4_DED_FIFO_EN                                (1 << 25)
+#define DWC2_HWCFG4_DED_FIFO_EN_OFFSET                 25
+#define DWC2_HWCFG4_NUM_IN_EPS_MASK                    (0xF << 26)
+#define DWC2_HWCFG4_NUM_IN_EPS_OFFSET                  26
+#define DWC2_HWCFG4_DESC_DMA                           (1 << 30)
+#define DWC2_HWCFG4_DESC_DMA_OFFSET                    30
+#define DWC2_HWCFG4_DESC_DMA_DYN                       (1 << 31)
+#define DWC2_HWCFG4_DESC_DMA_DYN_OFFSET                        31
+#define DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ                        0
+#define DWC2_HCFG_FSLSPCLKSEL_48_MHZ                   1
+#define DWC2_HCFG_FSLSPCLKSEL_6_MHZ                    2
+#define DWC2_HCFG_FSLSPCLKSEL_MASK                     (0x3 << 0)
+#define DWC2_HCFG_FSLSPCLKSEL_OFFSET                   0
+#define DWC2_HCFG_FSLSSUPP                             (1 << 2)
+#define DWC2_HCFG_FSLSSUPP_OFFSET                      2
+#define DWC2_HCFG_DESCDMA                              (1 << 23)
+#define DWC2_HCFG_DESCDMA_OFFSET                       23
+#define DWC2_HCFG_FRLISTEN_MASK                                (0x3 << 24)
+#define DWC2_HCFG_FRLISTEN_OFFSET                      24
+#define DWC2_HCFG_PERSCHEDENA                          (1 << 26)
+#define DWC2_HCFG_PERSCHEDENA_OFFSET                   26
+#define DWC2_HCFG_PERSCHEDSTAT                         (1 << 27)
+#define DWC2_HCFG_PERSCHEDSTAT_OFFSET                  27
+#define DWC2_HFIR_FRINT_MASK                           (0xFFFF << 0)
+#define DWC2_HFIR_FRINT_OFFSET                         0
+#define DWC2_HFNUM_FRNUM_MASK                          (0xFFFF << 0)
+#define DWC2_HFNUM_FRNUM_OFFSET                                0
+#define DWC2_HFNUM_FRREM_MASK                          (0xFFFF << 16)
+#define DWC2_HFNUM_FRREM_OFFSET                                16
+#define DWC2_HPTXSTS_PTXFSPCAVAIL_MASK                 (0xFFFF << 0)
+#define DWC2_HPTXSTS_PTXFSPCAVAIL_OFFSET               0
+#define DWC2_HPTXSTS_PTXQSPCAVAIL_MASK                 (0xFF << 16)
+#define DWC2_HPTXSTS_PTXQSPCAVAIL_OFFSET               16
+#define DWC2_HPTXSTS_PTXQTOP_TERMINATE                 (1 << 24)
+#define DWC2_HPTXSTS_PTXQTOP_TERMINATE_OFFSET          24
+#define DWC2_HPTXSTS_PTXQTOP_TOKEN_MASK                        (0x3 << 25)
+#define DWC2_HPTXSTS_PTXQTOP_TOKEN_OFFSET              25
+#define DWC2_HPTXSTS_PTXQTOP_CHNUM_MASK                        (0xF << 27)
+#define DWC2_HPTXSTS_PTXQTOP_CHNUM_OFFSET              27
+#define DWC2_HPTXSTS_PTXQTOP_ODD                       (1 << 31)
+#define DWC2_HPTXSTS_PTXQTOP_ODD_OFFSET                        31
+#define DWC2_HPRT0_PRTCONNSTS                          (1 << 0)
+#define DWC2_HPRT0_PRTCONNSTS_OFFSET                   0
+#define DWC2_HPRT0_PRTCONNDET                          (1 << 1)
+#define DWC2_HPRT0_PRTCONNDET_OFFSET                   1
+#define DWC2_HPRT0_PRTENA                              (1 << 2)
+#define DWC2_HPRT0_PRTENA_OFFSET                       2
+#define DWC2_HPRT0_PRTENCHNG                           (1 << 3)
+#define DWC2_HPRT0_PRTENCHNG_OFFSET                    3
+#define DWC2_HPRT0_PRTOVRCURRACT                       (1 << 4)
+#define DWC2_HPRT0_PRTOVRCURRACT_OFFSET        &n