From 167efe01bc5a9de2aa4f7ce2663dbe398f9d43f6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 22 Oct 2014 21:37:04 -0600 Subject: dm: ns16550: Use an address instead of a pointer for the uart base It is inconvenient to have to use casts when specifying platform data. Also it is not strictly correct, since we should use map_sysmem() to convert an address to a pointer. Adjust the platform data to use an address. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- include/ns16550.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/ns16550.h b/include/ns16550.h index 5784cfd97b8..0607379537d 100644 --- a/include/ns16550.h +++ b/include/ns16550.h @@ -53,7 +53,7 @@ * @clock: UART base clock speed in Hz */ struct ns16550_platdata { - unsigned char *base; + unsigned long base; int reg_shift; int clock; }; -- cgit v1.3.1 From 1a44cd89faec48bc80543ed4cf2afc614863068b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 22 Oct 2014 21:37:14 -0600 Subject: dm: am33xx: Move to driver model for GPIO and serial Adjust the configuration for the am33xx boards, including beaglebone black to use driver model. This can be extended to other OMAP boards once platform data is provided for them. Signed-off-by: Simon Glass Acked-by: Tom Rini --- include/configs/ti_am335x_common.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 80976e7e3b8..5ed86d9365c 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -19,12 +19,23 @@ #define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */ #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC +#ifndef CONFIG_SPL_BUILD +# define CONFIG_DM +# define CONFIG_CMD_DM +# define CONFIG_DM_GPIO +# define CONFIG_DM_SERIAL +# define CONFIG_OMAP_SERIAL +# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) +#endif + #include /* NS16550 Configuration */ #define CONFIG_SYS_NS16550 +#ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) +#endif #define CONFIG_SYS_NS16550_CLK 48000000 /* Network defines. */ -- cgit v1.3.1 From b3f4ca1135edd66d14254089bbeb8077c6d0bb72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 22 Oct 2014 21:37:15 -0600 Subject: dm: omap3: Move to driver model for GPIO and serial Adjust the configuration for the am33xx boards, including beagleboard, to use driver model. Signed-off-by: Simon Glass Acked-by: Tom Rini --- arch/arm/cpu/armv7/omap3/board.c | 26 ++++++++++++++++- board/isee/igep00x0/igep00x0.c | 13 +++++++++ board/logicpd/zoom1/zoom1.c | 13 +++++++++ board/overo/overo.c | 13 +++++++++ board/ti/beagle/beagle.c | 47 +++++++++++++++++++----------- board/ti/beagle/led.c | 61 +++++++++++++++++++-------------------- include/configs/ti_omap3_common.h | 19 ++++++++++-- 7 files changed, 140 insertions(+), 52 deletions(-) (limited to 'include') diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 667e77ff05b..e6996b50f6b 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -17,13 +17,14 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include #include #include #include -#include +#include #include #include #include @@ -38,6 +39,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 +71,8 @@ static const struct gpio_bank gpio_bank_34xx[6] = { const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; +#endif + #ifdef CONFIG_SPL_BUILD /* * We use static variables because global data is not ready yet. diff --git a/board/isee/igep00x0/igep00x0.c b/board/isee/igep00x0/igep00x0.c index 3b2b1f15b8e..7b87cc27c41 100644 --- a/board/isee/igep00x0/igep00x0.c +++ b/board/isee/igep00x0/igep00x0.c @@ -5,6 +5,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #include #include #include @@ -30,6 +32,17 @@ static const u32 gpmc_lan_config[] = { }; #endif +static const struct ns16550_platdata igep_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(igep_uart) = { + "serial_omap", + &igep_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/logicpd/zoom1/zoom1.c b/board/logicpd/zoom1/zoom1.c index 461a852724e..9ef002637a6 100644 --- a/board/logicpd/zoom1/zoom1.c +++ b/board/logicpd/zoom1/zoom1.c @@ -15,6 +15,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #include #include #include @@ -41,6 +43,17 @@ static const u32 gpmc_lab_enet[] = { /*CONF7- computed as params */ }; +static const struct ns16550_platdata zoom1_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(zoom1_uart) = { + "serial_omap", + &zoom1_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/overo/overo.c b/board/overo/overo.c index 13220c56dd0..7506820e349 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -13,6 +13,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #include #include #include @@ -73,6 +75,17 @@ static const u32 gpmc_lan_config[] = { /*CONFIG7- computed as params */ }; +static const struct ns16550_platdata overo_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(overo_uart) = { + "serial_omap", + &overo_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 94b99bf5376..4c5e38136fd 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -14,6 +14,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #ifdef CONFIG_STATUS_LED #include #endif @@ -70,6 +72,17 @@ static struct { char env_setting[64]; } expansion_config; +static const struct ns16550_platdata beagle_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(beagle_uart) = { + "serial_omap", + &beagle_serial +}; + /* * Routine: board_init * Description: Early hardware init. @@ -103,22 +116,22 @@ int board_init(void) */ static int get_board_revision(void) { - int revision; - - if (!gpio_request(171, "") && - !gpio_request(172, "") && - !gpio_request(173, "")) { - - gpio_direction_input(171); - gpio_direction_input(172); - gpio_direction_input(173); - - revision = gpio_get_value(173) << 2 | - gpio_get_value(172) << 1 | - gpio_get_value(171); - } else { - printf("Error: unable to acquire board revision GPIOs\n"); - revision = -1; + static int revision = -1; + + if (revision == -1) { + if (!gpio_request(171, "rev0") && + !gpio_request(172, "rev1") && + !gpio_request(173, "rev2")) { + gpio_direction_input(171); + gpio_direction_input(172); + gpio_direction_input(173); + + revision = gpio_get_value(173) << 2 | + gpio_get_value(172) << 1 | + gpio_get_value(171); + } else { + printf("Error: unable to acquire board revision GPIOs\n"); + } } return revision; @@ -258,7 +271,7 @@ static void beagle_dvi_pup(void) case REVISION_AXBX: case REVISION_CX: case REVISION_C4: - gpio_request(170, ""); + gpio_request(170, "dvi"); gpio_direction_output(170, 0); gpio_set_value(170, 1); break; diff --git a/board/ti/beagle/led.c b/board/ti/beagle/led.c index 89b8dd3c3c1..a913a4c84aa 100644 --- a/board/ti/beagle/led.c +++ b/board/ti/beagle/led.c @@ -27,47 +27,46 @@ void green_led_on(void) } #endif +static int get_led_gpio(led_id_t mask) +{ +#ifdef STATUS_LED_BIT + if (STATUS_LED_BIT & mask) + return BEAGLE_LED_USR0; +#endif +#ifdef STATUS_LED_BIT1 + if (STATUS_LED_BIT1 & mask) + return BEAGLE_LED_USR1; +#endif + + return 0; +} + void __led_init (led_id_t mask, int state) { - __led_set (mask, state); + int toggle_gpio; + + toggle_gpio = get_led_gpio(mask); + + if (toggle_gpio && !gpio_request(toggle_gpio, "led")) + __led_set(mask, state); } void __led_toggle (led_id_t mask) { - int state, toggle_gpio = 0; -#ifdef STATUS_LED_BIT - if (!toggle_gpio && STATUS_LED_BIT & mask) - toggle_gpio = BEAGLE_LED_USR0; -#endif -#ifdef STATUS_LED_BIT1 - if (!toggle_gpio && STATUS_LED_BIT1 & mask) - toggle_gpio = BEAGLE_LED_USR1; -#endif + int state, toggle_gpio; + + toggle_gpio = get_led_gpio(mask); if (toggle_gpio) { - if (!gpio_request(toggle_gpio, "")) { - gpio_direction_output(toggle_gpio, 0); - state = gpio_get_value(toggle_gpio); - gpio_set_value(toggle_gpio, !state); - } + state = gpio_get_value(toggle_gpio); + gpio_direction_output(toggle_gpio, !state); } } void __led_set (led_id_t mask, int state) { -#ifdef STATUS_LED_BIT - if (STATUS_LED_BIT & mask) { - if (!gpio_request(BEAGLE_LED_USR0, "")) { - gpio_direction_output(BEAGLE_LED_USR0, 0); - gpio_set_value(BEAGLE_LED_USR0, state); - } - } -#endif -#ifdef STATUS_LED_BIT1 - if (STATUS_LED_BIT1 & mask) { - if (!gpio_request(BEAGLE_LED_USR1, "")) { - gpio_direction_output(BEAGLE_LED_USR1, 0); - gpio_set_value(BEAGLE_LED_USR1, state); - } - } -#endif + int toggle_gpio; + + toggle_gpio = get_led_gpio(mask); + if (toggle_gpio) + gpio_direction_output(toggle_gpio, state); } diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h index 3b19d3d6baf..3c634ee680d 100644 --- a/include/configs/ti_omap3_common.h +++ b/include/configs/ti_omap3_common.h @@ -18,6 +18,15 @@ #include #include +#ifndef CONFIG_SPL_BUILD +# define CONFIG_DM +# define CONFIG_CMD_DM +# define CONFIG_DM_GPIO +# define CONFIG_DM_SERIAL +# define CONFIG_OMAP_SERIAL +# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) +#endif + /* The chip has SDRC controller */ #define CONFIG_SDRC @@ -28,16 +37,20 @@ /* NS16550 Configuration */ #define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ #define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE (-4) -#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK +#ifdef CONFIG_SPL_BUILD +# define CONFIG_SYS_NS16550_SERIAL +# define CONFIG_SYS_NS16550_REG_SIZE (-4) +# define CONFIG_SYS_NS16550_CLK V_NS16550_CLK +#endif #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \ 115200} /* Select serial console configuration */ #define CONFIG_CONS_INDEX 3 +#ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 #define CONFIG_SERIAL3 3 +#endif /* Physical Memory Map */ #define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 -- cgit v1.3.1 From b892d127ffd448e8adf21e9703c0c5107e2a7814 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:42 -0600 Subject: dm: gpio: Implement GPIO reservation in the uclass We have several GPIO drivers now and all are doing similar things to record which GPIOs are reserved. Move this logic into the uclass to make the drivers similar. We retain the request()/free() methods since currently one driver does use these for setting up the pin. Signed-off-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 92 +++++++++++++++++++++++++++++++++++++++------- include/asm-generic/gpio.h | 6 +++ 2 files changed, 84 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index a5ffd85c42f..e11c5a69c58 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -92,24 +93,41 @@ 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 gpio_get_ops(dev)->request(dev, offset, label); + return 0; } /** @@ -122,6 +140,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; @@ -130,9 +149,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; } /** @@ -152,8 +196,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); } /** @@ -174,8 +219,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); } /** @@ -196,8 +243,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); } /** @@ -218,8 +266,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) @@ -235,7 +284,7 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) } /* 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; @@ -250,7 +299,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; @@ -262,12 +311,27 @@ static int gpio_renumber(void) static int gpio_post_probe(struct udevice *dev) { - return gpio_renumber(); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + + uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *)); + if (!uc_priv->name) + return -ENOMEM; + + return gpio_renumber(NULL); } static int gpio_pre_remove(struct udevice *dev) { - return gpio_renumber(); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + int i; + + for (i = 0; i < uc_priv->gpio_count; i++) { + if (uc_priv->name[i]) + free(uc_priv->name[i]); + } + free(uc_priv->name); + + return gpio_renumber(dev); } UCLASS_DRIVER(gpio) = { diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 1ebb9c724d5..128249ef890 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -29,6 +29,9 @@ * Request a GPIO. This should be called before any of the other functions * are used on this GPIO. * + * Note: With driver model, the label is allocated so there is no need for + * the caller to preserve it. + * * @param gp GPIO number * @param label User label for this GPIO * @return 0 if ok, -1 on error @@ -157,11 +160,14 @@ struct dm_gpio_ops { * @gpio_base: Base GPIO number for this device. For the first active device * this will be 0; the numbering for others will follow sequentially so that * @gpio_base for device 1 will equal the number of GPIOs in device 0. + * @name: Array of pointers to the name for each GPIO in this bank. The + * value of the pointer will be NULL if the GPIO has not been claimed. */ struct gpio_dev_priv { const char *bank_name; unsigned gpio_count; unsigned gpio_base; + char **name; }; /* Access the GPIO operations for a device */ -- cgit v1.3.1 From 6449a506d67b0374bf23a3833f15afa0c92a7a0e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:43 -0600 Subject: dm: gpio: Add gpio_get_function() and friends Add helpers to the uclass to allow finding out the pin function. Signed-off-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ include/asm-generic/gpio.h | 34 ++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index e11c5a69c58..04b7b16fd6b 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -283,6 +283,53 @@ 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); +} + /* We need to renumber the GPIOs when any driver is probed/removed */ static int gpio_renumber(struct udevice *removed_dev) { diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 128249ef890..71044549ba4 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -83,7 +83,7 @@ int gpio_get_value(unsigned gpio); int gpio_set_value(unsigned gpio, int value); /* State of a GPIO, as reported by get_function() */ -enum { +enum gpio_func_t { GPIOF_INPUT = 0, GPIOF_OUTPUT, GPIOF_UNUSED, /* Not claimed */ @@ -95,6 +95,38 @@ enum { struct udevice; +/** + * gpio_get_function() - get the current function for a GPIO pin + * + * Note this returns GPIOF_UNUSED if the GPIO is not requested. + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @namep: If non-NULL, this is set to the nane given when the GPIO + * was requested, or -1 if it has not been requested + * @return -ENODATA if the driver returned an unknown function, + * -ENODEV if the device is not active, -EINVAL if the offset is invalid. + * GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the + * function from enum gpio_func_t. + */ +int gpio_get_function(struct udevice *dev, int offset, const char **namep); + +/** + * gpio_get_raw_function() - get the current raw function for a GPIO pin + * + * Note this does not return GPIOF_UNUSED - it will always return the GPIO + * driver's view of a pin function, even if it is not correctly set up. + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @namep: If non-NULL, this is set to the nane given when the GPIO + * was requested, or -1 if it has not been requested + * @return -ENODATA if the driver returned an unknown function, + * -ENODEV if the device is not active, -EINVAL if the offset is invalid. + * Otherwise returns the function from enum gpio_func_t. + */ +int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep); + /** * struct struct dm_gpio_ops - Driver model GPIO operations * -- cgit v1.3.1 From 0757535a7eee3ae5603520fe4a0588a01a590ea7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:44 -0600 Subject: dm: Move the function for getting GPIO status into the uclass This function can be more easily tested if it is in the uclass. Signed-off-by: Simon Glass --- common/cmd_gpio.c | 57 +++++++++++++++++----------------------------- drivers/gpio/gpio-uclass.c | 39 +++++++++++++++++++++++++++++++ include/asm-generic/gpio.h | 18 +++++++++++++++ 3 files changed, 78 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 11f4e4031da..c0cdc5f6fdf 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -25,13 +25,6 @@ enum gpio_cmd { }; #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) -static const char * const gpio_function[GPIOF_COUNT] = { - "input", - "output", - "unused", - "unknown", - "func", -}; /* A few flags used by show_gpio() */ enum { @@ -40,22 +33,16 @@ enum { FLAG_SHOW_NEWLINE = 1 << 2, }; -static void show_gpio(struct udevice *dev, const char *bank_name, int offset, - int *flagsp) +static void gpio_get_description(struct udevice *dev, const char *bank_name, + int offset, int *flagsp) { - struct dm_gpio_ops *ops = gpio_get_ops(dev); - int func = GPIOF_UNKNOWN; char buf[80]; int ret; - BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); - - if (ops->get_function) { - ret = ops->get_function(dev, offset); - if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) - func = ret; - } - if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED) + ret = gpio_get_function(dev, offset, NULL); + if (ret < 0) + goto err; + if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED) return; if ((*flagsp & FLAG_SHOW_BANK) && bank_name) { if (*flagsp & FLAG_SHOW_NEWLINE) { @@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset, printf("Bank %s:\n", bank_name); *flagsp &= ~FLAG_SHOW_BANK; } - *buf = '\0'; - if (ops->get_state) { - ret = ops->get_state(dev, offset, buf, sizeof(buf)); - if (ret) { - puts(""); - return; - } - } else { - sprintf(buf, "%s%u: %8s %d", bank_name, offset, - gpio_function[func], ops->get_value(dev, offset)); - } - puts(buf); - puts("\n"); + ret = gpio_get_status(dev, offset, buf, sizeof(buf)); + if (ret) + goto err; + + printf("%s\n", buf); + return; +err: + printf("Error %d\n", ret); } static int do_gpio_status(bool all, const char *gpio_name) @@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name) if (all) flags |= FLAG_SHOW_ALL; bank_name = gpio_get_bank_info(dev, &num_bits); - if (!num_bits) + if (!num_bits) { + debug("GPIO device %s has no bits\n", dev->name); continue; + } banklen = bank_name ? strlen(bank_name) : 0; if (!gpio_name || !bank_name || @@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name) p = gpio_name + banklen; if (gpio_name && *p) { offset = simple_strtoul(p, NULL, 10); - show_gpio(dev, bank_name, offset, &flags); + gpio_get_description(dev, bank_name, offset, + &flags); } else { for (offset = 0; offset < num_bits; offset++) { - show_gpio(dev, bank_name, offset, - &flags); + gpio_get_description(dev, bank_name, + offset, &flags); } } } diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 04b7b16fd6b..63670932109 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -330,6 +330,45 @@ 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(struct udevice *removed_dev) { diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 71044549ba4..693bb56f77e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -95,6 +95,24 @@ enum gpio_func_t { struct udevice; +/** + * gpio_get_status() - get the current GPIO status as a string + * + * Obtain the current GPIO status as a string which can be presented to the + * user. A typical string is: + * + * "b4: in: 1 [x] sdmmc_cd" + * + * which means this is GPIO bank b, offset 4, currently set to input, current + * value 1, [x] means that it is requested and the owner is 'sdmmc_cd' + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @buf: Place to put string + * @buffsize: Size of string including \0 + */ +int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize); + /** * gpio_get_function() - get the current function for a GPIO pin * -- cgit v1.3.1 From d44f597b12b8f8099c3c52c3eb09540966cafe79 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:49 -0600 Subject: dm: gpio: Add gpio_requestf() helper for printf() strings Add a helper which permits a printf()-style format string for the requester string. Signed-off-by: Simon Glass --- doc/driver-model/README.txt | 3 ++- drivers/gpio/gpio-uclass.c | 21 +++++++++++++++++++++ include/asm-generic/gpio.h | 10 ++++++++++ test/dm/gpio.c | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index 1ff454aeb4b..f4395c188af 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -95,7 +95,7 @@ are provided in test/dm. To run them, try: You should see something like this: <...U-Boot banner...> - Running 26 driver model tests + Running 27 driver model tests Test: dm_test_autobind Test: dm_test_autoprobe Test: dm_test_bus_children @@ -117,6 +117,7 @@ You should see something like this: Test: dm_test_gpio extra-gpios: get_value: error: gpio b5 not reserved Test: dm_test_gpio_anon + Test: dm_test_gpio_requestf Test: dm_test_leak Test: dm_test_lifecycle Test: dm_test_operations diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 63670932109..45e9a5ad227 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -130,6 +130,27 @@ int gpio_request(unsigned gpio, const char *label) 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]; + + va_start(args, fmt); + vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + return gpio_request(gpio, buf); +} + /** * gpio_free() - [COMPAT] Relinquish GPIO * gpio: GPIO number diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 693bb56f77e..8af760e7770 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -145,6 +145,16 @@ int gpio_get_function(struct udevice *dev, int offset, const char **namep); */ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep); +/** + * gpio_requestf() - request a GPIO using a format string for the owner + * + * This is a helper function for gpio_request(). It allows you to provide + * a printf()-format string for the GPIO owner. It calls gpio_request() with + * the string that is created + */ +int gpio_requestf(unsigned gpio, const char *fmt, ...) + __attribute__ ((format (__printf__, 2, 3))); + /** * struct struct dm_gpio_ops - Driver model GPIO operations * diff --git a/test/dm/gpio.c b/test/dm/gpio.c index ad56ca5fabd..5174cede247 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -120,3 +120,21 @@ static int dm_test_gpio_anon(struct dm_test_state *dms) return 0; } DM_TEST(dm_test_gpio_anon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that gpio_requestf() works as expected */ +static int dm_test_gpio_requestf(struct dm_test_state *dms) +{ + unsigned int offset, gpio; + struct udevice *dev; + char buf[80]; + + ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); + ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi")); + sandbox_gpio_set_direction(dev, offset, 1); + sandbox_gpio_set_value(dev, offset, 1); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf); + + return 0; +} +DM_TEST(dm_test_gpio_requestf, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From 756ac0bb1526c8c661ad3ff673cd17c7602ab46e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:50 -0600 Subject: test: dm: Support memory leak checking as a core feature Check the state of the malloc() heap before each test is run, so that tests can verify that all is well at the end. Provide helper functions to mark the heap and to check that it returns to its initial state. Signed-off-by: Simon Glass --- include/dm/test.h | 23 +++++++++++++++++++++++ test/dm/core.c | 46 ++++++++++++++++++++++++++++++---------------- test/dm/test-main.c | 2 ++ 3 files changed, 55 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/dm/test.h b/include/dm/test.h index 235d728bfbe..f08c05da814 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -8,6 +8,7 @@ #define __DM_TEST_H #include +#include /** * struct dm_test_cdata - configuration data for test instance @@ -120,6 +121,7 @@ struct dm_test_state { int force_fail_alloc; int skip_post_probe; struct udevice *removed; + struct mallinfo start; }; /* Test flags for each test */ @@ -177,6 +179,27 @@ int dm_check_operations(struct dm_test_state *dms, struct udevice *dev, */ int dm_check_devices(struct dm_test_state *dms, int num_devices); +/** + * dm_leak_check_start() - Prepare to check for a memory leak + * + * Call this before allocating memory to record the amount of memory being + * used. + * + * @dms: Overall test state + */ +void dm_leak_check_start(struct dm_test_state *dms); + +/** + * dm_leak_check_end() - Check that no memory has leaked + * + * Call this after dm_leak_check_start() and after you have hopefuilly freed + * all the memory that was allocated. This function will print an error if + * it sees a different amount of total memory allocated than before. + * + * @dms: Overall test state + */int dm_leak_check_end(struct dm_test_state *dms); + + /** * dm_test_main() - Run all the tests * diff --git a/test/dm/core.c b/test/dm/core.c index b0cfb42c85f..ff5c2a749c5 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -67,6 +67,34 @@ static struct driver_info driver_info_pre_reloc = { .platdata = &test_pdata_manual, }; +void dm_leak_check_start(struct dm_test_state *dms) +{ + dms->start = mallinfo(); + if (!dms->start.uordblks) + puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); +} + +int dm_leak_check_end(struct dm_test_state *dms) +{ + struct mallinfo end; + int id; + + /* Don't delete the root class, since we started with that */ + for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { + struct uclass *uc; + + uc = uclass_find(id); + if (!uc) + continue; + ut_assertok(uclass_destroy(uc)); + } + + end = mallinfo(); + ut_asserteq(dms->start.uordblks, end.uordblks); + + return 0; +} + /* Test that binding with platdata occurs correctly */ static int dm_test_autobind(struct dm_test_state *dms) { @@ -377,14 +405,11 @@ static int dm_test_leak(struct dm_test_state *dms) int i; for (i = 0; i < 2; i++) { - struct mallinfo start, end; struct udevice *dev; int ret; int id; - start = mallinfo(); - if (!start.uordblks) - puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); + dm_leak_check_start(dms); ut_assertok(dm_scan_platdata(false)); ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); @@ -398,18 +423,7 @@ static int dm_test_leak(struct dm_test_state *dms) ut_assertok(ret); } - /* Don't delete the root class, since we started with that */ - for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { - struct uclass *uc; - - uc = uclass_find(id); - if (!uc) - continue; - ut_assertok(uclass_destroy(uc)); - } - - end = mallinfo(); - ut_asserteq(start.uordblks, end.uordblks); + ut_assertok(dm_leak_check_end(dms)); } return 0; diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 94ce72abfd5..90ca81092f7 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ int dm_test_main(void) printf("Test: %s\n", test->name); ut_assertok(dm_test_init(dms)); + dms->start = mallinfo(); if (test->flags & DM_TESTF_SCAN_PDATA) ut_assertok(dm_scan_platdata(false)); if (test->flags & DM_TESTF_PROBE_TEST) -- cgit v1.3.1 From 2d91a9772c71e7f7c09fa4f6db2c3d11e6af8176 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 23 Oct 2014 13:15:58 -0600 Subject: dm: dts: Move omap device tree includes to correct place These ended up in arch/arm/dts/dt-bindings temporarily, but in fact the correct place is now include/dt-bindings. Move them to be consistent. Signed-off-by: Simon Glass --- arch/arm/dts/dt-bindings/gpio/gpio.h | 15 --------- arch/arm/dts/dt-bindings/pinctrl/am33xx.h | 42 ----------------------- arch/arm/dts/dt-bindings/pinctrl/omap.h | 55 ------------------------------- include/dt-bindings/pinctrl/am33xx.h | 42 +++++++++++++++++++++++ include/dt-bindings/pinctrl/omap.h | 55 +++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 112 deletions(-) delete mode 100644 arch/arm/dts/dt-bindings/gpio/gpio.h delete mode 100644 arch/arm/dts/dt-bindings/pinctrl/am33xx.h delete mode 100644 arch/arm/dts/dt-bindings/pinctrl/omap.h create mode 100644 include/dt-bindings/pinctrl/am33xx.h create mode 100644 include/dt-bindings/pinctrl/omap.h (limited to 'include') diff --git a/arch/arm/dts/dt-bindings/gpio/gpio.h b/arch/arm/dts/dt-bindings/gpio/gpio.h deleted file mode 100644 index e6b1e0a808a..00000000000 --- a/arch/arm/dts/dt-bindings/gpio/gpio.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This header provides constants for most GPIO bindings. - * - * Most GPIO bindings include a flags cell as part of the GPIO specifier. - * In most cases, the format of the flags cell uses the standard values - * defined in this header. - */ - -#ifndef _DT_BINDINGS_GPIO_GPIO_H -#define _DT_BINDINGS_GPIO_GPIO_H - -#define GPIO_ACTIVE_HIGH 0 -#define GPIO_ACTIVE_LOW 1 - -#endif diff --git a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h b/arch/arm/dts/dt-bindings/pinctrl/am33xx.h deleted file mode 100644 index 2fbc804e1a4..00000000000 --- a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This header provides constants specific to AM33XX pinctrl bindings. - */ - -#ifndef _DT_BINDINGS_PINCTRL_AM33XX_H -#define _DT_BINDINGS_PINCTRL_AM33XX_H - -#include - -/* am33xx specific mux bit defines */ -#undef PULL_ENA -#undef INPUT_EN - -#define PULL_DISABLE (1 << 3) -#define INPUT_EN (1 << 5) -#define SLEWCTRL_FAST (1 << 6) - -/* update macro depending on INPUT_EN and PULL_ENA */ -#undef PIN_OUTPUT -#undef PIN_OUTPUT_PULLUP -#undef PIN_OUTPUT_PULLDOWN -#undef PIN_INPUT -#undef PIN_INPUT_PULLUP -#undef PIN_INPUT_PULLDOWN - -#define PIN_OUTPUT (PULL_DISABLE) -#define PIN_OUTPUT_PULLUP (PULL_UP) -#define PIN_OUTPUT_PULLDOWN 0 -#define PIN_INPUT (INPUT_EN | PULL_DISABLE) -#define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) -#define PIN_INPUT_PULLDOWN (INPUT_EN) - -/* undef non-existing modes */ -#undef PIN_OFF_NONE -#undef PIN_OFF_OUTPUT_HIGH -#undef PIN_OFF_OUTPUT_LOW -#undef PIN_OFF_INPUT_PULLUP -#undef PIN_OFF_INPUT_PULLDOWN -#undef PIN_OFF_WAKEUPENABLE - -#endif - diff --git a/arch/arm/dts/dt-bindings/pinctrl/omap.h b/arch/arm/dts/dt-bindings/pinctrl/omap.h deleted file mode 100644 index edbd250809c..00000000000 --- a/arch/arm/dts/dt-bindings/pinctrl/omap.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This header provides constants for OMAP pinctrl bindings. - * - * Copyright (C) 2009 Nokia - * Copyright (C) 2009-2010 Texas Instruments - */ - -#ifndef _DT_BINDINGS_PINCTRL_OMAP_H -#define _DT_BINDINGS_PINCTRL_OMAP_H - -/* 34xx mux mode options for each pin. See TRM for options */ -#define MUX_MODE0 0 -#define MUX_MODE1 1 -#define MUX_MODE2 2 -#define MUX_MODE3 3 -#define MUX_MODE4 4 -#define MUX_MODE5 5 -#define MUX_MODE6 6 -#define MUX_MODE7 7 - -/* 24xx/34xx mux bit defines */ -#define PULL_ENA (1 << 3) -#define PULL_UP (1 << 4) -#define ALTELECTRICALSEL (1 << 5) - -/* 34xx specific mux bit defines */ -#define INPUT_EN (1 << 8) -#define OFF_EN (1 << 9) -#define OFFOUT_EN (1 << 10) -#define OFFOUT_VAL (1 << 11) -#define OFF_PULL_EN (1 << 12) -#define OFF_PULL_UP (1 << 13) -#define WAKEUP_EN (1 << 14) - -/* 44xx specific mux bit defines */ -#define WAKEUP_EVENT (1 << 15) - -/* Active pin states */ -#define PIN_OUTPUT 0 -#define PIN_OUTPUT_PULLUP (PIN_OUTPUT | PULL_ENA | PULL_UP) -#define PIN_OUTPUT_PULLDOWN (PIN_OUTPUT | PULL_ENA) -#define PIN_INPUT INPUT_EN -#define PIN_INPUT_PULLUP (PULL_ENA | INPUT_EN | PULL_UP) -#define PIN_INPUT_PULLDOWN (PULL_ENA | INPUT_EN) - -/* Off mode states */ -#define PIN_OFF_NONE 0 -#define PIN_OFF_OUTPUT_HIGH (OFF_EN | OFFOUT_EN | OFFOUT_VAL) -#define PIN_OFF_OUTPUT_LOW (OFF_EN | OFFOUT_EN) -#define PIN_OFF_INPUT_PULLUP (OFF_EN | OFF_PULL_EN | OFF_PULL_UP) -#define PIN_OFF_INPUT_PULLDOWN (OFF_EN | OFF_PULL_EN) -#define PIN_OFF_WAKEUPENABLE WAKEUP_EN - -#endif - diff --git a/include/dt-bindings/pinctrl/am33xx.h b/include/dt-bindings/pinctrl/am33xx.h new file mode 100644 index 00000000000..2fbc804e1a4 --- /dev/null +++ b/include/dt-bindings/pinctrl/am33xx.h @@ -0,0 +1,42 @@ +/* + * This header provides constants specific to AM33XX pinctrl bindings. + */ + +#ifndef _DT_BINDINGS_PINCTRL_AM33XX_H +#define _DT_BINDINGS_PINCTRL_AM33XX_H + +#include + +/* am33xx specific mux bit defines */ +#undef PULL_ENA +#undef INPUT_EN + +#define PULL_DISABLE (1 << 3) +#define INPUT_EN (1 << 5) +#define SLEWCTRL_FAST (1 << 6) + +/* update macro depending on INPUT_EN and PULL_ENA */ +#undef PIN_OUTPUT +#undef PIN_OUTPUT_PULLUP +#undef PIN_OUTPUT_PULLDOWN +#undef PIN_INPUT +#undef PIN_INPUT_PULLUP +#undef PIN_INPUT_PULLDOWN + +#define PIN_OUTPUT (PULL_DISABLE) +#define PIN_OUTPUT_PULLUP (PULL_UP) +#define PIN_OUTPUT_PULLDOWN 0 +#define PIN_INPUT (INPUT_EN | PULL_DISABLE) +#define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) +#define PIN_INPUT_PULLDOWN (INPUT_EN) + +/* undef non-existing modes */ +#undef PIN_OFF_NONE +#undef PIN_OFF_OUTPUT_HIGH +#undef PIN_OFF_OUTPUT_LOW +#undef PIN_OFF_INPUT_PULLUP +#undef PIN_OFF_INPUT_PULLDOWN +#undef PIN_OFF_WAKEUPENABLE + +#endif + diff --git a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h new file mode 100644 index 00000000000..edbd250809c --- /dev/null +++ b/include/dt-bindings/pinctrl/omap.h @@ -0,0 +1,55 @@ +/* + * This header provides constants for OMAP pinctrl bindings. + * + * Copyright (C) 2009 Nokia + * Copyright (C) 2009-2010 Texas Instruments + */ + +#ifndef _DT_BINDINGS_PINCTRL_OMAP_H +#define _DT_BINDINGS_PINCTRL_OMAP_H + +/* 34xx mux mode options for each pin. See TRM for options */ +#define MUX_MODE0 0 +#define MUX_MODE1 1 +#define MUX_MODE2 2 +#define MUX_MODE3 3 +#define MUX_MODE4 4 +#define MUX_MODE5 5 +#define MUX_MODE6 6 +#define MUX_MODE7 7 + +/* 24xx/34xx mux bit defines */ +#define PULL_ENA (1 << 3) +#define PULL_UP (1 << 4) +#define ALTELECTRICALSEL (1 << 5) + +/* 34xx specific mux bit defines */ +#define INPUT_EN (1 << 8) +#define OFF_EN (1 << 9) +#define OFFOUT_EN (1 << 10) +#define OFFOUT_VAL (1 << 11) +#define OFF_PULL_EN (1 << 12) +#define OFF_PULL_UP (1 << 13) +#define WAKEUP_EN (1 << 14) + +/* 44xx specific mux bit defines */ +#define WAKEUP_EVENT (1 << 15) + +/* Active pin states */ +#define PIN_OUTPUT 0 +#define PIN_OUTPUT_PULLUP (PIN_OUTPUT | PULL_ENA | PULL_UP) +#define PIN_OUTPUT_PULLDOWN (PIN_OUTPUT | PULL_ENA) +#define PIN_INPUT INPUT_EN +#define PIN_INPUT_PULLUP (PULL_ENA | INPUT_EN | PULL_UP) +#define PIN_INPUT_PULLDOWN (PULL_ENA | INPUT_EN) + +/* Off mode states */ +#define PIN_OFF_NONE 0 +#define PIN_OFF_OUTPUT_HIGH (OFF_EN | OFFOUT_EN | OFFOUT_VAL) +#define PIN_OFF_OUTPUT_LOW (OFF_EN | OFFOUT_EN) +#define PIN_OFF_INPUT_PULLUP (OFF_EN | OFF_PULL_EN | OFF_PULL_UP) +#define PIN_OFF_INPUT_PULLDOWN (OFF_EN | OFF_PULL_EN) +#define PIN_OFF_WAKEUPENABLE WAKEUP_EN + +#endif + -- cgit v1.3.1 From 85bfe6e4f6ecb667a8f65698e92bfa9a1a481850 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:57 -0600 Subject: dm: gpio: Remove unused get_state() uclass method This is no longer used so drop it. Signed-off-by: Simon Glass --- include/asm-generic/gpio.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 8af760e7770..4ec411b3728 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -198,8 +198,6 @@ struct dm_gpio_ops { * @return current function - GPIOF_... */ int (*get_function)(struct udevice *dev, unsigned offset); - int (*get_state)(struct udevice *dev, unsigned offset, char *state, - int maxlen); }; /** -- cgit v1.3.1 From 7414112d70727e90be680e77dcb8a31394255ca8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Oct 2014 07:49:18 -0600 Subject: dm: x86: Convert Intel ICH6 GPIO driver to use driver model Convert over this driver, using device tree to pass in the required information. The peripheral is still probed, just the number of GPIO banks and their offsets is in the device tree (previously this was a table in the driver). Signed-off-by: Simon Glass --- drivers/gpio/intel_ich6_gpio.c | 250 ++++++++++++++++++++--------------------- include/configs/coreboot.h | 4 + 2 files changed, 124 insertions(+), 130 deletions(-) (limited to 'include') diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index 7d9fac72337..d3381b0369c 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -27,88 +27,46 @@ */ #include +#include +#include +#include #include #include #include +#define GPIO_PER_BANK 32 + /* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 -#define NUM_BANKS 3 - -/* Within the I/O space, where are the registers to control the GPIOs? */ -static struct { - u8 use_sel; - u8 io_sel; - u8 lvl; -} gpio_bank[NUM_BANKS] = { - { 0x00, 0x04, 0x0c }, /* Bank 0 */ - { 0x30, 0x34, 0x38 }, /* Bank 1 */ - { 0x40, 0x44, 0x48 } /* Bank 2 */ +struct ich6_bank_priv { + /* These are I/O addresses */ + uint32_t use_sel; + uint32_t io_sel; + uint32_t lvl; }; -static pci_dev_t dev; /* handle for 0:1f:0 */ -static u32 gpiobase; /* offset into I/O space */ -static int found_it_once; /* valid GPIO device? */ -static u32 lock[NUM_BANKS]; /* "lock" for access to pins */ - -static int bad_arg(int num, int *bank, int *bitnum) -{ - int i = num / 32; - int j = num % 32; - - if (num < 0 || i > NUM_BANKS) { - debug("%s: bogus gpio num: %d\n", __func__, num); - return -1; - } - *bank = i; - *bitnum = j; - return 0; -} - -static int mark_gpio(int bank, int bitnum) -{ - if (lock[bank] & (1UL << bitnum)) { - debug("%s: %d.%d already marked\n", __func__, bank, bitnum); - return -1; - } - lock[bank] |= (1 << bitnum); - return 0; -} - -static void clear_gpio(int bank, int bitnum) -{ - lock[bank] &= ~(1 << bitnum); -} - -static int notmine(int num, int *bank, int *bitnum) -{ - if (bad_arg(num, bank, bitnum)) - return -1; - return !(lock[*bank] & (1UL << *bitnum)); -} - -static int gpio_init(void) +static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) { + struct ich6_bank_platdata *plat = dev_get_platdata(dev); + pci_dev_t pci_dev; /* handle for 0:1f:0 */ u8 tmpbyte; u16 tmpword; u32 tmplong; - - /* Have we already done this? */ - if (found_it_once) - return 0; + u32 gpiobase; + int offset; /* Where should it be? */ - dev = PCI_BDF(0, 0x1f, 0); + pci_dev = PCI_BDF(0, 0x1f, 0); /* Is the device present? */ - pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword); + pci_read_config_word(pci_dev, PCI_VENDOR_ID, &tmpword); if (tmpword != PCI_VENDOR_ID_INTEL) { debug("%s: wrong VendorID\n", __func__); - return -1; + return -ENODEV; } - pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword); + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &tmpword); debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword); /* * We'd like to validate the Device ID too, but pretty much any @@ -118,37 +76,37 @@ static int gpio_init(void) */ /* I/O should already be enabled (it's a RO bit). */ - pci_read_config_word(dev, PCI_COMMAND, &tmpword); + pci_read_config_word(pci_dev, PCI_COMMAND, &tmpword); if (!(tmpword & PCI_COMMAND_IO)) { debug("%s: device IO not enabled\n", __func__); - return -1; + return -ENODEV; } /* Header Type must be normal (bits 6-0 only; see spec.) */ - pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_HEADER_TYPE, &tmpbyte); if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) { debug("%s: invalid Header type\n", __func__); - return -1; + return -ENODEV; } /* Base Class must be a bridge device */ - pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_CODE, &tmpbyte); if (tmpbyte != PCI_CLASS_CODE_BRIDGE) { debug("%s: invalid class\n", __func__); - return -1; + return -ENODEV; } /* Sub Class must be ISA */ - pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_SUB_CODE, &tmpbyte); if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) { debug("%s: invalid subclass\n", __func__); - return -1; + return -ENODEV; } /* Programming Interface must be 0x00 (no others exist) */ - pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_PROG, &tmpbyte); if (tmpbyte != 0x00) { debug("%s: invalid interface type\n", __func__); - return -1; + return -ENODEV; } /* @@ -156,11 +114,11 @@ static int gpio_init(void) * that it was unused (or undocumented). Check that it looks * okay: not all ones or zeros, and mapped to I/O space (bit 0). */ - pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong); + pci_read_config_dword(pci_dev, PCI_CFG_GPIOBASE, &tmplong); if (tmplong == 0x00000000 || tmplong == 0xffffffff || !(tmplong & 0x00000001)) { debug("%s: unexpected GPIOBASE value\n", __func__); - return -1; + return -ENODEV; } /* @@ -170,105 +128,137 @@ static int gpio_init(void) * an I/O address, not a memory address, so mask that off. */ gpiobase = tmplong & 0xfffffffe; + offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); + if (offset == -1) { + debug("%s: Invalid register offset %d\n", __func__, offset); + return -EINVAL; + } + plat->base_addr = gpiobase + offset; + plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset, + "bank-name", NULL); - /* Finally. These are the droids we're looking for. */ - found_it_once = 1; return 0; } -int gpio_request(unsigned num, const char *label /* UNUSED */) +int ich6_gpio_probe(struct udevice *dev) { - u32 tmplong; - int i = 0, j = 0; + struct ich6_bank_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct ich6_bank_priv *bank = dev_get_priv(dev); + + uc_priv->gpio_count = GPIO_PER_BANK; + uc_priv->bank_name = plat->bank_name; + bank->use_sel = plat->base_addr; + bank->io_sel = plat->base_addr + 4; + bank->lvl = plat->base_addr + 8; - /* Is the hardware ready? */ - if (gpio_init()) - return -1; + return 0; +} - if (bad_arg(num, &i, &j)) - return -1; +int ich6_gpio_request(struct udevice *dev, unsigned offset, const char *label) +{ + struct ich6_bank_priv *bank = dev_get_priv(dev); + u32 tmplong; /* * Make sure that the GPIO pin we want isn't already in use for some * built-in hardware function. We have to check this for every * requested pin. */ - tmplong = inl(gpiobase + gpio_bank[i].use_sel); - if (!(tmplong & (1UL << j))) { + tmplong = inl(bank->use_sel); + if (!(tmplong & (1UL << offset))) { debug("%s: gpio %d is reserved for internal use\n", __func__, - num); - return -1; + offset); + return -EPERM; } - return mark_gpio(i, j); -} - -int gpio_free(unsigned num) -{ - int i = 0, j = 0; - - if (notmine(num, &i, &j)) - return -1; - - clear_gpio(i, j); return 0; } -int gpio_direction_input(unsigned num) +static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - - if (notmine(num, &i, &j)) - return -1; - tmplong = inl(gpiobase + gpio_bank[i].io_sel); - tmplong |= (1UL << j); - outl(gpiobase + gpio_bank[i].io_sel, tmplong); + tmplong = inl(bank->io_sel); + tmplong |= (1UL << offset); + outl(bank->io_sel, tmplong); return 0; } -int gpio_direction_output(unsigned num, int value) +static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].io_sel); - tmplong &= ~(1UL << j); - outl(gpiobase + gpio_bank[i].io_sel, tmplong); + tmplong = inl(bank->io_sel); + tmplong &= ~(1UL << offset); + outl(bank->io_sel, tmplong); return 0; } -int gpio_get_value(unsigned num) +static int ich6_gpio_get_value(struct udevice *dev, unsigned offset) + { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; int r; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].lvl); - r = (tmplong & (1UL << j)) ? 1 : 0; + tmplong = inl(bank->lvl); + r = (tmplong & (1UL << offset)) ? 1 : 0; return r; } -int gpio_set_value(unsigned num, int value) +static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, + int value) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].lvl); + tmplong = inl(bank->lvl); if (value) - tmplong |= (1UL << j); + tmplong |= (1UL << offset); else - tmplong &= ~(1UL << j); - outl(gpiobase + gpio_bank[i].lvl, tmplong); + tmplong &= ~(1UL << offset); + outl(bank->lvl, tmplong); return 0; } + +static int ich6_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct ich6_bank_priv *bank = dev_get_priv(dev); + u32 mask = 1UL << offset; + + if (!(inl(bank->use_sel) & mask)) + return GPIOF_FUNC; + if (inl(bank->io_sel) & mask) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; +} + +static const struct dm_gpio_ops gpio_ich6_ops = { + .request = ich6_gpio_request, + .direction_input = ich6_gpio_direction_input, + .direction_output = ich6_gpio_direction_output, + .get_value = ich6_gpio_get_value, + .set_value = ich6_gpio_set_value, + .get_function = ich6_gpio_get_function, +}; + +static const struct udevice_id intel_ich6_gpio_ids[] = { + { .compatible = "intel,ich6-gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_ich6) = { + .name = "gpio_ich6", + .id = UCLASS_GPIO, + .of_match = intel_ich6_gpio_ids, + .ops = &gpio_ich6_ops, + .ofdata_to_platdata = gpio_ich6_ofdata_to_platdata, + .probe = ich6_gpio_probe, + .priv_auto_alloc_size = sizeof(struct ich6_bank_priv), + .platdata_auto_alloc_size = sizeof(struct ich6_bank_platdata), +}; diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 200b744e4f2..0e85145c249 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -27,6 +27,10 @@ #define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_DISPLAY_BOARDINFO_LATE +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO + #define CONFIG_LMB #define CONFIG_OF_LIBFDT -- cgit v1.3.1 From e98a03ca68ca0edd08c260126aacc8c0f550804a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 10 Oct 2014 07:49:20 -0600 Subject: dm: x86: Convert coreboot serial to use driver model This makes use of the existing device tree node to use driver model for the serial console. Signed-off-by: Simon Glass --- arch/x86/dts/coreboot.dtsi | 4 ++-- arch/x86/include/asm/ibmpc.h | 10 ---------- drivers/serial/Makefile | 1 + drivers/serial/serial_coreboot.c | 38 ++++++++++++++++++++++++++++++++++++++ include/configs/coreboot.h | 18 +++++++----------- 5 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 drivers/serial/serial_coreboot.c (limited to 'include') diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi index c989152887c..c8dc4cec3c9 100644 --- a/arch/x86/dts/coreboot.dtsi +++ b/arch/x86/dts/coreboot.dtsi @@ -1,8 +1,8 @@ /include/ "skeleton.dtsi" / { - aliases { - console = "/serial"; + chosen { + stdout-path = "/serial"; }; serial { diff --git a/arch/x86/include/asm/ibmpc.h b/arch/x86/include/asm/ibmpc.h index 0f9665f5495..e6d183b4796 100644 --- a/arch/x86/include/asm/ibmpc.h +++ b/arch/x86/include/asm/ibmpc.h @@ -18,14 +18,4 @@ #define SYSCTLA 0x92 #define SLAVE_PIC 0xa0 -#if 1 -#define UART0_BASE 0x3f8 -#define UART1_BASE 0x2f8 -#else -/* FixMe: uarts swapped */ -#define UART0_BASE 0x2f8 -#define UART1_BASE 0x3f8 -#endif - - #endif diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index cd87d18cf7e..2c19ebc2885 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_ARC_SERIAL) += serial_arc.o obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o +obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c new file mode 100644 index 00000000000..5c6a76c59c0 --- /dev/null +++ b/drivers/serial/serial_coreboot.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static const struct udevice_id coreboot_serial_ids[] = { + { .compatible = "coreboot-uart" }, + { } +}; + +static int coreboot_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = 1843200; + + return 0; +} +U_BOOT_DRIVER(serial_ns16550) = { + .name = "serial_coreboot", + .id = UCLASS_SERIAL, + .of_match = coreboot_serial_ids, + .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, +}; diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 0e85145c249..4b90dc205de 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -30,6 +30,7 @@ #define CONFIG_DM #define CONFIG_CMD_DM #define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL #define CONFIG_LMB #define CONFIG_OF_LIBFDT @@ -92,21 +93,16 @@ /*----------------------------------------------------------------------- * Serial Configuration */ -#define CONFIG_CONS_INDEX 1 +#define CONFIG_COREBOOT_SERIAL #define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE 1 -#define CONFIG_SYS_NS16550_CLK 1843200 -#define CONFIG_BAUDRATE 9600 +#define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {300, 600, 1200, 2400, 4800, \ 9600, 19200, 38400, 115200} -#define CONFIG_SYS_NS16550_COM1 UART0_BASE -#define CONFIG_SYS_NS16550_COM2 UART1_BASE #define CONFIG_SYS_NS16550_PORT_MAPPED -#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,eserial0\0" \ - "stdout=vga,eserial0,cbmem\0" \ - "stderr=vga,eserial0,cbmem\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ + "stdout=vga,serial,cbmem\0" \ + "stderr=vga,serial,cbmem\0" #define CONFIG_CONSOLE_MUX #define CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -260,7 +256,7 @@ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024) - +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE -- cgit v1.3.1 From 86256b796ee757b7d1407233d0ca71576a7b8182 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 24 Oct 2014 12:41:19 +0900 Subject: dm: move platform data headers to include/dm/platform_data The platform_data definitions are generally referenced from both drivers and board files. That is why header files defining platform_data sturectures are placed in "include" directory, but our top level "include" directory is already too cluttered. Let's collect platform_data definitions under the directory "include/dm/platform_data" like Linux gathers ones around under "include/linux/platform_data". This commit moves two header files: include/serial_mxc.h -> include/dm/platform_data/serial_mxc.h include/serial_pl01x.h -> include/dm/platform_data/serial_pl01x.h Signed-off-by: Masahiro Yamada --- board/compulab/cm_fx6/cm_fx6.c | 2 +- drivers/serial/serial_mxc.c | 2 +- drivers/serial/serial_pl01x.c | 2 +- include/dm/platform_data/serial_mxc.h | 14 ++++++++++++++ include/dm/platform_data/serial_pl01x.h | 27 +++++++++++++++++++++++++++ include/serial_mxc.h | 14 -------------- include/serial_pl01x.h | 27 --------------------------- 7 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 include/dm/platform_data/serial_mxc.h create mode 100644 include/dm/platform_data/serial_pl01x.h delete mode 100644 include/serial_mxc.h delete mode 100644 include/serial_pl01x.h (limited to 'include') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index f77ff48a1c3..82681b10eb8 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include #include "common.h" #include "../common/eeprom.h" diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 9ce24f9f932..d6cf1d874a6 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -7,10 +7,10 @@ #include #include #include -#include #include #include #include +#include #include #include diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index e6313ad3d3a..38dda910217 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "serial_pl01x_internal.h" diff --git a/include/dm/platform_data/serial_mxc.h b/include/dm/platform_data/serial_mxc.h new file mode 100644 index 00000000000..7d3ace2f9e4 --- /dev/null +++ b/include/dm/platform_data/serial_mxc.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2014 Google, Inc + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __serial_mxc_h +#define __serial_mxc_h + +/* Information about a serial port */ +struct mxc_serial_platdata { + struct mxc_uart *reg; /* address of registers in physical memory */ +}; + +#endif diff --git a/include/dm/platform_data/serial_pl01x.h b/include/dm/platform_data/serial_pl01x.h new file mode 100644 index 00000000000..5e068f390bd --- /dev/null +++ b/include/dm/platform_data/serial_pl01x.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014 Google, Inc + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __serial_pl01x_h +#define __serial_pl01x_h + +enum pl01x_type { + TYPE_PL010, + TYPE_PL011, +}; + +/* + *Information about a serial port + * + * @base: Register base address + * @type: Port type + * @clock: Input clock rate, used for calculating the baud rate divisor + */ +struct pl01x_serial_platdata { + unsigned long base; + enum pl01x_type type; + unsigned int clock; +}; + +#endif diff --git a/include/serial_mxc.h b/include/serial_mxc.h deleted file mode 100644 index 7d3ace2f9e4..00000000000 --- a/include/serial_mxc.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __serial_mxc_h -#define __serial_mxc_h - -/* Information about a serial port */ -struct mxc_serial_platdata { - struct mxc_uart *reg; /* address of registers in physical memory */ -}; - -#endif diff --git a/include/serial_pl01x.h b/include/serial_pl01x.h deleted file mode 100644 index 5e068f390bd..00000000000 --- a/include/serial_pl01x.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __serial_pl01x_h -#define __serial_pl01x_h - -enum pl01x_type { - TYPE_PL010, - TYPE_PL011, -}; - -/* - *Information about a serial port - * - * @base: Register base address - * @type: Port type - * @clock: Input clock rate, used for calculating the baud rate divisor - */ -struct pl01x_serial_platdata { - unsigned long base; - enum pl01x_type type; - unsigned int clock; -}; - -#endif -- cgit v1.3.1 From 3fdd0bb2b0dc20f192e9ea8682d5c18f37daadc1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 23 Oct 2014 22:26:05 +0900 Subject: serial: add static directive to local functions The functions _serial_putc, _serial_putc_raw, _serial_puts, _serial_getc, _serial_tstc, _serial_setbrg are defined and used locally in each of serial_ns16550.c and serial_s3c24x0.c. Add static directive to them and remove declarations from include/common.h. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- drivers/serial/serial_ns16550.c | 21 +++++++-------------- drivers/serial/serial_s3c24x0.c | 10 +++++----- include/common.h | 7 ------- 3 files changed, 12 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 632da4cf70b..799ef6a667d 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = { .puts = eserial##port##_puts, \ } -void -_serial_putc(const char c,const int port) +static void _serial_putc(const char c, const int port) { if (c == '\n') NS16550_putc(PORT, '\r'); @@ -128,35 +127,29 @@ _serial_putc(const char c,const int port) NS16550_putc(PORT, c); } -void -_serial_putc_raw(const char c,const int port) +static void _serial_putc_raw(const char c, const int port) { NS16550_putc(PORT, c); } -void -_serial_puts (const char *s,const int port) +static void _serial_puts(const char *s, const int port) { while (*s) { - _serial_putc (*s++,port); + _serial_putc(*s++, port); } } - -int -_serial_getc(const int port) +static int _serial_getc(const int port) { return NS16550_getc(PORT); } -int -_serial_tstc(const int port) +static int _serial_tstc(const int port) { return NS16550_tstc(PORT); } -void -_serial_setbrg (const int port) +static void _serial_setbrg(const int port) { int clock_divisor; diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c index c07f4c9b473..7afc5044a8c 100644 --- a/drivers/serial/serial_s3c24x0.c +++ b/drivers/serial/serial_s3c24x0.c @@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR; static int hwflow; #endif -void _serial_setbrg(const int dev_index) +static void _serial_setbrg(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); unsigned int reg = 0; @@ -131,7 +131,7 @@ static int serial_init_dev(const int dev_index) * otherwise. When the function is succesfull, the character read is * written into its argument c. */ -int _serial_getc(const int dev_index) +static int _serial_getc(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); @@ -181,7 +181,7 @@ void enable_putc(void) /* * Output a single byte to the serial port. */ -void _serial_putc(const char c, const int dev_index) +static void _serial_putc(const char c, const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); #ifdef CONFIG_MODEM_SUPPORT @@ -212,7 +212,7 @@ static inline void serial_putc_dev(unsigned int dev_index, const char c) /* * Test whether a character is in the RX buffer */ -int _serial_tstc(const int dev_index) +static int _serial_tstc(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); @@ -224,7 +224,7 @@ static inline int serial_tstc_dev(unsigned int dev_index) return _serial_tstc(dev_index); } -void _serial_puts(const char *s, const int dev_index) +static void _serial_puts(const char *s, const int dev_index) { while (*s) { _serial_putc(*s++, dev_index); diff --git a/include/common.h b/include/common.h index d5020c8c45d..bcf6c7e9502 100644 --- a/include/common.h +++ b/include/common.h @@ -636,13 +636,6 @@ struct stdio_dev; int serial_stub_getc(struct stdio_dev *sdev); int serial_stub_tstc(struct stdio_dev *sdev); -void _serial_setbrg (const int); -void _serial_putc (const char, const int); -void _serial_putc_raw(const char, const int); -void _serial_puts (const char *, const int); -int _serial_getc (const int); -int _serial_tstc (const int); - /* $(CPU)/speed.c */ int get_clocks (void); int get_clocks_866 (void); -- cgit v1.3.1 From d064cbffff37367b64b53f6e6942cbea67109237 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 23 Oct 2014 22:26:10 +0900 Subject: dm: serial: use Driver Model for UniPhier serial driver This commit converts UniPhier on-chip serial driver to driver model. Since UniPhier SoCs do not have Device Tree support, some board files should be added under arch/arm/cpu/armv7/uniphier/ph1-*/ directories. (Device Tree support for UniPhier platform is still under way.) Now the base address and master clock frequency are passed from platform data, so CONFIG_SYS_UNIPHIER_SERIAL_BASE* and CONFIG_SYS_UNIPHIER_UART_CLK should be removed. Tested on UniPhier PH1-LD4 ref board. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile | 1 + arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c | 15 ++ arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile | 1 + arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c | 15 ++ arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile | 1 + arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c | 15 ++ arch/arm/include/asm/arch-uniphier/platdevice.h | 24 +++ configs/ph1_ld4_defconfig | 2 + configs/ph1_pro4_defconfig | 2 + configs/ph1_sld8_defconfig | 2 + drivers/serial/serial_uniphier.c | 199 ++++++++-------------- include/configs/ph1_ld4.h | 2 - include/configs/ph1_pro4.h | 2 - include/configs/ph1_sld8.h | 2 - include/configs/uniphier-common.h | 7 +- include/dm/platform_data/serial-uniphier.h | 18 ++ 16 files changed, 172 insertions(+), 136 deletions(-) create mode 100644 arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c create mode 100644 arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c create mode 100644 arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c create mode 100644 arch/arm/include/asm/arch-uniphier/platdevice.h create mode 100644 include/dm/platform_data/serial-uniphier.h (limited to 'include') diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index b385e195447..781b511a97b 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \ sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c new file mode 100644 index 00000000000..0047223181a --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define UART_MASTER_CLK 36864000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index 712afd1beeb..e11f4f6d8b3 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \ sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c new file mode 100644 index 00000000000..6da921e9204 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define UART_MASTER_CLK 73728000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index b385e195447..781b511a97b 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \ sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c new file mode 100644 index 00000000000..59d054a3102 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define UART_MASTER_CLK 80000000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/include/asm/arch-uniphier/platdevice.h b/arch/arm/include/asm/arch-uniphier/platdevice.h new file mode 100644 index 00000000000..cdf7d132d44 --- /dev/null +++ b/arch/arm/include/asm/arch-uniphier/platdevice.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARCH_PLATDEVICE_H +#define ARCH_PLATDEVICE_H + +#include +#include + +#define SERIAL_DEVICE(n, ba, clk) \ +static struct uniphier_serial_platform_data serial_device##n = { \ + .base = ba, \ + .uartclk = clk \ +}; \ +U_BOOT_DEVICE(serial##n) = { \ + .name = DRIVER_NAME, \ + .platdata = &serial_device##n \ +}; + +#endif /* ARCH_PLATDEVICE_H */ diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index 53f3126e71e..c8404f8a8ee 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -2,7 +2,9 @@ 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 S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 209466ebcb3..5c051e36a03 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -2,7 +2,9 @@ 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 S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 658977bcf62..2c636e60d14 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -2,7 +2,9 @@ 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 S:CONFIG_SPL_NAND_DENALI=y diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index f8c9d921e28..9114b3ed600 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -2,14 +2,14 @@ * Copyright (C) 2012-2014 Panasonic Corporation * Author: Masahiro Yamada * - * Based on serial_ns16550.c - * (C) Copyright 2000 - * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. - * * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include +#include +#include #include #define UART_REG(x) \ @@ -48,157 +48,104 @@ struct uniphier_serial { #define UART_LSR_DR 0x01 /* Data ready */ #define UART_LSR_THRE 0x20 /* Xmit holding register empty */ -DECLARE_GLOBAL_DATA_PTR; +struct uniphier_serial_private_data { + struct uniphier_serial __iomem *membase; +}; + +#define uniphier_serial_port(dev) \ + ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase -static void uniphier_serial_init(struct uniphier_serial *port) +int uniphier_serial_setbrg(struct udevice *dev, int baudrate) { + struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); const unsigned int mode_x_div = 16; unsigned int divisor; writeb(UART_LCR_WLS_8, &port->lcr); - divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK, - mode_x_div * gd->baudrate); + divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate); writew(divisor, &port->dlr); -} -static void uniphier_serial_setbrg(struct uniphier_serial *port) -{ - uniphier_serial_init(port); + return 0; } -static int uniphier_serial_tstc(struct uniphier_serial *port) +static int uniphier_serial_getc(struct udevice *dev) { - return (readb(&port->lsr) & UART_LSR_DR) != 0; -} + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); -static int uniphier_serial_getc(struct uniphier_serial *port) -{ - while (!uniphier_serial_tstc(port)) - ; + if (!(readb(&port->lsr) & UART_LSR_DR)) + return -EAGAIN; return readb(&port->rbr); } -static void uniphier_serial_putc(struct uniphier_serial *port, const char c) +static int uniphier_serial_putc(struct udevice *dev, const char c) { - if (c == '\n') - uniphier_serial_putc(port, '\r'); + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); - while (!(readb(&port->lsr) & UART_LSR_THRE)) - ; + if (!(readb(&port->lsr) & UART_LSR_THRE)) + return -EAGAIN; writeb(c, &port->thr); + + return 0; } -static struct uniphier_serial *serial_ports[4] = { -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3, -#else - NULL, -#endif -}; +int uniphier_serial_probe(struct udevice *dev) +{ + struct uniphier_serial_private_data *priv = dev_get_priv(dev); + struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); -/* Multi serial device functions */ -#define DECLARE_ESERIAL_FUNCTIONS(port) \ - static int eserial##port##_init(void) \ - { \ - uniphier_serial_init(serial_ports[port]); \ - return 0 ; \ - } \ - static void eserial##port##_setbrg(void) \ - { \ - uniphier_serial_setbrg(serial_ports[port]); \ - } \ - static int eserial##port##_getc(void) \ - { \ - return uniphier_serial_getc(serial_ports[port]); \ - } \ - static int eserial##port##_tstc(void) \ - { \ - return uniphier_serial_tstc(serial_ports[port]); \ - } \ - static void eserial##port##_putc(const char c) \ - { \ - uniphier_serial_putc(serial_ports[port], c); \ - } - -/* Serial device descriptor */ -#define INIT_ESERIAL_STRUCTURE(port, __name) { \ - .name = __name, \ - .start = eserial##port##_init, \ - .stop = NULL, \ - .setbrg = eserial##port##_setbrg, \ - .getc = eserial##port##_getc, \ - .tstc = eserial##port##_tstc, \ - .putc = eserial##port##_putc, \ - .puts = default_serial_puts, \ -} + priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial)); -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) -DECLARE_ESERIAL_FUNCTIONS(0); -struct serial_device uniphier_serial0_device = - INIT_ESERIAL_STRUCTURE(0, "ttyS0"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) -DECLARE_ESERIAL_FUNCTIONS(1); -struct serial_device uniphier_serial1_device = - INIT_ESERIAL_STRUCTURE(1, "ttyS1"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) -DECLARE_ESERIAL_FUNCTIONS(2); -struct serial_device uniphier_serial2_device = - INIT_ESERIAL_STRUCTURE(2, "ttyS2"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) -DECLARE_ESERIAL_FUNCTIONS(3); -struct serial_device uniphier_serial3_device = - INIT_ESERIAL_STRUCTURE(3, "ttyS3"); -#endif + if (!priv->membase) + return -ENOMEM; -__weak struct serial_device *default_serial_console(void) + return 0; +} + +int uniphier_serial_remove(struct udevice *dev) { -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) - return &uniphier_serial0_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) - return &uniphier_serial1_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) - return &uniphier_serial2_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) - return &uniphier_serial3_device; -#else -#error "No uniphier serial ports configured." -#endif + unmap_sysmem(uniphier_serial_port(dev)); + + return 0; } -void uniphier_serial_initialize(void) +#ifdef CONFIG_OF_CONTROL +static const struct udevice_id uniphier_uart_of_match = { + { .compatible = "panasonic,uniphier-uart"}, + {}, +}; + +static int uniphier_serial_ofdata_to_platdata(struct udevice *dev) { -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) - serial_register(&uniphier_serial0_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) - serial_register(&uniphier_serial1_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) - serial_register(&uniphier_serial2_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) - serial_register(&uniphier_serial3_device); -#endif + /* + * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com) + * + * Implement conversion code from DTB to platform data + * when supporting CONFIG_OF_CONTROL on UniPhir platform. + */ } +#endif + +static const struct dm_serial_ops uniphier_serial_ops = { + .setbrg = uniphier_serial_setbrg, + .getc = uniphier_serial_getc, + .putc = uniphier_serial_putc, +}; + +U_BOOT_DRIVER(uniphier_serial) = { + .name = DRIVER_NAME, + .id = UCLASS_SERIAL, + .of_match = of_match_ptr(uniphier_uart_of_match), + .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata), + .probe = uniphier_serial_probe, + .remove = uniphier_serial_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data), + .platdata_auto_alloc_size = + sizeof(struct uniphier_serial_platform_data), + .ops = &uniphier_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/include/configs/ph1_ld4.h b/include/configs/ph1_ld4.h index a28d7b579a6..a5468659371 100644 --- a/include/configs/ph1_ld4.h +++ b/include/configs/ph1_ld4.h @@ -34,8 +34,6 @@ #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 36864000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 1 diff --git a/include/configs/ph1_pro4.h b/include/configs/ph1_pro4.h index b79967f7da4..85c14ba6cd0 100644 --- a/include/configs/ph1_pro4.h +++ b/include/configs/ph1_pro4.h @@ -34,8 +34,6 @@ #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 73728000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 2 diff --git a/include/configs/ph1_sld8.h b/include/configs/ph1_sld8.h index 9d391f1d74a..41e2299beec 100644 --- a/include/configs/ph1_sld8.h +++ b/include/configs/ph1_sld8.h @@ -34,8 +34,6 @@ #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 80000000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 1 diff --git a/include/configs/uniphier-common.h b/include/configs/uniphier-common.h index 18fe277cada..b18ae6dfaeb 100644 --- a/include/configs/uniphier-common.h +++ b/include/configs/uniphier-common.h @@ -33,18 +33,17 @@ are defined. Select only one of them." # define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000) #endif +#ifdef CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE #define CONFIG_SYS_NS16550_CLK 12288000 #define CONFIG_SYS_NS16550_REG_SIZE -2 +#endif #define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE #define CONFIG_SMC911X_32_BIT -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE0 0x54006800 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE1 0x54006900 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE2 0x54006a00 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE3 0x54006b00 +#define CONFIG_SYS_MALLOC_F_LEN 0x7000 /*----------------------------------------------------------------------- * MMU and Cache Setting diff --git a/include/dm/platform_data/serial-uniphier.h b/include/dm/platform_data/serial-uniphier.h new file mode 100644 index 00000000000..52343e34ee7 --- /dev/null +++ b/include/dm/platform_data/serial-uniphier.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PLAT_UNIPHIER_SERIAL_H +#define __PLAT_UNIPHIER_SERIAL_H + +#define DRIVER_NAME "uniphier-uart" + +struct uniphier_serial_platform_data { + unsigned long base; + unsigned int uartclk; +}; + +#endif /* __PLAT_UNIPHIER_SERIAL_H */ -- cgit v1.3.1 From ff247b7a0d2f4051786f5be1e73cf90a86b4b641 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 23 Oct 2014 22:26:11 +0900 Subject: serial: uniphier: move CONFIG_UNIPHIER_SERIAL to Kconfig Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- configs/ph1_ld4_defconfig | 1 + configs/ph1_pro4_defconfig | 1 + configs/ph1_sld8_defconfig | 1 + drivers/serial/Kconfig | 6 ++++++ include/configs/ph1_ld4.h | 4 +--- include/configs/ph1_pro4.h | 4 +--- include/configs/ph1_sld8.h | 4 +--- 7 files changed, 12 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index c8404f8a8ee..e6aba422f81 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -7,4 +7,5 @@ CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 5c051e36a03..334ec4bbdff 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -7,4 +7,5 @@ CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 2c636e60d14..4e8f354c9b5 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -7,4 +7,5 @@ CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6a392ba24fd..a0b6e02b546 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -4,3 +4,9 @@ config DM_SERIAL help If you want to use driver model for serial drivers, say Y. To use legacy serial drivers, say N. + +config UNIPHIER_SERIAL + bool "UniPhier on-chip UART support" + depends on ARCH_UNIPHIER && DM_SERIAL + help + Support for the on-chip UARTs on the Panasonic UniPhier platform. diff --git a/include/configs/ph1_ld4.h b/include/configs/ph1_ld4.h index a5468659371..005a853f568 100644 --- a/include/configs/ph1_ld4.h +++ b/include/configs/ph1_ld4.h @@ -28,9 +28,7 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif diff --git a/include/configs/ph1_pro4.h b/include/configs/ph1_pro4.h index 85c14ba6cd0..7dd6fd2a929 100644 --- a/include/configs/ph1_pro4.h +++ b/include/configs/ph1_pro4.h @@ -28,9 +28,7 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif diff --git a/include/configs/ph1_sld8.h b/include/configs/ph1_sld8.h index 41e2299beec..1062aace38a 100644 --- a/include/configs/ph1_sld8.h +++ b/include/configs/ph1_sld8.h @@ -28,9 +28,7 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif -- cgit v1.3.1