mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-28 15:13:31 +08:00
Merge git://git.denx.de/u-boot-dm
Conflicts: drivers/serial/serial-uclass.c Signed-off-by: Tom Rini <trini@ti.com>
This commit is contained in:
commit
1739564e75
119
README
119
README
@ -623,6 +623,120 @@ The following options need to be configured:
|
|||||||
exists, unlike the similar options in the Linux kernel. Do not
|
exists, unlike the similar options in the Linux kernel. Do not
|
||||||
set these options unless they apply!
|
set these options unless they apply!
|
||||||
|
|
||||||
|
- Driver Model
|
||||||
|
Driver model is a new framework for devices in U-Boot
|
||||||
|
introduced in early 2014. U-Boot is being progressively
|
||||||
|
moved over to this. It offers a consistent device structure,
|
||||||
|
supports grouping devices into classes and has built-in
|
||||||
|
handling of platform data and device tree.
|
||||||
|
|
||||||
|
To enable transition to driver model in a relatively
|
||||||
|
painful fashion, each subsystem can be independently
|
||||||
|
switched between the legacy/ad-hoc approach and the new
|
||||||
|
driver model using the options below. Also, many uclass
|
||||||
|
interfaces include compatibility features which may be
|
||||||
|
removed once the conversion of that subsystem is complete.
|
||||||
|
As a result, the API provided by the subsystem may in fact
|
||||||
|
not change with driver model.
|
||||||
|
|
||||||
|
See doc/driver-model/README.txt for more information.
|
||||||
|
|
||||||
|
CONFIG_DM
|
||||||
|
|
||||||
|
Enable driver model. This brings in the core support,
|
||||||
|
including scanning of platform data on start-up. If
|
||||||
|
CONFIG_OF_CONTROL is enabled, the device tree will be
|
||||||
|
scanned also when available.
|
||||||
|
|
||||||
|
CONFIG_CMD_DM
|
||||||
|
|
||||||
|
Enable driver model test commands. These allow you to print
|
||||||
|
out the driver model tree and the uclasses.
|
||||||
|
|
||||||
|
CONFIG_DM_DEMO
|
||||||
|
|
||||||
|
Enable some demo devices and the 'demo' command. These are
|
||||||
|
really only useful for playing around while trying to
|
||||||
|
understand driver model in sandbox.
|
||||||
|
|
||||||
|
CONFIG_SPL_DM
|
||||||
|
|
||||||
|
Enable driver model in SPL. You will need to provide a
|
||||||
|
suitable malloc() implementation. If you are not using the
|
||||||
|
full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START,
|
||||||
|
consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you
|
||||||
|
must provide CONFIG_SYS_MALLOC_F_LEN to set the size.
|
||||||
|
In most cases driver model will only allocate a few uclasses
|
||||||
|
and devices in SPL, so 1KB should be enable. See
|
||||||
|
CONFIG_SYS_MALLOC_F_LEN for more details on how to enable
|
||||||
|
it.
|
||||||
|
|
||||||
|
CONFIG_DM_SERIAL
|
||||||
|
|
||||||
|
Enable driver model for serial. This replaces
|
||||||
|
drivers/serial/serial.c with the serial uclass, which
|
||||||
|
implements serial_putc() etc. The uclass interface is
|
||||||
|
defined in include/serial.h.
|
||||||
|
|
||||||
|
CONFIG_DM_GPIO
|
||||||
|
|
||||||
|
Enable driver model for GPIO access. The standard GPIO
|
||||||
|
interface (gpio_get_value(), etc.) is then implemented by
|
||||||
|
the GPIO uclass. Drivers provide methods to query the
|
||||||
|
particular GPIOs that they provide. The uclass interface
|
||||||
|
is defined in include/asm-generic/gpio.h.
|
||||||
|
|
||||||
|
CONFIG_DM_SPI
|
||||||
|
|
||||||
|
Enable driver model for SPI. The SPI slave interface
|
||||||
|
(spi_setup_slave(), spi_xfer(), etc.) is then implemented by
|
||||||
|
the SPI uclass. Drivers provide methods to access the SPI
|
||||||
|
buses that they control. The uclass interface is defined in
|
||||||
|
include/spi.h. The existing spi_slave structure is attached
|
||||||
|
as 'parent data' to every slave on each bus. Slaves
|
||||||
|
typically use driver-private data instead of extending the
|
||||||
|
spi_slave structure.
|
||||||
|
|
||||||
|
CONFIG_DM_SPI_FLASH
|
||||||
|
|
||||||
|
Enable driver model for SPI flash. This SPI flash interface
|
||||||
|
(spi_flash_probe(), spi_flash_write(), etc.) is then
|
||||||
|
implemented by the SPI flash uclass. There is one standard
|
||||||
|
SPI flash driver which knows how to probe most chips
|
||||||
|
supported by U-Boot. The uclass interface is defined in
|
||||||
|
include/spi_flash.h, but is currently fully compatible
|
||||||
|
with the old interface to avoid confusion and duplication
|
||||||
|
during the transition parent. SPI and SPI flash must be
|
||||||
|
enabled together (it is not possible to use driver model
|
||||||
|
for one and not the other).
|
||||||
|
|
||||||
|
CONFIG_DM_CROS_EC
|
||||||
|
|
||||||
|
Enable driver model for the Chrome OS EC interface. This
|
||||||
|
allows the cros_ec SPI driver to operate with CONFIG_DM_SPI
|
||||||
|
but otherwise makes few changes. Since cros_ec also supports
|
||||||
|
I2C and LPC (which don't support driver model yet), a full
|
||||||
|
conversion is not yet possible.
|
||||||
|
|
||||||
|
|
||||||
|
** Code size options: The following options are enabled by
|
||||||
|
default except in SPL. Enable them explicitly to get these
|
||||||
|
features in SPL.
|
||||||
|
|
||||||
|
CONFIG_DM_WARN
|
||||||
|
|
||||||
|
Enable the dm_warn() function. This can use up quite a bit
|
||||||
|
of space for its strings.
|
||||||
|
|
||||||
|
CONFIG_DM_STDIO
|
||||||
|
|
||||||
|
Enable registering a serial device with the stdio library.
|
||||||
|
|
||||||
|
CONFIG_DM_DEVICE_REMOVE
|
||||||
|
|
||||||
|
Enable removing of devices.
|
||||||
|
|
||||||
|
|
||||||
- Linux Kernel Interface:
|
- Linux Kernel Interface:
|
||||||
CONFIG_CLOCKS_IN_MHZ
|
CONFIG_CLOCKS_IN_MHZ
|
||||||
|
|
||||||
@ -3870,6 +3984,11 @@ Configuration Settings:
|
|||||||
Pre-relocation malloc() is only supported on ARM and sandbox
|
Pre-relocation malloc() is only supported on ARM and sandbox
|
||||||
at present but is fairly easy to enable for other archs.
|
at present but is fairly easy to enable for other archs.
|
||||||
|
|
||||||
|
- CONFIG_SYS_MALLOC_SIMPLE
|
||||||
|
Provides a simple and small malloc() and calloc() for those
|
||||||
|
boards which do not use the full malloc in SPL (which is
|
||||||
|
enabled with CONFIG_SYS_SPL_MALLOC_START).
|
||||||
|
|
||||||
- CONFIG_SYS_BOOTM_LEN:
|
- CONFIG_SYS_BOOTM_LEN:
|
||||||
Normally compressed uImages are limited to an
|
Normally compressed uImages are limited to an
|
||||||
uncompressed size of 8 MBytes. If this is not enough,
|
uncompressed size of 8 MBytes. If this is not enough,
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/arch/at91sam9260_matrix.h>
|
#include <asm/arch/at91sam9260_matrix.h>
|
||||||
#include <asm/arch/at91_common.h>
|
#include <asm/arch/at91_common.h>
|
||||||
@ -229,3 +230,16 @@ void at91_sdram_hw_init(void)
|
|||||||
at91_set_a_periph(AT91_PIO_PORTC, 30, 0);
|
at91_set_a_periph(AT91_PIO_PORTC, 30, 0);
|
||||||
at91_set_a_periph(AT91_PIO_PORTC, 31, 0);
|
at91_set_a_periph(AT91_PIO_PORTC, 31, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Platform data for the GPIOs */
|
||||||
|
static const struct at91_port_platdata at91sam9260_plat[] = {
|
||||||
|
{ ATMEL_BASE_PIOA, "PA" },
|
||||||
|
{ ATMEL_BASE_PIOB, "PB" },
|
||||||
|
{ ATMEL_BASE_PIOC, "PC" },
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DEVICES(at91sam9260_gpios) = {
|
||||||
|
{ "gpio_at91", &at91sam9260_plat[0] },
|
||||||
|
{ "gpio_at91", &at91sam9260_plat[1] },
|
||||||
|
{ "gpio_at91", &at91sam9260_plat[2] },
|
||||||
|
};
|
||||||
|
@ -34,6 +34,13 @@ SECTIONS
|
|||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
||||||
. = .;
|
. = .;
|
||||||
|
#ifdef CONFIG_SPL_DM
|
||||||
|
.u_boot_list : {
|
||||||
|
KEEP(*(SORT(.u_boot_list_*_driver_*)));
|
||||||
|
KEEP(*(SORT(.u_boot_list_*_uclass_*)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
__image_copy_end = .;
|
__image_copy_end = .;
|
||||||
|
|
||||||
|
@ -136,9 +136,11 @@
|
|||||||
/*
|
/*
|
||||||
* Other misc defines
|
* Other misc defines
|
||||||
*/
|
*/
|
||||||
|
#ifndef CONFIG_DM_GPIO
|
||||||
#define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */
|
#define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */
|
||||||
#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP
|
|
||||||
#define ATMEL_BASE_PIO ATMEL_BASE_PIOA
|
#define ATMEL_BASE_PIO ATMEL_BASE_PIOA
|
||||||
|
#endif
|
||||||
|
#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SoC specific defines
|
* SoC specific defines
|
||||||
|
15
arch/arm/include/asm/arch-at91/atmel_serial.h
Normal file
15
arch/arm/include/asm/arch-at91/atmel_serial.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Google, Inc
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ATMEL_SERIAL_H
|
||||||
|
#define _ATMEL_SERIAL_H
|
||||||
|
|
||||||
|
/* Information about a serial port */
|
||||||
|
struct atmel_serial_platdata {
|
||||||
|
uint32_t base_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -253,4 +253,10 @@ static inline unsigned at91_gpio_to_pin(unsigned gpio)
|
|||||||
return gpio % 32;
|
return gpio % 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Platform data for each GPIO port */
|
||||||
|
struct at91_port_platdata {
|
||||||
|
uint32_t base_addr;
|
||||||
|
const char *bank_name;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_AT91_GPIO_H */
|
#endif /* __ASM_ARCH_AT91_GPIO_H */
|
||||||
|
@ -78,7 +78,7 @@ clr_gd:
|
|||||||
strlo r0, [r1] /* clear 32-bit GD word */
|
strlo r0, [r1] /* clear 32-bit GD word */
|
||||||
addlo r1, r1, #4 /* move to next */
|
addlo r1, r1, #4 /* move to next */
|
||||||
blo clr_gd
|
blo clr_gd
|
||||||
#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD)
|
#if defined(CONFIG_SYS_MALLOC_F_LEN)
|
||||||
sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN
|
sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN
|
||||||
str sp, [r9, #GD_MALLOC_BASE]
|
str sp, [r9, #GD_MALLOC_BASE]
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
SNAPPER9260 BOARD
|
SNAPPER9260 BOARD
|
||||||
M: Ryan Mallon <ryan@bluewatersys.com>
|
M: Simon Glass <sjg@chromium.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: board/bluewater/snapper9260/
|
F: board/bluewater/snapper9260/
|
||||||
F: include/configs/snapper9260.h
|
F: include/configs/snapper9260.h
|
||||||
|
@ -9,12 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
#include <asm/arch/at91sam9260_matrix.h>
|
#include <asm/arch/at91sam9260_matrix.h>
|
||||||
#include <asm/arch/at91sam9_smc.h>
|
#include <asm/arch/at91sam9_smc.h>
|
||||||
#include <asm/arch/at91_common.h>
|
#include <asm/arch/at91_common.h>
|
||||||
#include <asm/arch/at91_pmc.h>
|
#include <asm/arch/at91_pmc.h>
|
||||||
#include <asm/arch/gpio.h>
|
#include <asm/arch/gpio.h>
|
||||||
|
#include <asm/arch/atmel_serial.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netdev.h>
|
#include <netdev.h>
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
@ -95,10 +98,12 @@ static void nand_hw_init(void)
|
|||||||
&smc->cs[3].mode);
|
&smc->cs[3].mode);
|
||||||
|
|
||||||
/* Configure RDY/BSY */
|
/* Configure RDY/BSY */
|
||||||
at91_set_gpio_input(CONFIG_SYS_NAND_READY_PIN, 1);
|
gpio_request(CONFIG_SYS_NAND_READY_PIN, "nand_rdy");
|
||||||
|
gpio_direction_input(CONFIG_SYS_NAND_READY_PIN);
|
||||||
|
|
||||||
/* Enable NandFlash */
|
/* Enable NandFlash */
|
||||||
at91_set_gpio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
|
gpio_request(CONFIG_SYS_NAND_ENABLE_PIN, "nand_ce");
|
||||||
|
gpio_direction_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_init(void)
|
int board_init(void)
|
||||||
@ -140,3 +145,12 @@ int dram_init(void)
|
|||||||
void reset_phy(void)
|
void reset_phy(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct atmel_serial_platdata at91sam9260_serial_plat = {
|
||||||
|
.base_addr = ATMEL_BASE_DBGU,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DEVICE(at91sam9260_serial) = {
|
||||||
|
.name = "serial_atmel",
|
||||||
|
.platdata = &at91sam9260_serial_plat,
|
||||||
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <ns16550.h>
|
#include <ns16550.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -43,6 +44,13 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BUILD
|
||||||
|
/* TODO(sjg@chromium.org): Remove once SPL supports device tree */
|
||||||
|
U_BOOT_DEVICE(tegra_gpios) = {
|
||||||
|
"gpio_tegra"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const struct tegra_sysinfo sysinfo = {
|
const struct tegra_sysinfo sysinfo = {
|
||||||
CONFIG_TEGRA_BOARD_STRING
|
CONFIG_TEGRA_BOARD_STRING
|
||||||
};
|
};
|
||||||
|
@ -252,6 +252,9 @@ obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
|
|||||||
obj-y += console.o
|
obj-y += console.o
|
||||||
obj-$(CONFIG_CROS_EC) += cros_ec.o
|
obj-$(CONFIG_CROS_EC) += cros_ec.o
|
||||||
obj-y += dlmalloc.o
|
obj-y += dlmalloc.o
|
||||||
|
ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||||
|
obj-y += malloc_simple.o
|
||||||
|
endif
|
||||||
obj-y += image.o
|
obj-y += image.o
|
||||||
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
|
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
|
||||||
obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
|
obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
|
||||||
|
@ -99,7 +99,8 @@ static int initr_trace(void)
|
|||||||
|
|
||||||
static int initr_reloc(void)
|
static int initr_reloc(void)
|
||||||
{
|
{
|
||||||
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
|
/* tell others: relocation done */
|
||||||
|
gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
|
||||||
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
|
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -198,6 +198,19 @@ static uint get_alen(char *arg)
|
|||||||
return alen;
|
return alen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum i2c_err_op {
|
||||||
|
I2C_ERR_READ,
|
||||||
|
I2C_ERR_WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int i2c_report_err(int ret, enum i2c_err_op op)
|
||||||
|
{
|
||||||
|
printf("Error %s the chip: %d\n",
|
||||||
|
op == I2C_ERR_READ ? "reading" : "writing", ret);
|
||||||
|
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do_i2c_read() - Handle the "i2c read" command-line command
|
* do_i2c_read() - Handle the "i2c read" command-line command
|
||||||
* @cmdtp: Command data struct pointer
|
* @cmdtp: Command data struct pointer
|
||||||
@ -245,7 +258,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||||||
memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
|
memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
|
||||||
|
|
||||||
if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
|
if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
|
||||||
puts ("Error reading the chip.\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -286,8 +299,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
|
|||||||
|
|
||||||
while (length-- > 0) {
|
while (length-- > 0) {
|
||||||
if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) {
|
if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) {
|
||||||
puts("Error writing to the chip.\n");
|
return i2c_report_err(-1, I2C_ERR_WRITE);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* No write delay with FRAM devices.
|
* No write delay with FRAM devices.
|
||||||
@ -370,7 +382,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||||||
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
|
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
|
||||||
|
|
||||||
if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
|
if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
|
||||||
puts ("Error reading the chip.\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
else {
|
else {
|
||||||
printf("%04x:", addr);
|
printf("%04x:", addr);
|
||||||
cp = linebuf;
|
cp = linebuf;
|
||||||
@ -452,7 +464,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||||||
|
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
|
if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
|
||||||
puts ("Error writing the chip.\n");
|
i2c_report_err(-1, I2C_ERR_WRITE);
|
||||||
/*
|
/*
|
||||||
* Wait for the write to complete. The write can take
|
* Wait for the write to complete. The write can take
|
||||||
* up to 10mSec (we allow a little more time).
|
* up to 10mSec (we allow a little more time).
|
||||||
@ -528,7 +540,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||||||
addr++;
|
addr++;
|
||||||
}
|
}
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
puts ("Error reading the chip,\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
else
|
else
|
||||||
printf ("%08lx\n", crc);
|
printf ("%08lx\n", crc);
|
||||||
|
|
||||||
@ -601,7 +613,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
|
|||||||
do {
|
do {
|
||||||
printf("%08lx:", addr);
|
printf("%08lx:", addr);
|
||||||
if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
|
if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
|
||||||
puts ("\nError reading the chip,\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
else {
|
else {
|
||||||
data = cpu_to_be32(data);
|
data = cpu_to_be32(data);
|
||||||
if (size == 1)
|
if (size == 1)
|
||||||
@ -644,7 +656,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
|
|||||||
*/
|
*/
|
||||||
bootretry_reset_cmd_timeout();
|
bootretry_reset_cmd_timeout();
|
||||||
if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
|
if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
|
||||||
puts ("Error writing the chip.\n");
|
i2c_report_err(-1, I2C_ERR_WRITE);
|
||||||
#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
|
#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
|
||||||
udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
|
udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
|
||||||
#endif
|
#endif
|
||||||
@ -783,7 +795,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||||||
*/
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
if (i2c_read(chip, addr, alen, bytes, length) != 0)
|
if (i2c_read(chip, addr, alen, bytes, length) != 0)
|
||||||
puts ("Error reading the chip.\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
udelay(delay);
|
udelay(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,7 +1353,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||||||
|
|
||||||
chip = simple_strtoul(argv[1], NULL, 16);
|
chip = simple_strtoul(argv[1], NULL, 16);
|
||||||
if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) {
|
if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) {
|
||||||
puts("Error reading EDID content.\n");
|
i2c_report_err(-1, I2C_ERR_READ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2184,17 +2184,8 @@ Void_t* mALLOc(bytes) size_t bytes;
|
|||||||
INTERNAL_SIZE_T nb;
|
INTERNAL_SIZE_T nb;
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||||
if (gd && !(gd->flags & GD_FLG_RELOC)) {
|
if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
|
||||||
ulong new_ptr;
|
return malloc_simple(bytes);
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
new_ptr = gd->malloc_ptr + bytes;
|
|
||||||
if (new_ptr > gd->malloc_limit)
|
|
||||||
panic("Out of pre-reloc memory");
|
|
||||||
ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
|
|
||||||
gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check if mem_malloc_init() was run */
|
/* check if mem_malloc_init() was run */
|
||||||
@ -2462,7 +2453,7 @@ void fREe(mem) Void_t* mem;
|
|||||||
|
|
||||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||||
/* free() is a no-op - all the memory will be freed on relocation */
|
/* free() is a no-op - all the memory will be freed on relocation */
|
||||||
if (!(gd->flags & GD_FLG_RELOC))
|
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2618,7 +2609,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
|||||||
if (oldmem == NULL) return mALLOc(bytes);
|
if (oldmem == NULL) return mALLOc(bytes);
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||||
if (!(gd->flags & GD_FLG_RELOC)) {
|
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
|
||||||
/* This is harder to support and should not be needed */
|
/* This is harder to support and should not be needed */
|
||||||
panic("pre-reloc realloc() is not supported");
|
panic("pre-reloc realloc() is not supported");
|
||||||
}
|
}
|
||||||
@ -2970,7 +2961,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||||
if (!(gd->flags & GD_FLG_RELOC)) {
|
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
|
||||||
MALLOC_ZERO(mem, sz);
|
MALLOC_ZERO(mem, sz);
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
39
common/malloc_simple.c
Normal file
39
common/malloc_simple.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Simple malloc implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Google, Inc
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
void *malloc_simple(size_t bytes)
|
||||||
|
{
|
||||||
|
ulong new_ptr;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
new_ptr = gd->malloc_ptr + bytes;
|
||||||
|
if (new_ptr > gd->malloc_limit)
|
||||||
|
panic("Out of pre-reloc memory");
|
||||||
|
ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
|
||||||
|
gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYS_MALLOC_SIMPLE
|
||||||
|
void *calloc(size_t nmemb, size_t elem_size)
|
||||||
|
{
|
||||||
|
size_t size = nmemb * elem_size;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = malloc(size);
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
#endif
|
@ -7,6 +7,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
#include <asm/u-boot.h>
|
#include <asm/u-boot.h>
|
||||||
#include <nand.h>
|
#include <nand.h>
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <dm/root.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
@ -139,9 +141,16 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
|
|||||||
u32 boot_device;
|
u32 boot_device;
|
||||||
debug(">>spl:board_init_r()\n");
|
debug(">>spl:board_init_r()\n");
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_SPL_MALLOC_START
|
#if defined(CONFIG_SYS_SPL_MALLOC_START)
|
||||||
mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
|
mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
|
||||||
CONFIG_SYS_SPL_MALLOC_SIZE);
|
CONFIG_SYS_SPL_MALLOC_SIZE);
|
||||||
|
gd->flags |= GD_FLG_FULL_MALLOC_INIT;
|
||||||
|
#elif defined(CONFIG_SYS_MALLOC_F_LEN)
|
||||||
|
gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN;
|
||||||
|
gd->malloc_ptr = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SPL_DM
|
||||||
|
dm_init_and_scan(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_PPC
|
#ifndef CONFIG_PPC
|
||||||
@ -240,6 +249,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
|
|||||||
default:
|
default:
|
||||||
debug("Unsupported OS image.. Jumping nevertheless..\n");
|
debug("Unsupported OS image.. Jumping nevertheless..\n");
|
||||||
}
|
}
|
||||||
|
#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE)
|
||||||
|
debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
|
||||||
|
gd->malloc_ptr / 1024);
|
||||||
|
#endif
|
||||||
|
|
||||||
jump_to_image_no_args(&spl_image);
|
jump_to_image_no_args(&spl_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,20 +750,44 @@ device pointers, but this is not currently implemented (the root device
|
|||||||
pointer is saved but not made available through the driver model API).
|
pointer is saved but not made available through the driver model API).
|
||||||
|
|
||||||
|
|
||||||
|
SPL Support
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Driver model can operate in SPL. Its efficient implementation and small code
|
||||||
|
size provide for a small overhead which is acceptable for all but the most
|
||||||
|
constrained systems.
|
||||||
|
|
||||||
|
To enable driver model in SPL, define CONFIG_SPL_DM. You might want to
|
||||||
|
consider the following option also. See the main README for more details.
|
||||||
|
|
||||||
|
- CONFIG_SYS_MALLOC_SIMPLE
|
||||||
|
- CONFIG_DM_WARN
|
||||||
|
- CONFIG_DM_DEVICE_REMOVE
|
||||||
|
- CONFIG_DM_STDIO
|
||||||
|
|
||||||
|
|
||||||
|
Enabling Driver Model
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Driver model is being brought into U-Boot gradually. As each subsystems gets
|
||||||
|
support, a uclass is created and a CONFIG to enable use of driver model for
|
||||||
|
that subsystem.
|
||||||
|
|
||||||
|
For example CONFIG_DM_SERIAL enables driver model for serial. With that
|
||||||
|
defined, the old serial support is not enabled, and your serial driver must
|
||||||
|
conform to driver model. With that undefined, the old serial support is
|
||||||
|
enabled and driver model is not available for serial. This means that when
|
||||||
|
you convert a driver, you must either convert all its boards, or provide for
|
||||||
|
the driver to be compiled both with and without driver model (generally this
|
||||||
|
is not very hard).
|
||||||
|
|
||||||
|
See the main README for full details of the available driver model CONFIG
|
||||||
|
options.
|
||||||
|
|
||||||
|
|
||||||
Things to punt for later
|
Things to punt for later
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
- SPL support - this will have to be present before many drivers can be
|
|
||||||
converted, but it seems like we can add it once we are happy with the
|
|
||||||
core implementation.
|
|
||||||
|
|
||||||
That is not to say that no thinking has gone into this - in fact there
|
|
||||||
is quite a lot there. However, getting these right is non-trivial and
|
|
||||||
there is a high cost associated with going down the wrong path.
|
|
||||||
|
|
||||||
For SPL, it may be possible to fit in a simplified driver model with only
|
|
||||||
bind and probe methods, to reduce size.
|
|
||||||
|
|
||||||
Uclasses are statically numbered at compile time. It would be possible to
|
Uclasses are statically numbered at compile time. It would be possible to
|
||||||
change this to dynamic numbering, but then we would require some sort of
|
change this to dynamic numbering, but then we would require some sort of
|
||||||
lookup service, perhaps searching by name. This is slightly less efficient
|
lookup service, perhaps searching by name. This is slightly less efficient
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0+
|
# SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := device.o lists.o root.o uclass.o util.o
|
obj-$(CONFIG_DM) += device.o lists.o root.o uclass.o util.o
|
||||||
obj-$(CONFIG_OF_CONTROL) += simple-bus.o
|
obj-$(CONFIG_OF_CONTROL) += simple-bus.o
|
||||||
|
obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o
|
||||||
|
187
drivers/core/device-remove.c
Normal file
187
drivers/core/device-remove.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Device manager
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Google, Inc
|
||||||
|
*
|
||||||
|
* (C) Copyright 2012
|
||||||
|
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <dm/device.h>
|
||||||
|
#include <dm/device-internal.h>
|
||||||
|
#include <dm/uclass.h>
|
||||||
|
#include <dm/uclass-internal.h>
|
||||||
|
#include <dm/util.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_chld_unbind() - Unbind all device's children from the device
|
||||||
|
*
|
||||||
|
* On error, the function continues to unbind all children, and reports the
|
||||||
|
* first error.
|
||||||
|
*
|
||||||
|
* @dev: The device that is to be stripped of its children
|
||||||
|
* @return 0 on success, -ve on error
|
||||||
|
*/
|
||||||
|
static int device_chld_unbind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct udevice *pos, *n;
|
||||||
|
int ret, saved_ret = 0;
|
||||||
|
|
||||||
|
assert(dev);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
||||||
|
ret = device_unbind(pos);
|
||||||
|
if (ret && !saved_ret)
|
||||||
|
saved_ret = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return saved_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_chld_remove() - Stop all device's children
|
||||||
|
* @dev: The device whose children are to be removed
|
||||||
|
* @return 0 on success, -ve on error
|
||||||
|
*/
|
||||||
|
static int device_chld_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct udevice *pos, *n;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
assert(dev);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
||||||
|
ret = device_remove(pos);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int device_unbind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct driver *drv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (dev->flags & DM_FLAG_ACTIVATED)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
drv = dev->driver;
|
||||||
|
assert(drv);
|
||||||
|
|
||||||
|
if (drv->unbind) {
|
||||||
|
ret = drv->unbind(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = device_chld_unbind(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = uclass_unbind_device(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (dev->parent)
|
||||||
|
list_del(&dev->sibling_node);
|
||||||
|
free(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_free() - Free memory buffers allocated by a device
|
||||||
|
* @dev: Device that is to be started
|
||||||
|
*/
|
||||||
|
void device_free(struct udevice *dev)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
|
||||||
|
if (dev->driver->priv_auto_alloc_size) {
|
||||||
|
free(dev->priv);
|
||||||
|
dev->priv = NULL;
|
||||||
|
}
|
||||||
|
if (dev->flags & DM_FLAG_ALLOC_PDATA) {
|
||||||
|
free(dev->platdata);
|
||||||
|
dev->platdata = NULL;
|
||||||
|
}
|
||||||
|
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
|
||||||
|
if (size) {
|
||||||
|
free(dev->uclass_priv);
|
||||||
|
dev->uclass_priv = NULL;
|
||||||
|
}
|
||||||
|
if (dev->parent) {
|
||||||
|
size = dev->parent->driver->per_child_auto_alloc_size;
|
||||||
|
if (size) {
|
||||||
|
free(dev->parent_priv);
|
||||||
|
dev->parent_priv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int device_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct driver *drv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!(dev->flags & DM_FLAG_ACTIVATED))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
drv = dev->driver;
|
||||||
|
assert(drv);
|
||||||
|
|
||||||
|
ret = uclass_pre_remove_device(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = device_chld_remove(dev);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (drv->remove) {
|
||||||
|
ret = drv->remove(dev);
|
||||||
|
if (ret)
|
||||||
|
goto err_remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->parent && dev->parent->driver->child_post_remove) {
|
||||||
|
ret = dev->parent->driver->child_post_remove(dev);
|
||||||
|
if (ret) {
|
||||||
|
dm_warn("%s: Device '%s' failed child_post_remove()",
|
||||||
|
__func__, dev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device_free(dev);
|
||||||
|
|
||||||
|
dev->seq = -1;
|
||||||
|
dev->flags &= ~DM_FLAG_ACTIVATED;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err_remove:
|
||||||
|
/* We can't put the children back */
|
||||||
|
dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
|
||||||
|
__func__, dev->name);
|
||||||
|
err:
|
||||||
|
ret = uclass_post_probe_device(dev);
|
||||||
|
if (ret) {
|
||||||
|
dm_warn("%s: Device '%s' failed to post_probe on error path\n",
|
||||||
|
__func__, dev->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -24,52 +24,6 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/**
|
|
||||||
* device_chld_unbind() - Unbind all device's children from the device
|
|
||||||
*
|
|
||||||
* On error, the function continues to unbind all children, and reports the
|
|
||||||
* first error.
|
|
||||||
*
|
|
||||||
* @dev: The device that is to be stripped of its children
|
|
||||||
* @return 0 on success, -ve on error
|
|
||||||
*/
|
|
||||||
static int device_chld_unbind(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct udevice *pos, *n;
|
|
||||||
int ret, saved_ret = 0;
|
|
||||||
|
|
||||||
assert(dev);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
|
||||||
ret = device_unbind(pos);
|
|
||||||
if (ret && !saved_ret)
|
|
||||||
saved_ret = ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return saved_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* device_chld_remove() - Stop all device's children
|
|
||||||
* @dev: The device whose children are to be removed
|
|
||||||
* @return 0 on success, -ve on error
|
|
||||||
*/
|
|
||||||
static int device_chld_remove(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct udevice *pos, *n;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
assert(dev);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
|
||||||
ret = device_remove(pos);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int device_bind(struct udevice *parent, struct driver *drv, const char *name,
|
int device_bind(struct udevice *parent, struct driver *drv, const char *name,
|
||||||
void *platdata, int of_offset, struct udevice **devp)
|
void *platdata, int of_offset, struct udevice **devp)
|
||||||
{
|
{
|
||||||
@ -167,71 +121,6 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
|
|||||||
-1, devp);
|
-1, devp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_unbind(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct driver *drv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!dev)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (dev->flags & DM_FLAG_ACTIVATED)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
drv = dev->driver;
|
|
||||||
assert(drv);
|
|
||||||
|
|
||||||
if (drv->unbind) {
|
|
||||||
ret = drv->unbind(dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = device_chld_unbind(dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = uclass_unbind_device(dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (dev->parent)
|
|
||||||
list_del(&dev->sibling_node);
|
|
||||||
free(dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* device_free() - Free memory buffers allocated by a device
|
|
||||||
* @dev: Device that is to be started
|
|
||||||
*/
|
|
||||||
static void device_free(struct udevice *dev)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
|
|
||||||
if (dev->driver->priv_auto_alloc_size) {
|
|
||||||
free(dev->priv);
|
|
||||||
dev->priv = NULL;
|
|
||||||
}
|
|
||||||
if (dev->flags & DM_FLAG_ALLOC_PDATA) {
|
|
||||||
free(dev->platdata);
|
|
||||||
dev->platdata = NULL;
|
|
||||||
}
|
|
||||||
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
|
|
||||||
if (size) {
|
|
||||||
free(dev->uclass_priv);
|
|
||||||
dev->uclass_priv = NULL;
|
|
||||||
}
|
|
||||||
if (dev->parent) {
|
|
||||||
size = dev->parent->driver->per_child_auto_alloc_size;
|
|
||||||
if (size) {
|
|
||||||
free(dev->parent_priv);
|
|
||||||
dev->parent_priv = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int device_probe_child(struct udevice *dev, void *parent_priv)
|
int device_probe_child(struct udevice *dev, void *parent_priv)
|
||||||
{
|
{
|
||||||
struct driver *drv;
|
struct driver *drv;
|
||||||
@ -342,63 +231,6 @@ int device_probe(struct udevice *dev)
|
|||||||
return device_probe_child(dev, NULL);
|
return device_probe_child(dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_remove(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct driver *drv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!dev)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!(dev->flags & DM_FLAG_ACTIVATED))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
drv = dev->driver;
|
|
||||||
assert(drv);
|
|
||||||
|
|
||||||
ret = uclass_pre_remove_device(dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = device_chld_remove(dev);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (drv->remove) {
|
|
||||||
ret = drv->remove(dev);
|
|
||||||
if (ret)
|
|
||||||
goto err_remove;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->parent && dev->parent->driver->child_post_remove) {
|
|
||||||
ret = dev->parent->driver->child_post_remove(dev);
|
|
||||||
if (ret) {
|
|
||||||
dm_warn("%s: Device '%s' failed child_post_remove()",
|
|
||||||
__func__, dev->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
device_free(dev);
|
|
||||||
|
|
||||||
dev->seq = -1;
|
|
||||||
dev->flags &= ~DM_FLAG_ACTIVATED;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
err_remove:
|
|
||||||
/* We can't put the children back */
|
|
||||||
dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
|
|
||||||
__func__, dev->name);
|
|
||||||
err:
|
|
||||||
ret = uclass_post_probe_device(dev);
|
|
||||||
if (ret) {
|
|
||||||
dm_warn("%s: Device '%s' failed to post_probe on error path\n",
|
|
||||||
__func__, dev->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *dev_get_platdata(struct udevice *dev)
|
void *dev_get_platdata(struct udevice *dev)
|
||||||
{
|
{
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
@ -548,3 +380,13 @@ int device_find_next_child(struct udevice **devp)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct udevice *dev_get_parent(struct udevice *child)
|
||||||
|
{
|
||||||
|
return child->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong dev_get_of_data(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return dev->of_id->data;
|
||||||
|
}
|
||||||
|
@ -25,9 +25,6 @@ struct driver *lists_driver_lookup_name(const char *name)
|
|||||||
const int n_ents = ll_entry_count(struct driver, driver);
|
const int n_ents = ll_entry_count(struct driver, driver);
|
||||||
struct driver *entry;
|
struct driver *entry;
|
||||||
|
|
||||||
if (!drv || !n_ents)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (entry = drv; entry != drv + n_ents; entry++) {
|
for (entry = drv; entry != drv + n_ents; entry++) {
|
||||||
if (!strcmp(name, entry->name))
|
if (!strcmp(name, entry->name))
|
||||||
return entry;
|
return entry;
|
||||||
@ -44,9 +41,6 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
|
|||||||
const int n_ents = ll_entry_count(struct uclass_driver, uclass);
|
const int n_ents = ll_entry_count(struct uclass_driver, uclass);
|
||||||
struct uclass_driver *entry;
|
struct uclass_driver *entry;
|
||||||
|
|
||||||
if ((id == UCLASS_INVALID) || !uclass)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (entry = uclass; entry != uclass + n_ents; entry++) {
|
for (entry = uclass; entry != uclass + n_ents; entry++) {
|
||||||
if (entry->id == id)
|
if (entry->id == id)
|
||||||
return entry;
|
return entry;
|
||||||
@ -77,34 +71,60 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_bind_driver(struct udevice *parent, const char *drv_name,
|
||||||
|
const char *dev_name, struct udevice **devp)
|
||||||
|
{
|
||||||
|
struct driver *drv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
drv = lists_driver_lookup_name(drv_name);
|
||||||
|
if (!drv) {
|
||||||
|
printf("Cannot find driver '%s'\n", drv_name);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
ret = device_bind(parent, drv, dev_name, NULL, -1, devp);
|
||||||
|
if (ret) {
|
||||||
|
printf("Cannot create device named '%s' (err=%d)\n",
|
||||||
|
dev_name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OF_CONTROL
|
#ifdef CONFIG_OF_CONTROL
|
||||||
/**
|
/**
|
||||||
* driver_check_compatible() - Check if a driver is compatible with this node
|
* driver_check_compatible() - Check if a driver is compatible with this node
|
||||||
*
|
*
|
||||||
* @param blob: Device tree pointer
|
* @param blob: Device tree pointer
|
||||||
* @param offset: Offset of node in device tree
|
* @param offset: Offset of node in device tree
|
||||||
* @param of_matchL List of compatible strings to match
|
* @param of_match: List of compatible strings to match
|
||||||
|
* @param of_idp: Returns the match that was found
|
||||||
* @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node
|
* @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node
|
||||||
* does not have a compatible string, other error <0 if there is a device
|
* does not have a compatible string, other error <0 if there is a device
|
||||||
* tree error
|
* tree error
|
||||||
*/
|
*/
|
||||||
static int driver_check_compatible(const void *blob, int offset,
|
static int driver_check_compatible(const void *blob, int offset,
|
||||||
const struct udevice_id *of_match)
|
const struct udevice_id *of_match,
|
||||||
|
const struct udevice_id **of_idp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
*of_idp = NULL;
|
||||||
if (!of_match)
|
if (!of_match)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
while (of_match->compatible) {
|
while (of_match->compatible) {
|
||||||
ret = fdt_node_check_compatible(blob, offset,
|
ret = fdt_node_check_compatible(blob, offset,
|
||||||
of_match->compatible);
|
of_match->compatible);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
|
*of_idp = of_match;
|
||||||
return 0;
|
return 0;
|
||||||
else if (ret == -FDT_ERR_NOTFOUND)
|
} else if (ret == -FDT_ERR_NOTFOUND) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
else if (ret < 0)
|
} else if (ret < 0) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
of_match++;
|
of_match++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +136,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
|||||||
{
|
{
|
||||||
struct driver *driver = ll_entry_start(struct driver, driver);
|
struct driver *driver = ll_entry_start(struct driver, driver);
|
||||||
const int n_ents = ll_entry_count(struct driver, driver);
|
const int n_ents = ll_entry_count(struct driver, driver);
|
||||||
|
const struct udevice_id *id;
|
||||||
struct driver *entry;
|
struct driver *entry;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -127,7 +148,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
|||||||
if (devp)
|
if (devp)
|
||||||
*devp = NULL;
|
*devp = NULL;
|
||||||
for (entry = driver; entry != driver + n_ents; entry++) {
|
for (entry = driver; entry != driver + n_ents; entry++) {
|
||||||
ret = driver_check_compatible(blob, offset, entry->of_match);
|
ret = driver_check_compatible(blob, offset, entry->of_match,
|
||||||
|
&id);
|
||||||
name = fdt_get_name(blob, offset, NULL);
|
name = fdt_get_name(blob, offset, NULL);
|
||||||
if (ret == -ENOENT) {
|
if (ret == -ENOENT) {
|
||||||
continue;
|
continue;
|
||||||
@ -136,8 +158,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
|||||||
break;
|
break;
|
||||||
} else if (ret) {
|
} else if (ret) {
|
||||||
dm_warn("Device tree error at offset %d\n", offset);
|
dm_warn("Device tree error at offset %d\n", offset);
|
||||||
if (!result || ret != -ENOENT)
|
result = ret;
|
||||||
result = ret;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +168,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
|||||||
dm_warn("Error binding driver '%s'\n", entry->name);
|
dm_warn("Error binding driver '%s'\n", entry->name);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
|
dev->of_id = id;
|
||||||
found = true;
|
found = true;
|
||||||
if (devp)
|
if (devp)
|
||||||
*devp = dev;
|
*devp = dev;
|
||||||
|
@ -73,10 +73,8 @@ int dm_scan_platdata(bool pre_reloc_only)
|
|||||||
dm_warn("Some drivers were not found\n");
|
dm_warn("Some drivers were not found\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OF_CONTROL
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
#include <asm/arch/hardware.h>
|
#include <asm/arch/hardware.h>
|
||||||
#include <asm/arch/at91_pio.h>
|
#include <asm/arch/at91_pio.h>
|
||||||
#include <asm/arch/gpio.h>
|
|
||||||
|
#define GPIO_PER_BANK 32
|
||||||
|
|
||||||
static struct at91_port *at91_pio_get_port(unsigned port)
|
static struct at91_port *at91_pio_get_port(unsigned port)
|
||||||
{
|
{
|
||||||
@ -39,19 +42,25 @@ static struct at91_port *at91_pio_get_port(unsigned port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void at91_set_port_pullup(struct at91_port *at91_port, unsigned offset,
|
||||||
|
int use_pullup)
|
||||||
|
{
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
if (use_pullup)
|
||||||
|
writel(mask, &at91_port->puer);
|
||||||
|
else
|
||||||
|
writel(mask, &at91_port->pudr);
|
||||||
|
writel(mask, &at91_port->per);
|
||||||
|
}
|
||||||
|
|
||||||
int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
|
int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
|
||||||
{
|
{
|
||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK))
|
||||||
mask = 1 << pin;
|
at91_set_port_pullup(at91_port, pin, use_pullup);
|
||||||
if (use_pullup)
|
|
||||||
writel(1 << pin, &at91_port->puer);
|
|
||||||
else
|
|
||||||
writel(1 << pin, &at91_port->pudr);
|
|
||||||
writel(mask, &at91_port->per);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -64,7 +73,7 @@ int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->idr);
|
writel(mask, &at91_port->idr);
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
at91_set_pio_pullup(port, pin, use_pullup);
|
||||||
@ -82,7 +91,7 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->idr);
|
writel(mask, &at91_port->idr);
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
at91_set_pio_pullup(port, pin, use_pullup);
|
||||||
@ -108,7 +117,7 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->idr);
|
writel(mask, &at91_port->idr);
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
at91_set_pio_pullup(port, pin, use_pullup);
|
||||||
@ -135,7 +144,7 @@ int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->idr);
|
writel(mask, &at91_port->idr);
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
at91_set_pio_pullup(port, pin, use_pullup);
|
||||||
@ -157,7 +166,7 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->idr);
|
writel(mask, &at91_port->idr);
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
at91_set_pio_pullup(port, pin, use_pullup);
|
||||||
@ -172,6 +181,29 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_GPIO
|
||||||
|
static bool at91_get_port_output(struct at91_port *at91_port, int offset)
|
||||||
|
{
|
||||||
|
u32 mask, val;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
val = readl(&at91_port->osr);
|
||||||
|
return val & mask;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void at91_set_port_input(struct at91_port *at91_port, int offset,
|
||||||
|
int use_pullup)
|
||||||
|
{
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
writel(mask, &at91_port->idr);
|
||||||
|
at91_set_port_pullup(at91_port, offset, use_pullup);
|
||||||
|
writel(mask, &at91_port->odr);
|
||||||
|
writel(mask, &at91_port->per);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
|
* mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
|
||||||
* configure it for an input.
|
* configure it for an input.
|
||||||
@ -179,19 +211,29 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
|
|||||||
int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
|
int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
|
||||||
{
|
{
|
||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK))
|
||||||
mask = 1 << pin;
|
at91_set_port_input(at91_port, pin, use_pullup);
|
||||||
writel(mask, &at91_port->idr);
|
|
||||||
at91_set_pio_pullup(port, pin, use_pullup);
|
|
||||||
writel(mask, &at91_port->odr);
|
|
||||||
writel(mask, &at91_port->per);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void at91_set_port_output(struct at91_port *at91_port, int offset,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
writel(mask, &at91_port->idr);
|
||||||
|
writel(mask, &at91_port->pudr);
|
||||||
|
if (value)
|
||||||
|
writel(mask, &at91_port->sodr);
|
||||||
|
else
|
||||||
|
writel(mask, &at91_port->codr);
|
||||||
|
writel(mask, &at91_port->oer);
|
||||||
|
writel(mask, &at91_port->per);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mux the pin to the gpio controller (instead of "A" or "B" peripheral),
|
* mux the pin to the gpio controller (instead of "A" or "B" peripheral),
|
||||||
* and configure it for an output.
|
* and configure it for an output.
|
||||||
@ -199,19 +241,9 @@ int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
|
|||||||
int at91_set_pio_output(unsigned port, u32 pin, int value)
|
int at91_set_pio_output(unsigned port, u32 pin, int value)
|
||||||
{
|
{
|
||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (at91_port && (port < ATMEL_PIO_PORTS) && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK))
|
||||||
mask = 1 << pin;
|
at91_set_port_output(at91_port, pin, value);
|
||||||
writel(mask, &at91_port->idr);
|
|
||||||
writel(mask, &at91_port->pudr);
|
|
||||||
if (value)
|
|
||||||
writel(mask, &at91_port->sodr);
|
|
||||||
else
|
|
||||||
writel(mask, &at91_port->codr);
|
|
||||||
writel(mask, &at91_port->oer);
|
|
||||||
writel(mask, &at91_port->per);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -224,7 +256,7 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
if (is_on) {
|
if (is_on) {
|
||||||
#if defined(CPU_HAS_PIO3)
|
#if defined(CPU_HAS_PIO3)
|
||||||
@ -248,7 +280,7 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
if (is_on) {
|
if (is_on) {
|
||||||
writel(mask, &at91_port->ifscer);
|
writel(mask, &at91_port->ifscer);
|
||||||
@ -271,7 +303,7 @@ int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(mask, &at91_port->pudr);
|
writel(mask, &at91_port->pudr);
|
||||||
if (is_on)
|
if (is_on)
|
||||||
@ -291,7 +323,7 @@ int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
writel(readl(&at91_port->schmitt) | mask,
|
writel(readl(&at91_port->schmitt) | mask,
|
||||||
&at91_port->schmitt);
|
&at91_port->schmitt);
|
||||||
@ -310,7 +342,7 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
|
|||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK)) {
|
||||||
mask = 1 << pin;
|
mask = 1 << pin;
|
||||||
if (is_on)
|
if (is_on)
|
||||||
writel(mask, &at91_port->mder);
|
writel(mask, &at91_port->mder);
|
||||||
@ -321,41 +353,54 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void at91_set_port_value(struct at91_port *at91_port, int offset,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
if (value)
|
||||||
|
writel(mask, &at91_port->sodr);
|
||||||
|
else
|
||||||
|
writel(mask, &at91_port->codr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* assuming the pin is muxed as a gpio output, set its value.
|
* assuming the pin is muxed as a gpio output, set its value.
|
||||||
*/
|
*/
|
||||||
int at91_set_pio_value(unsigned port, unsigned pin, int value)
|
int at91_set_pio_value(unsigned port, unsigned pin, int value)
|
||||||
{
|
{
|
||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK))
|
||||||
mask = 1 << pin;
|
at91_set_port_value(at91_port, pin, value);
|
||||||
if (value)
|
|
||||||
writel(mask, &at91_port->sodr);
|
|
||||||
else
|
|
||||||
writel(mask, &at91_port->codr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int at91_get_port_value(struct at91_port *at91_port, int offset)
|
||||||
|
{
|
||||||
|
u32 pdsr = 0, mask;
|
||||||
|
|
||||||
|
mask = 1 << offset;
|
||||||
|
pdsr = readl(&at91_port->pdsr) & mask;
|
||||||
|
|
||||||
|
return pdsr != 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* read the pin's value (works even if it's not muxed as a gpio).
|
* read the pin's value (works even if it's not muxed as a gpio).
|
||||||
*/
|
*/
|
||||||
int at91_get_pio_value(unsigned port, unsigned pin)
|
int at91_get_pio_value(unsigned port, unsigned pin)
|
||||||
{
|
{
|
||||||
struct at91_port *at91_port = at91_pio_get_port(port);
|
struct at91_port *at91_port = at91_pio_get_port(port);
|
||||||
u32 pdsr = 0, mask;
|
|
||||||
|
|
||||||
if (at91_port && (pin < 32)) {
|
if (at91_port && (pin < GPIO_PER_BANK))
|
||||||
mask = 1 << pin;
|
return at91_get_port_value(at91_port, pin);
|
||||||
pdsr = readl(&at91_port->pdsr) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pdsr != 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_GPIO
|
||||||
/* Common GPIO API */
|
/* Common GPIO API */
|
||||||
|
|
||||||
int gpio_request(unsigned gpio, const char *label)
|
int gpio_request(unsigned gpio, const char *label)
|
||||||
@ -395,3 +440,91 @@ int gpio_set_value(unsigned gpio, int value)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_GPIO
|
||||||
|
|
||||||
|
struct at91_port_priv {
|
||||||
|
struct at91_port *regs;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* set GPIO pin 'gpio' as an input */
|
||||||
|
static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
at91_set_port_input(port->regs, offset, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set GPIO pin 'gpio' as an output, with polarity 'value' */
|
||||||
|
static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
at91_set_port_output(port->regs, offset, value);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read GPIO IN value of pin 'gpio' */
|
||||||
|
static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
return at91_get_port_value(port->regs, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write GPIO OUT value to pin 'gpio' */
|
||||||
|
static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
at91_set_port_value(port->regs, offset, value);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int at91_gpio_get_function(struct udevice *dev, unsigned offset)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
/* GPIOF_FUNC is not implemented yet */
|
||||||
|
if (at91_get_port_output(port->regs, offset))
|
||||||
|
return GPIOF_OUTPUT;
|
||||||
|
else
|
||||||
|
return GPIOF_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_gpio_ops gpio_at91_ops = {
|
||||||
|
.direction_input = at91_gpio_direction_input,
|
||||||
|
.direction_output = at91_gpio_direction_output,
|
||||||
|
.get_value = at91_gpio_get_value,
|
||||||
|
.set_value = at91_gpio_set_value,
|
||||||
|
.get_function = at91_gpio_get_function,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int at91_gpio_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct at91_port_priv *port = dev_get_priv(dev);
|
||||||
|
struct at91_port_platdata *plat = dev_get_platdata(dev);
|
||||||
|
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
|
||||||
|
|
||||||
|
uc_priv->bank_name = plat->bank_name;
|
||||||
|
uc_priv->gpio_count = GPIO_PER_BANK;
|
||||||
|
port->regs = (struct at91_port *)plat->base_addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(gpio_at91) = {
|
||||||
|
.name = "gpio_at91",
|
||||||
|
.id = UCLASS_GPIO,
|
||||||
|
.ops = &gpio_at91_ops,
|
||||||
|
.probe = at91_gpio_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct at91_port_priv),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
@ -701,6 +701,7 @@ static int cros_ec_check_version(struct cros_ec_dev *dev)
|
|||||||
|
|
||||||
/* Try sending a version 3 packet */
|
/* Try sending a version 3 packet */
|
||||||
dev->protocol_version = 3;
|
dev->protocol_version = 3;
|
||||||
|
req.in_data = 0;
|
||||||
if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
|
if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
|
||||||
(uint8_t **)&resp, sizeof(*resp)) > 0) {
|
(uint8_t **)&resp, sizeof(*resp)) > 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -602,14 +602,14 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum,
|
|||||||
spec, ret);
|
spec, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = device_find_child_by_seq(bus, cs, true, &slave);
|
ret = spi_find_chip_select(bus, cs, &slave);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
printf("Chip select %d already exists for spec '%s'\n", cs,
|
printf("Chip select %d already exists for spec '%s'\n", cs,
|
||||||
spec);
|
spec);
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_bind_device(bus, cs, "spi_flash_std", spec, &slave);
|
ret = device_bind_driver(bus, "spi_flash_std", spec, &slave);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -7,11 +7,16 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#ifdef CONFIG_DM_SERIAL
|
||||||
|
#include <asm/arch/atmel_serial.h>
|
||||||
|
#endif
|
||||||
#include <asm/arch/clk.h>
|
#include <asm/arch/clk.h>
|
||||||
#include <asm/arch/hardware.h>
|
#include <asm/arch/hardware.h>
|
||||||
|
|
||||||
@ -19,9 +24,9 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
static void atmel_serial_setbrg(void)
|
static void atmel_serial_setbrg_internal(atmel_usart3_t *usart, int id,
|
||||||
|
int baudrate)
|
||||||
{
|
{
|
||||||
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
|
|
||||||
unsigned long divisor;
|
unsigned long divisor;
|
||||||
unsigned long usart_hz;
|
unsigned long usart_hz;
|
||||||
|
|
||||||
@ -30,15 +35,13 @@ static void atmel_serial_setbrg(void)
|
|||||||
* Baud Rate = --------------
|
* Baud Rate = --------------
|
||||||
* 16 * CD
|
* 16 * CD
|
||||||
*/
|
*/
|
||||||
usart_hz = get_usart_clk_rate(CONFIG_USART_ID);
|
usart_hz = get_usart_clk_rate(id);
|
||||||
divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
|
divisor = (usart_hz / 16 + baudrate / 2) / baudrate;
|
||||||
writel(USART3_BF(CD, divisor), &usart->brgr);
|
writel(USART3_BF(CD, divisor), &usart->brgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_serial_init(void)
|
static void atmel_serial_init_internal(atmel_usart3_t *usart)
|
||||||
{
|
{
|
||||||
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just in case: drain transmitter register
|
* Just in case: drain transmitter register
|
||||||
* 1000us is enough for baudrate >= 9600
|
* 1000us is enough for baudrate >= 9600
|
||||||
@ -47,9 +50,10 @@ static int atmel_serial_init(void)
|
|||||||
__udelay(1000);
|
__udelay(1000);
|
||||||
|
|
||||||
writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
|
writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
|
||||||
|
}
|
||||||
|
|
||||||
serial_setbrg();
|
static void atmel_serial_activate(atmel_usart3_t *usart)
|
||||||
|
{
|
||||||
writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
|
writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
|
||||||
| USART3_BF(USCLKS, USART3_USCLKS_MCK)
|
| USART3_BF(USCLKS, USART3_USCLKS_MCK)
|
||||||
| USART3_BF(CHRL, USART3_CHRL_8)
|
| USART3_BF(CHRL, USART3_CHRL_8)
|
||||||
@ -59,6 +63,22 @@ static int atmel_serial_init(void)
|
|||||||
writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
|
writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
|
||||||
/* 100us is enough for the new settings to be settled */
|
/* 100us is enough for the new settings to be settled */
|
||||||
__udelay(100);
|
__udelay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_SERIAL
|
||||||
|
static void atmel_serial_setbrg(void)
|
||||||
|
{
|
||||||
|
atmel_serial_setbrg_internal((atmel_usart3_t *)CONFIG_USART_BASE,
|
||||||
|
CONFIG_USART_ID, gd->baudrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atmel_serial_init(void)
|
||||||
|
{
|
||||||
|
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
|
||||||
|
|
||||||
|
atmel_serial_init_internal(usart);
|
||||||
|
serial_setbrg();
|
||||||
|
atmel_serial_activate(usart);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -109,3 +129,81 @@ __weak struct serial_device *default_serial_console(void)
|
|||||||
{
|
{
|
||||||
return &atmel_serial_drv;
|
return &atmel_serial_drv;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_SERIAL
|
||||||
|
|
||||||
|
struct atmel_serial_priv {
|
||||||
|
atmel_usart3_t *usart;
|
||||||
|
};
|
||||||
|
|
||||||
|
int atmel_serial_setbrg(struct udevice *dev, int baudrate)
|
||||||
|
{
|
||||||
|
struct atmel_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
atmel_serial_setbrg_internal(priv->usart, 0 /* ignored */, baudrate);
|
||||||
|
atmel_serial_activate(priv->usart);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atmel_serial_getc(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct atmel_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
return readl(&priv->usart->rhr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atmel_serial_putc(struct udevice *dev, const char ch)
|
||||||
|
{
|
||||||
|
struct atmel_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (!(readl(&priv->usart->csr) & USART3_BIT(TXRDY)))
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
writel(ch, &priv->usart->thr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atmel_serial_pending(struct udevice *dev, bool input)
|
||||||
|
{
|
||||||
|
struct atmel_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
uint32_t csr = readl(&priv->usart->csr);
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
return csr & USART3_BIT(RXRDY) ? 1 : 0;
|
||||||
|
else
|
||||||
|
return csr & USART3_BIT(TXEMPTY) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_serial_ops atmel_serial_ops = {
|
||||||
|
.putc = atmel_serial_putc,
|
||||||
|
.pending = atmel_serial_pending,
|
||||||
|
.getc = atmel_serial_getc,
|
||||||
|
.setbrg = atmel_serial_setbrg,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int atmel_serial_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct atmel_serial_platdata *plat = dev->platdata;
|
||||||
|
struct atmel_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
priv->usart = (atmel_usart3_t *)plat->base_addr;
|
||||||
|
atmel_serial_init_internal(priv->usart);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(serial_atmel) = {
|
||||||
|
.name = "serial_atmel",
|
||||||
|
.id = UCLASS_SERIAL,
|
||||||
|
.probe = atmel_serial_probe,
|
||||||
|
.ops = &atmel_serial_ops,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct atmel_serial_priv),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <environment.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <os.h>
|
#include <os.h>
|
||||||
@ -19,6 +20,11 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table with supported baudrates (defined in config_xyz.h)
|
||||||
|
*/
|
||||||
|
static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
|
||||||
|
|
||||||
#ifndef CONFIG_SYS_MALLOC_F_LEN
|
#ifndef CONFIG_SYS_MALLOC_F_LEN
|
||||||
#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
|
#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
|
||||||
#endif
|
#endif
|
||||||
@ -160,10 +166,12 @@ void serial_stdio_init(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_STDIO
|
||||||
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
|
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
|
||||||
{
|
{
|
||||||
_serial_putc(sdev->priv, ch);
|
_serial_putc(sdev->priv, ch);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
|
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
|
||||||
{
|
{
|
||||||
@ -180,11 +188,74 @@ int serial_stub_tstc(struct stdio_dev *sdev)
|
|||||||
return _serial_tstc(sdev->priv);
|
return _serial_tstc(sdev->priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* on_baudrate() - Update the actual baudrate when the env var changes
|
||||||
|
*
|
||||||
|
* This will check for a valid baudrate and only apply it if valid.
|
||||||
|
*/
|
||||||
|
static int on_baudrate(const char *name, const char *value, enum env_op op,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int baudrate;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case env_op_create:
|
||||||
|
case env_op_overwrite:
|
||||||
|
/*
|
||||||
|
* Switch to new baudrate if new baudrate is supported
|
||||||
|
*/
|
||||||
|
baudrate = simple_strtoul(value, NULL, 10);
|
||||||
|
|
||||||
|
/* Not actually changing */
|
||||||
|
if (gd->baudrate == baudrate)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
|
||||||
|
if (baudrate == baudrate_table[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == ARRAY_SIZE(baudrate_table)) {
|
||||||
|
if ((flags & H_FORCE) == 0)
|
||||||
|
printf("## Baudrate %d bps not supported\n",
|
||||||
|
baudrate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((flags & H_INTERACTIVE) != 0) {
|
||||||
|
printf("## Switch baudrate to %d bps and press ENTER ...\n",
|
||||||
|
baudrate);
|
||||||
|
udelay(50000);
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->baudrate = baudrate;
|
||||||
|
|
||||||
|
serial_setbrg();
|
||||||
|
|
||||||
|
udelay(50000);
|
||||||
|
|
||||||
|
if ((flags & H_INTERACTIVE) != 0)
|
||||||
|
while (1) {
|
||||||
|
if (getc() == '\r')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case env_op_delete:
|
||||||
|
printf("## Baudrate may not be deleted\n");
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
|
||||||
|
|
||||||
static int serial_post_probe(struct udevice *dev)
|
static int serial_post_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct stdio_dev sdev;
|
|
||||||
struct dm_serial_ops *ops = serial_get_ops(dev);
|
struct dm_serial_ops *ops = serial_get_ops(dev);
|
||||||
|
#ifdef CONFIG_DM_STDIO
|
||||||
struct serial_dev_priv *upriv = dev->uclass_priv;
|
struct serial_dev_priv *upriv = dev->uclass_priv;
|
||||||
|
struct stdio_dev sdev;
|
||||||
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Set the baud rate */
|
/* Set the baud rate */
|
||||||
@ -194,9 +265,9 @@ static int serial_post_probe(struct udevice *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_STDIO
|
||||||
if (!(gd->flags & GD_FLG_RELOC))
|
if (!(gd->flags & GD_FLG_RELOC))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(&sdev, '\0', sizeof(sdev));
|
memset(&sdev, '\0', sizeof(sdev));
|
||||||
|
|
||||||
strncpy(sdev.name, dev->name, sizeof(sdev.name));
|
strncpy(sdev.name, dev->name, sizeof(sdev.name));
|
||||||
@ -207,7 +278,7 @@ static int serial_post_probe(struct udevice *dev)
|
|||||||
sdev.getc = serial_stub_getc;
|
sdev.getc = serial_stub_getc;
|
||||||
sdev.tstc = serial_stub_tstc;
|
sdev.tstc = serial_stub_tstc;
|
||||||
stdio_register_dev(&sdev, &upriv->sdev);
|
stdio_register_dev(&sdev, &upriv->sdev);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <ns16550.h>
|
#include <ns16550.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
static const struct udevice_id tegra_serial_ids[] = {
|
static const struct udevice_id tegra_serial_ids[] = {
|
||||||
{ .compatible = "nvidia,tegra20-uart" },
|
{ .compatible = "nvidia,tegra20-uart" },
|
||||||
{ }
|
{ }
|
||||||
@ -26,13 +27,28 @@ static int tegra_serial_ofdata_to_platdata(struct udevice *dev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
struct ns16550_platdata tegra_serial = {
|
||||||
|
.base = CONFIG_SYS_NS16550_COM1,
|
||||||
|
.reg_shift = 2,
|
||||||
|
.clock = V_NS16550_CLK,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DEVICE(ns16550_serial) = {
|
||||||
|
"serial_tegra20", &tegra_serial
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
U_BOOT_DRIVER(serial_ns16550) = {
|
U_BOOT_DRIVER(serial_ns16550) = {
|
||||||
.name = "serial_tegra20",
|
.name = "serial_tegra20",
|
||||||
.id = UCLASS_SERIAL,
|
.id = UCLASS_SERIAL,
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
.of_match = tegra_serial_ids,
|
.of_match = tegra_serial_ids,
|
||||||
.ofdata_to_platdata = tegra_serial_ofdata_to_platdata,
|
.ofdata_to_platdata = tegra_serial_ofdata_to_platdata,
|
||||||
.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
|
.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
|
||||||
|
#endif
|
||||||
.priv_auto_alloc_size = sizeof(struct NS16550),
|
.priv_auto_alloc_size = sizeof(struct NS16550),
|
||||||
.probe = ns16550_serial_probe,
|
.probe = ns16550_serial_probe,
|
||||||
.ops = &ns16550_serial_ops,
|
.ops = &ns16550_serial_ops,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
};
|
};
|
||||||
|
@ -115,16 +115,7 @@ int spi_chip_select(struct udevice *dev)
|
|||||||
return slave ? slave->cs : -ENOENT;
|
return slave ? slave->cs : -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
|
||||||
* spi_find_chip_select() - Find the slave attached to chip select
|
|
||||||
*
|
|
||||||
* @bus: SPI bus to search
|
|
||||||
* @cs: Chip select to look for
|
|
||||||
* @devp: Returns the slave device if found
|
|
||||||
* @return 0 if found, -ENODEV on error
|
|
||||||
*/
|
|
||||||
static int spi_find_chip_select(struct udevice *bus, int cs,
|
|
||||||
struct udevice **devp)
|
|
||||||
{
|
{
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
||||||
@ -197,27 +188,6 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
|
|
||||||
const char *dev_name, struct udevice **devp)
|
|
||||||
{
|
|
||||||
struct driver *drv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
drv = lists_driver_lookup_name(drv_name);
|
|
||||||
if (!drv) {
|
|
||||||
printf("Cannot find driver '%s'\n", drv_name);
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
ret = device_bind(bus, drv, dev_name, NULL, -1, devp);
|
|
||||||
if (ret) {
|
|
||||||
printf("Cannot create device named '%s' (err=%d)\n",
|
|
||||||
dev_name, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
|
int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
|
||||||
struct udevice **devp)
|
struct udevice **devp)
|
||||||
{
|
{
|
||||||
@ -264,7 +234,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
|
|||||||
if (ret == -ENODEV && drv_name) {
|
if (ret == -ENODEV && drv_name) {
|
||||||
debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
|
debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
|
||||||
__func__, dev_name, busnum, cs, drv_name);
|
__func__, dev_name, busnum, cs, drv_name);
|
||||||
ret = spi_bind_device(bus, cs, drv_name, dev_name, &dev);
|
ret = device_bind_driver(bus, drv_name, dev_name, &dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
created = true;
|
created = true;
|
||||||
|
@ -108,5 +108,6 @@ typedef struct global_data {
|
|||||||
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
|
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
|
||||||
#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */
|
#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */
|
||||||
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */
|
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */
|
||||||
|
#define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */
|
||||||
|
|
||||||
#endif /* __ASM_GENERIC_GBL_DATA_H */
|
#endif /* __ASM_GENERIC_GBL_DATA_H */
|
||||||
|
@ -20,4 +20,10 @@
|
|||||||
#define CONFIG_ZLIB 1
|
#define CONFIG_ZLIB 1
|
||||||
#define CONFIG_PARTITIONS 1
|
#define CONFIG_PARTITIONS 1
|
||||||
|
|
||||||
|
#ifndef CONFIG_SPL_BUILD
|
||||||
|
#define CONFIG_DM_WARN
|
||||||
|
#define CONFIG_DM_DEVICE_REMOVE
|
||||||
|
#define CONFIG_DM_STDIO
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,11 +15,17 @@
|
|||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
|
||||||
#define CONFIG_SYS_TEXT_BASE 0x20000000
|
#define CONFIG_SYS_TEXT_BASE 0x21f00000
|
||||||
|
|
||||||
/* ARM asynchronous clock */
|
/* ARM asynchronous clock */
|
||||||
#define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* External Crystal, in Hz */
|
#define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* External Crystal, in Hz */
|
||||||
#define CONFIG_SYS_AT91_SLOW_CLOCK 32768
|
#define CONFIG_SYS_AT91_SLOW_CLOCK 32768
|
||||||
|
#define CONFIG_SYS_GENERIC_BOARD
|
||||||
|
#define CONFIG_DM
|
||||||
|
#define CONFIG_CMD_DM
|
||||||
|
#define CONFIG_DM_GPIO
|
||||||
|
#define CONFIG_DM_SERIAL
|
||||||
|
#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
|
||||||
|
|
||||||
/* CPU */
|
/* CPU */
|
||||||
#define CONFIG_ARCH_CPU_INIT
|
#define CONFIG_ARCH_CPU_INIT
|
||||||
@ -84,8 +90,10 @@
|
|||||||
|
|
||||||
/* UARTs/Serial console */
|
/* UARTs/Serial console */
|
||||||
#define CONFIG_ATMEL_USART
|
#define CONFIG_ATMEL_USART
|
||||||
|
#ifndef CONFIG_DM_SERIAL
|
||||||
#define CONFIG_USART_BASE ATMEL_BASE_DBGU
|
#define CONFIG_USART_BASE ATMEL_BASE_DBGU
|
||||||
#define CONFIG_USART_ID ATMEL_ID_SYS
|
#define CONFIG_USART_ID ATMEL_ID_SYS
|
||||||
|
#endif
|
||||||
#define CONFIG_BAUDRATE 115200
|
#define CONFIG_BAUDRATE 115200
|
||||||
#define CONFIG_SYS_PROMPT "Snapper> "
|
#define CONFIG_SYS_PROMPT "Snapper> "
|
||||||
|
|
||||||
@ -159,7 +167,7 @@
|
|||||||
#define CONFIG_CMD_DHCP
|
#define CONFIG_CMD_DHCP
|
||||||
#define CONFIG_CMD_FAT
|
#define CONFIG_CMD_FAT
|
||||||
#define CONFIG_CMD_I2C
|
#define CONFIG_CMD_I2C
|
||||||
#undef CONFIG_CMD_GPIO
|
#define CONFIG_CMD_GPIO
|
||||||
#define CONFIG_CMD_USB
|
#define CONFIG_CMD_USB
|
||||||
#define CONFIG_CMD_MII
|
#define CONFIG_CMD_MII
|
||||||
#define CONFIG_CMD_NAND
|
#define CONFIG_CMD_NAND
|
||||||
|
@ -118,7 +118,9 @@
|
|||||||
#define CONFIG_SYS_MEMTEST_START (NV_PA_SDRC_CS0 + 0x600000)
|
#define CONFIG_SYS_MEMTEST_START (NV_PA_SDRC_CS0 + 0x600000)
|
||||||
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x100000)
|
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x100000)
|
||||||
|
|
||||||
|
#ifndef CONFIG_SPL_BUILD
|
||||||
#define CONFIG_USE_ARCH_MEMCPY
|
#define CONFIG_USE_ARCH_MEMCPY
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
* Physical Memory Map
|
* Physical Memory Map
|
||||||
|
@ -87,7 +87,11 @@ int device_probe_child(struct udevice *dev, void *parent_priv);
|
|||||||
* @dev: Pointer to device to remove
|
* @dev: Pointer to device to remove
|
||||||
* @return 0 if OK, -ve on error (an error here is normally a very bad thing)
|
* @return 0 if OK, -ve on error (an error here is normally a very bad thing)
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||||
int device_remove(struct udevice *dev);
|
int device_remove(struct udevice *dev);
|
||||||
|
#else
|
||||||
|
static inline int device_remove(struct udevice *dev) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_unbind() - Unbind a device, destroying it
|
* device_unbind() - Unbind a device, destroying it
|
||||||
@ -99,6 +103,12 @@ int device_remove(struct udevice *dev);
|
|||||||
*/
|
*/
|
||||||
int device_unbind(struct udevice *dev);
|
int device_unbind(struct udevice *dev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||||
|
void device_free(struct udevice *dev);
|
||||||
|
#else
|
||||||
|
static inline void device_free(struct udevice *dev) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Cast away any volatile pointer */
|
/* Cast away any volatile pointer */
|
||||||
#define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root)
|
#define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root)
|
||||||
#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)
|
#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)
|
||||||
|
@ -47,6 +47,7 @@ struct driver_info;
|
|||||||
* @name: Name of device, typically the FDT node name
|
* @name: Name of device, typically the FDT node name
|
||||||
* @platdata: Configuration data for this device
|
* @platdata: Configuration data for this device
|
||||||
* @of_offset: Device tree node offset for this device (- for none)
|
* @of_offset: Device tree node offset for this device (- for none)
|
||||||
|
* @of_id: Pointer to the udevice_id structure which created the device
|
||||||
* @parent: Parent of this device, or NULL for the top level device
|
* @parent: Parent of this device, or NULL for the top level device
|
||||||
* @priv: Private data for this device
|
* @priv: Private data for this device
|
||||||
* @uclass: Pointer to uclass for this device
|
* @uclass: Pointer to uclass for this device
|
||||||
@ -65,6 +66,7 @@ struct udevice {
|
|||||||
const char *name;
|
const char *name;
|
||||||
void *platdata;
|
void *platdata;
|
||||||
int of_offset;
|
int of_offset;
|
||||||
|
const struct udevice_id *of_id;
|
||||||
struct udevice *parent;
|
struct udevice *parent;
|
||||||
void *priv;
|
void *priv;
|
||||||
struct uclass *uclass;
|
struct uclass *uclass;
|
||||||
@ -205,6 +207,23 @@ void *dev_get_parentdata(struct udevice *dev);
|
|||||||
*/
|
*/
|
||||||
void *dev_get_priv(struct udevice *dev);
|
void *dev_get_priv(struct udevice *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct dev_get_parent() - Get the parent of a device
|
||||||
|
*
|
||||||
|
* @child: Child to check
|
||||||
|
* @return parent of child, or NULL if this is the root device
|
||||||
|
*/
|
||||||
|
struct udevice *dev_get_parent(struct udevice *child);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_get_of_data() - get the device tree data used to bind a device
|
||||||
|
*
|
||||||
|
* When a device is bound using a device tree node, it matches a
|
||||||
|
* particular compatible string as in struct udevice_id. This function
|
||||||
|
* returns the associated data value for that compatible string
|
||||||
|
*/
|
||||||
|
ulong dev_get_of_data(struct udevice *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_get_child() - Get the child of a device by index
|
* device_get_child() - Get the child of a device by index
|
||||||
*
|
*
|
||||||
|
@ -60,4 +60,17 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
|
|||||||
int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
|
||||||
struct udevice **devp);
|
struct udevice **devp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_bind_driver() - bind a device to a driver
|
||||||
|
*
|
||||||
|
* This binds a new device to a driver.
|
||||||
|
*
|
||||||
|
* @parent: Parent device
|
||||||
|
* @drv_name: Name of driver to attach to this parent
|
||||||
|
* @dev_name: Name of the new device thus created
|
||||||
|
* @devp: Returns the newly bound device
|
||||||
|
*/
|
||||||
|
int device_bind_driver(struct udevice *parent, const char *drv_name,
|
||||||
|
const char *dev_name, struct udevice **devp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,13 @@
|
|||||||
#ifndef __DM_UTIL_H
|
#ifndef __DM_UTIL_H
|
||||||
#define __DM_UTIL_H
|
#define __DM_UTIL_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_WARN
|
||||||
void dm_warn(const char *fmt, ...);
|
void dm_warn(const char *fmt, ...);
|
||||||
|
#else
|
||||||
|
static inline void dm_warn(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void dm_dbg(const char *fmt, ...);
|
void dm_dbg(const char *fmt, ...);
|
||||||
|
@ -872,33 +872,46 @@ extern Void_t* sbrk();
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef USE_DL_PREFIX
|
#ifdef CONFIG_SYS_MALLOC_SIMPLE
|
||||||
#define cALLOc dlcalloc
|
#define malloc malloc_simple
|
||||||
#define fREe dlfree
|
#define realloc realloc_simple
|
||||||
#define mALLOc dlmalloc
|
#define memalign memalign_simple
|
||||||
#define mEMALIGn dlmemalign
|
static inline void free(void *ptr) {}
|
||||||
#define rEALLOc dlrealloc
|
void *calloc(size_t nmemb, size_t size);
|
||||||
#define vALLOc dlvalloc
|
void *memalign_simple(size_t alignment, size_t bytes);
|
||||||
#define pvALLOc dlpvalloc
|
void *realloc_simple(void *ptr, size_t size);
|
||||||
#define mALLINFo dlmallinfo
|
#else
|
||||||
#define mALLOPt dlmallopt
|
|
||||||
#else /* USE_DL_PREFIX */
|
# ifdef USE_DL_PREFIX
|
||||||
#define cALLOc calloc
|
# define cALLOc dlcalloc
|
||||||
#define fREe free
|
# define fREe dlfree
|
||||||
#define mALLOc malloc
|
# define mALLOc dlmalloc
|
||||||
#define mEMALIGn memalign
|
# define mEMALIGn dlmemalign
|
||||||
#define rEALLOc realloc
|
# define rEALLOc dlrealloc
|
||||||
#define vALLOc valloc
|
# define vALLOc dlvalloc
|
||||||
#define pvALLOc pvalloc
|
# define pvALLOc dlpvalloc
|
||||||
#define mALLINFo mallinfo
|
# define mALLINFo dlmallinfo
|
||||||
#define mALLOPt mallopt
|
# define mALLOPt dlmallopt
|
||||||
#endif /* USE_DL_PREFIX */
|
# else /* USE_DL_PREFIX */
|
||||||
|
# define cALLOc calloc
|
||||||
|
# define fREe free
|
||||||
|
# define mALLOc malloc
|
||||||
|
# define mEMALIGn memalign
|
||||||
|
# define rEALLOc realloc
|
||||||
|
# define vALLOc valloc
|
||||||
|
# define pvALLOc pvalloc
|
||||||
|
# define mALLINFo mallinfo
|
||||||
|
# define mALLOPt mallopt
|
||||||
|
# endif /* USE_DL_PREFIX */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Public routines */
|
/* Public routines */
|
||||||
|
|
||||||
#if __STD_C
|
/* Simple versions which can be used when space is tight */
|
||||||
|
void *malloc_simple(size_t size);
|
||||||
|
|
||||||
|
# if __STD_C
|
||||||
|
|
||||||
Void_t* mALLOc(size_t);
|
Void_t* mALLOc(size_t);
|
||||||
void fREe(Void_t*);
|
void fREe(Void_t*);
|
||||||
@ -913,7 +926,7 @@ size_t malloc_usable_size(Void_t*);
|
|||||||
void malloc_stats(void);
|
void malloc_stats(void);
|
||||||
int mALLOPt(int, int);
|
int mALLOPt(int, int);
|
||||||
struct mallinfo mALLINFo(void);
|
struct mallinfo mALLINFo(void);
|
||||||
#else
|
# else
|
||||||
Void_t* mALLOc();
|
Void_t* mALLOc();
|
||||||
void fREe();
|
void fREe();
|
||||||
Void_t* rEALLOc();
|
Void_t* rEALLOc();
|
||||||
@ -927,6 +940,7 @@ size_t malloc_usable_size();
|
|||||||
void malloc_stats();
|
void malloc_stats();
|
||||||
int mALLOPt();
|
int mALLOPt();
|
||||||
struct mallinfo mALLINFo();
|
struct mallinfo mALLINFo();
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -534,18 +534,14 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
|
|||||||
int spi_chip_select(struct udevice *slave);
|
int spi_chip_select(struct udevice *slave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spi_bind_device() - bind a device to a bus's chip select
|
* spi_find_chip_select() - Find the slave attached to chip select
|
||||||
*
|
|
||||||
* This binds a new device to an given chip select (which must be unused).
|
|
||||||
*
|
*
|
||||||
* @bus: SPI bus to search
|
* @bus: SPI bus to search
|
||||||
* @cs: Chip select to attach to
|
* @cs: Chip select to look for
|
||||||
* @drv_name: Name of driver to attach to this chip select
|
* @devp: Returns the slave device if found
|
||||||
* @dev_name: Name of the new device thus created
|
* @return 0 if found, -ENODEV on error
|
||||||
* @devp: Returns the newly bound device
|
|
||||||
*/
|
*/
|
||||||
int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
|
int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp);
|
||||||
const char *dev_name, struct udevice **devp);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spi_ofdata_to_platdata() - decode standard SPI platform data
|
* spi_ofdata_to_platdata() - decode standard SPI platform data
|
||||||
|
@ -357,9 +357,9 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
|
|||||||
slash = strrchr(prop, '/');
|
slash = strrchr(prop, '/');
|
||||||
if (strcmp(slash + 1, find_name))
|
if (strcmp(slash + 1, find_name))
|
||||||
continue;
|
continue;
|
||||||
for (p = name; *p; p++) {
|
for (p = name + strlen(name) - 1; p > name; p--) {
|
||||||
if (isdigit(*p)) {
|
if (!isdigit(*p)) {
|
||||||
*seqp = simple_strtoul(p, NULL, 10);
|
*seqp = simple_strtoul(p + 1, NULL, 10);
|
||||||
debug("Found seq %d\n", *seqp);
|
debug("Found seq %d\n", *seqp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
|
|||||||
libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
|
libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
|
||||||
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/
|
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/
|
||||||
libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
|
libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
|
||||||
|
libs-$(CONFIG_SPL_DM) += drivers/core/
|
||||||
libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/
|
libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/
|
||||||
libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/
|
libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/
|
||||||
libs-$(CONFIG_SPL_MMC_SUPPORT) += drivers/mmc/
|
libs-$(CONFIG_SPL_MMC_SUPPORT) += drivers/mmc/
|
||||||
|
Loading…
Reference in New Issue
Block a user