All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
@ 2015-06-23 21:38 Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command Simon Glass
                   ` (55 more replies)
  0 siblings, 56 replies; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot


This series adds several new uclasses. Some of these have been discussed
for a while. All are fairly simple and just provide enough functionality for
existing use cases. The following are included in this series:

- Clocks - setting and getting PLL and peripheral clocks
- Pinctrl - adjusting pin multiplexing settings
- Reset - reseting the board or SoC
- RAM - setting up RAM controllers and detecting the available RAM
- MMC - MMC controllers (using the existing block device framework)
- LEDs - turning LEDs on and off, with only a GPIO driver so far

Trivial support is also added for regmap and syscon controllers, modelled
on how the kernel does this.

This builds on the SPL device tree support which was recently added.

One problem with device tree is that U-Boot has no way of dropping features
it does not need or use. For SPL this problem needs to be solved and this
series uses a new 'fdtgrep' tool for this. The 45KB Firefly device tree
reduces to a 6KB bytes when unused material is removed. SDRAM timings are
also in the device tree.

This series includes some changes aimed at reduce code size in SPL,
including:
- dropping alias sequence support (the aliases node) since many boards just
use a single UART in SPL
- adding a smaller panic() function that does not support printf()-format
strings
- removing device unbind code which will never be used in SPL

Changes in v3:
- Use case-insensitve compare for image params (fixes build break with m53evk)
- Fix indentation in function comment
- Convert hex number to upper case to keep bc happy
- Split this series apart from the Rockchip series

Changes in v2:
- Add new patch to remove unused strings from a device tree
- Add new patch with fdt_first/next_region() functions
- Tidy up commit message a little
- Add new patch with fdtgrep tool
- Add new patch to reduce SPL device tree size with fdtgrep

Simon Glass (54):
  Add a dhrystone benchmark command
  sandbox: Enable dhry command
  mkimage: Display a better list of available image types
  fdt: Add a function to remove unused strings from a device tree
  fdt: Add fdt_first/next_region() functions
  fdt: Add fdtgrep tool
  dm: Reduce SPL device tree size
  dm: arm: Put driver model I2C drivers before legacy ones
  Add a way of checking the position of a structure member
  debug_uart: Remove use of asmlinkage
  dm: Allow debug UART to support an early console
  sandbox: Drop special-case sandbox console code
  dm: Move the tree/uclass dump code into its own file
  dm: core: Use debug() instead of printf() for failures
  dm: core: Add a function to find any device from device tree
  dm: core: Correct device_get_child_by_of_offset() parameter
  dm: gpio: Allow GPIO uclass to be used in SPL
  dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name
  dm: gpio: Add dm_gpio_request() to manually request a GPIO
  dm: Add support for register maps (regmap)
  dm: Add support for generic system controllers (syscon)
  dm: Correct the missing method check in cpu_get_info()
  dm: Add support for LEDs
  dm: led: Add a driver for GPIO-controlled LEDs
  spl: Add debugging info for spl_mmc boot
  dm: mmc: Add an MMC uclass
  mmc: Avoid using printf() for errors
  mmc: Add debug() output on read errors
  dm: mmc: Allow driver model to be used for MMC in SPL
  mmc: Add structure comments for dwmmc
  mmc: Support bypass mode with the get_mmc_clk() method
  mmc: Calculate dwmmc FIFO threshold size if not provided
  dm: Add basic support for pin multiplexing (pinctrl)
  dm: power: Avoid case-insensitve match for child names
  dm: power: Add regulator flags to centralise auto-set logic
  dm: pmic: Split output from function
  dm: power: Add a function to set up all regulators
  dm: power: Use debug() for errors in regulator uclass
  dm: pmic: Add functions to adjust PMIC registers
  dm: power: Allow use of regulators in SPL
  Drop CONFIG_ERRNO_STR from SPL
  dm: Add support for RAM drivers
  dm: spi: Make local functions static
  ns16550: Improve debug UART so it can work with 32-bit access
  Add rivest cipher 4 (rc4) implementation
  lib: Add function to extract a number from the end of a string
  fdt: Provide debug info when a device tree cannot be found
  dm: spl: Allow device tree/driver model in board_init_f()
  spl: Add a debug string before the jump to U-Boot
  mkimage: Set up a file size parameter and keep it updated
  dm: Add a system reset uclass
  zynq: Rename struct clk_ops to zynq_clk_ops
  dm: Add a clock uclass
  power: pmic: Use trailing_strtol() instead of a local function

 Makefile                                    |    2 +-
 arch/arm/cpu/u-boot-spl.lds                 |   12 +-
 arch/arm/mach-zynq/clk.c                    |    6 +-
 common/console.c                            |   25 +-
 common/image.c                              |   58 +-
 common/spl/spl.c                            |   36 +-
 common/spl/spl_mmc.c                        |   26 +-
 configs/sandbox_defconfig                   |    1 +
 doc/device-tree-bindings/leds/common.txt    |   23 +
 doc/device-tree-bindings/leds/leds-gpio.txt |   52 ++
 drivers/Kconfig                             |    8 +
 drivers/Makefile                            |    4 +
 drivers/clk/Kconfig                         |   19 +
 drivers/clk/Makefile                        |    8 +
 drivers/clk/clk-uclass.c                    |   58 ++
 drivers/core/Makefile                       |    3 +
 drivers/core/device.c                       |   29 +-
 drivers/core/dump.c                         |   96 +++
 drivers/core/lists.c                        |    6 +-
 drivers/core/regmap.c                       |   86 ++
 drivers/core/syscon-uclass.c                |   73 ++
 drivers/cpu/cpu-uclass.c                    |    2 +-
 drivers/gpio/Makefile                       |    4 -
 drivers/gpio/gpio-uclass.c                  |   36 +-
 drivers/led/Kconfig                         |   26 +
 drivers/led/Makefile                        |    9 +
 drivers/led/led-uclass.c                    |   48 ++
 drivers/led/led_gpio.c                      |  101 +++
 drivers/misc/Kconfig                        |    9 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/reset-uclass.c                 |   62 ++
 drivers/mmc/Kconfig                         |   10 +
 drivers/mmc/Makefile                        |    2 +
 drivers/mmc/dw_mmc.c                        |   33 +-
 drivers/mmc/exynos_dw_mmc.c                 |    2 +-
 drivers/mmc/mmc-uclass.c                    |   34 +
 drivers/mmc/mmc.c                           |   10 +-
 drivers/pinctrl/Kconfig                     |   19 +
 drivers/pinctrl/Makefile                    |    8 +
 drivers/pinctrl/pinctrl-uclass.c            |   51 ++
 drivers/power/pmic/pmic-uclass.c            |   57 +-
 drivers/power/regulator/regulator-uclass.c  |  134 +--
 drivers/ram/Kconfig                         |   18 +
 drivers/ram/Makefile                        |    7 +
 drivers/ram/ram-uclass.c                    |   28 +
 drivers/serial/ns16550.c                    |   36 +-
 drivers/spi/spi-uclass.c                    |    8 +-
 dts/Kconfig                                 |   12 +
 include/asm-generic/global_data.h           |    1 +
 include/asm-generic/gpio.h                  |   25 +
 include/clk.h                               |   80 ++
 include/common.h                            |   11 +
 include/debug_uart.h                        |   22 +-
 include/dm/device.h                         |   16 +-
 include/dm/uclass-id.h                      |    7 +
 include/dm/util.h                           |    6 +
 include/dwmmc.h                             |   34 +-
 include/image.h                             |   11 +
 include/led.h                               |   51 ++
 include/libfdt.h                            |  256 +++++-
 include/mmc.h                               |   22 +
 include/pinctrl.h                           |   74 ++
 include/power/pmic.h                        |   34 +
 include/power/regulator.h                   |   53 +-
 include/power/sandbox_pmic.h                |    4 +-
 include/ram.h                               |   38 +
 include/rc4.h                               |   21 +
 include/regmap.h                            |   72 ++
 include/reset.h                             |   62 ++
 include/spl.h                               |   12 +
 include/syscon.h                            |   56 ++
 include/vsprintf.h                          |   26 +
 lib/Kconfig                                 |    2 +
 lib/Makefile                                |    5 +-
 lib/dhry/Kconfig                            |    7 +
 lib/dhry/Makefile                           |    7 +
 lib/dhry/cmd_dhry.c                         |   34 +
 lib/dhry/dhry.h                             |  442 ++++++++++
 lib/dhry/dhry_1.c                           |  421 +++++++++
 lib/dhry/dhry_2.c                           |  217 +++++
 lib/fdtdec.c                                |   21 +-
 lib/libfdt/Makefile                         |    2 +-
 lib/libfdt/fdt_region.c                     |  492 +++++++++++
 lib/libfdt/fdt_rw.c                         |   32 +
 lib/rc4.c                                   |   49 ++
 lib/vsprintf.c                              |   19 +
 scripts/Makefile.spl                        |   33 +
 test/dm/cmd_dm.c                            |   82 +-
 test/dm/regulator.c                         |    2 +-
 tools/Makefile                              |    6 +-
 tools/fdtgrep.c                             | 1234 +++++++++++++++++++++++++++
 tools/imagetool.h                           |    1 +
 tools/mkimage.c                             |   77 +-
 93 files changed, 5259 insertions(+), 318 deletions(-)
 create mode 100644 doc/device-tree-bindings/leds/common.txt
 create mode 100644 doc/device-tree-bindings/leds/leds-gpio.txt
 create mode 100644 drivers/clk/Kconfig
 create mode 100644 drivers/clk/Makefile
 create mode 100644 drivers/clk/clk-uclass.c
 create mode 100644 drivers/core/dump.c
 create mode 100644 drivers/core/regmap.c
 create mode 100644 drivers/core/syscon-uclass.c
 create mode 100644 drivers/led/Kconfig
 create mode 100644 drivers/led/Makefile
 create mode 100644 drivers/led/led-uclass.c
 create mode 100644 drivers/led/led_gpio.c
 create mode 100644 drivers/misc/reset-uclass.c
 create mode 100644 drivers/mmc/mmc-uclass.c
 create mode 100644 drivers/pinctrl/Kconfig
 create mode 100644 drivers/pinctrl/Makefile
 create mode 100644 drivers/pinctrl/pinctrl-uclass.c
 create mode 100644 drivers/ram/Kconfig
 create mode 100644 drivers/ram/Makefile
 create mode 100644 drivers/ram/ram-uclass.c
 create mode 100644 include/led.h
 create mode 100644 include/pinctrl.h
 create mode 100644 include/ram.h
 create mode 100644 include/rc4.h
 create mode 100644 include/regmap.h
 create mode 100644 include/reset.h
 create mode 100644 include/syscon.h
 create mode 100644 lib/dhry/Kconfig
 create mode 100644 lib/dhry/Makefile
 create mode 100644 lib/dhry/cmd_dhry.c
 create mode 100644 lib/dhry/dhry.h
 create mode 100644 lib/dhry/dhry_1.c
 create mode 100644 lib/dhry/dhry_2.c
 create mode 100644 lib/libfdt/fdt_region.c
 create mode 100644 lib/rc4.c
 create mode 100644 tools/fdtgrep.c

-- 
2.4.3.573.g4eafbef

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command Simon Glass
                   ` (54 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Drystone provides a convenient sanity check that the CPU is running at full
speed. Add this as a command which can be enabled as needed.

Note: I investigated using Coremark for this but there was a license
agreement and I could not work out if it was GPL-compatible.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 lib/Kconfig         |   2 +
 lib/Makefile        |   2 +
 lib/dhry/Kconfig    |   7 +
 lib/dhry/Makefile   |   7 +
 lib/dhry/cmd_dhry.c |  34 ++++
 lib/dhry/dhry.h     | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/dhry/dhry_1.c   | 421 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/dhry/dhry_2.c   | 217 ++++++++++++++++++++++++++
 8 files changed, 1132 insertions(+)
 create mode 100644 lib/dhry/Kconfig
 create mode 100644 lib/dhry/Makefile
 create mode 100644 lib/dhry/cmd_dhry.c
 create mode 100644 lib/dhry/dhry.h
 create mode 100644 lib/dhry/dhry_1.c
 create mode 100644 lib/dhry/dhry_2.c

diff --git a/lib/Kconfig b/lib/Kconfig
index 7ec8c98..f75dff1 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -49,6 +49,8 @@ config LIB_RAND
 	help
 	  This library provides pseudo-random number generator functions.
 
+source lib/dhry/Kconfig
+
 source lib/rsa/Kconfig
 
 menu "Hashing Support"
diff --git a/lib/Makefile b/lib/Makefile
index 97ed398..ca72187 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_BZIP2) += bzip2/
 obj-$(CONFIG_TIZEN) += tizen/
 obj-$(CONFIG_OF_LIBFDT) += libfdt/
 obj-$(CONFIG_FIT) += libfdt/
+obj-$(CONFIG_FIT) += libfdt/
+obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
 
 obj-$(CONFIG_AES) += aes.o
 obj-$(CONFIG_USB_TTY) += circbuf.o
diff --git a/lib/dhry/Kconfig b/lib/dhry/Kconfig
new file mode 100644
index 0000000..641b806
--- /dev/null
+++ b/lib/dhry/Kconfig
@@ -0,0 +1,7 @@
+config CMD_DHRYSTONE
+	bool "Support the 'dhry' command to run the dhrystone benchmark"
+	help
+	  Dhrystone is an old benchmark in the public domain that gives a
+	  rough idea of CPU performance. This enables a 'dhry' command
+	  which runs this benchmark within U-Boot and reports the performance.
+	  The number of 'Dhrystone MIPS' is also reported.
diff --git a/lib/dhry/Makefile b/lib/dhry/Makefile
new file mode 100644
index 0000000..926c0d6
--- /dev/null
+++ b/lib/dhry/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += cmd_dhry.o dhry_1.o dhry_2.o
diff --git a/lib/dhry/cmd_dhry.c b/lib/dhry/cmd_dhry.c
new file mode 100644
index 0000000..5dc191e
--- /dev/null
+++ b/lib/dhry/cmd_dhry.c
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include "dhry.h"
+
+static int do_dhry(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	ulong start, duration, dhry_per_sec, vax_mips;
+	int iterations = 1000000;
+
+	if (argc > 1)
+		iterations = simple_strtoul(argv[1], NULL, 10);
+
+	start = get_timer(0);
+	dhry(iterations);
+	duration = get_timer(start);
+	dhry_per_sec = iterations * 1000 / duration;
+	vax_mips = dhry_per_sec / 1757;
+	printf("%d iterations in %lu ms: %lu/s, %lu DMIPS\n", iterations,
+	       duration, dhry_per_sec, vax_mips);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	dhry,	2,	1,	do_dhry,
+	"[iterations] - run dhrystone benchmark",
+	"\n    - run the Dhrystone 2.1 benchmark, a rough measure of CPU speed\n"
+);
diff --git a/lib/dhry/dhry.h b/lib/dhry/dhry.h
new file mode 100644
index 0000000..49d4223
--- /dev/null
+++ b/lib/dhry/dhry.h
@@ -0,0 +1,442 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry.h   SID: 3.4 5/15/91 19:30:21
+ *          
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben at bytepb.byte.com   rick_g at bytepb.byte.com   tyager at bytepb.byte.com
+ *
+ *****************************************************************************
+ *  Modification Log:
+ *  addapted from:
+ *
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry.h (part 1 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *                      Siemens AG, AUT E 51
+ *                      Postfach 3220
+ *                      8520 Erlangen
+ *                      Germany (West)
+ *                              Phone:  [+49]-9131-7-20330
+ *                                      (8-17 Central European Time)
+ *                              Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ *              Original Version (in Ada) published in
+ *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ *              pp. 1013 - 1030, together with the statistics
+ *              on which the distribution of statements etc. is based.
+ *
+ *              In this C version, the following C library functions are used:
+ *              - strcpy, strcmp (inside the measurement loop)
+ *              - printf, scanf (outside the measurement loop)
+ *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ *              are used for execution time measurement. For measurements
+ *              on other systems, these calls have to be changed.
+ *
+ *  Collection of Results:
+ *              Reinhold Weicker (address see above) and
+ *              
+ *              Rick Richardson
+ *              PC Research. Inc.
+ *              94 Apple Orchard Drive
+ *              Tinton Falls, NJ 07724
+ *                      Phone:  (201) 834-1378 (9-17 EST)               
+ *                      Usenet: ...!seismo!uunet!pcrat!rick
+ *
+ *      Please send results to Rick Richardson and/or Reinhold Weicker.
+ *      Complete information should be given on hardware and software used.
+ *      Hardware information includes: Machine type, CPU, type and size
+ *      of caches; for microprocessors: clock frequency, memory speed
+ *      (number of wait states).
+ *      Software information includes: Compiler (and runtime library)
+ *      manufacturer and version, compilation switches, OS version.
+ *      The Operating System version may give an indication about the
+ *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ *      The complete output generated by the program should be mailed
+ *      such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ *  History:    This version C/2.1 has been made for two reasons:
+ *
+ *              1) There is an obvious need for a common C version of
+ *              Dhrystone, since C is at present the most popular system
+ *              programming language for the class of processors
+ *              (microcomputers, minicomputers) where Dhrystone is used most.
+ *              There should be, as far as possible, only one C version of
+ *              Dhrystone such that results can be compared without
+ *              restrictions. In the past, the C versions distributed
+ *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ *              had small (though not significant) differences.
+ *
+ *              2) As far as it is possible without changes to the Dhrystone
+ *              statistics, optimizing compilers should be prevented from
+ *              removing significant statements.
+ *
+ *              This C version has been developed in cooperation with
+ *              Rick Richardson (Tinton Falls, NJ), it incorporates many
+ *              ideas from the "Version 1.1" distributed previously by
+ *              him over the UNIX network Usenet.
+ *              I also thank Chaim Benedelac (National Semiconductor),
+ *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ *              for their help with comments on earlier versions of the
+ *              benchmark.
+ *
+ *  Changes:    In the initialization part, this version follows mostly
+ *              Rick Richardson's version distributed via Usenet, not the
+ *              version distributed earlier via floppy disk by Reinhold Weicker.
+ *              As a concession to older compilers, names have been made
+ *              unique within the first 8 characters.
+ *              Inside the measurement loop, this version follows the
+ *              version previously distributed by Reinhold Weicker.
+ *
+ *              At several places in the benchmark, code has been added,
+ *              but within the measurement loop only in branches that 
+ *              are not executed. The intention is that optimizing compilers
+ *              should be prevented from moving code out of the measurement
+ *              loop, or from removing code altogether. Since the statements
+ *              that are executed within the measurement loop have NOT been
+ *              changed, the numbers defining the "Dhrystone distribution"
+ *              (distribution of statements, operand types and locality)
+ *              still hold. Except for sophisticated optimizing compilers,
+ *              execution times for this version should be the same as
+ *              for previous versions.
+ *              
+ *              Since it has proven difficult to subtract the time for the
+ *              measurement loop overhead in a correct way, the loop check
+ *              has been made a part of the benchmark. This does have
+ *              an impact - though a very minor one - on the distribution
+ *              statistics which have been updated for this version.
+ *
+ *              All changes within the measurement loop are described
+ *              and discussed in the companion paper "Rationale for
+ *              Dhrystone version 2".
+ *
+ *              Because of the self-imposed limitation that the order and
+ *              distribution of the executed statements should not be
+ *              changed, there are still cases where optimizing compilers
+ *              may not generate code for some statements. To a certain
+ *              degree, this is unavoidable for small synthetic benchmarks.
+ *              Users of the benchmark are advised to check code listings
+ *              whether code is generated for all statements of Dhrystone.
+ *
+ *              Version 2.1 is identical to version 2.0 distributed via
+ *              the UNIX network Usenet in March 1988 except that it corrects
+ *              some minor deficiencies that were found by users of version 2.0.
+ *              The only change within the measurement loop is that a
+ *              non-executed "else" part was added to the "if" statement in
+ *              Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines:     The following "Defines" are possible:
+ *              -DREG=register          (default: Not defined)
+ *                      As an approximation to what an average C programmer
+ *                      might do, the "register" storage class is applied
+ *                      (if enabled by -DREG=register)
+ *                      - for local variables, if they are used (dynamically)
+ *                        five or more times
+ *                      - for parameters if they are used (dynamically)
+ *                        six or more times
+ *                      Note that an optimal "register" strategy is
+ *                      compiler-dependent, and that "register" declarations
+ *                      do not necessarily lead to faster execution.
+ *              -DNOSTRUCTASSIGN        (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      assignment of structures.
+ *              -DNOENUMS               (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      enumeration types.
+ *              -DTIMES                 (default)
+ *              -DTIME
+ *                      The "times" function of UNIX (returning process times)
+ *                      or the "time" function (returning wallclock time)
+ *                      is used for measurement. 
+ *                      For single user machines, "time ()" is adequate. For
+ *                      multi-user machines where you cannot get single-user
+ *                      access, use the "times ()" function. If you have
+ *                      neither, use a stopwatch in the dead of night.
+ *                      "printf"s are provided marking the points "Start Timer"
+ *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
+ *                      command, as this will measure the total time to
+ *                      run this program, which will (erroneously) include
+ *                      the time to allocate storage (malloc) and to perform
+ *                      the initialization.
+ *              -DHZ=nnn
+ *                      In Berkeley UNIX, the function "times" returns process
+ *                      time in 1/HZ seconds, with HZ = 60 for most systems.
+ *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ *                      A VALUE.
+ *
+ ***************************************************************************
+ *
+ *  Compilation model and measurement (IMPORTANT):
+ *
+ *  This C version of Dhrystone consists of three files:
+ *  - dhry.h (this file, containing global definitions and comments)
+ *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ *  The following "ground rules" apply for measurements:
+ *  - Separate compilation
+ *  - No procedure merging
+ *  - Otherwise, compiler optimizations are allowed but should be indicated
+ *  - Default results are those without register declarations
+ *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+ *  detailed discussion of these ground rules.
+ *
+ *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ *  models ("small", "medium", "large" etc.) should be given if possible,
+ *  together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ *  Dhrystone (C version) statistics:
+ *
+ *  [Comment from the first distribution, updated for version 2.
+ *   Note that because of language differences, the numbers are slightly
+ *   different from the Ada version.]
+ *
+ *  The following program contains statements of a high level programming
+ *  language (here: C) in a distribution considered representative:           
+ *
+ *    assignments                  52 (51.0 %)
+ *    control statements           33 (32.4 %)
+ *    procedure, function calls    17 (16.7 %)
+ *
+ *  103 statements are dynamically executed. The program is balanced with
+ *  respect to the three aspects:                                             
+ *
+ *    - statement type
+ *    - operand type
+ *    - operand locality
+ *         operand global, local, parameter, or constant.                     
+ *
+ *  The combination of these three aspects is balanced only approximately.    
+ *
+ *  1. Statement Type:                                                        
+ *  -----------------             number
+ *
+ *     V1 = V2                     9
+ *       (incl. V1 = F(..)
+ *     V = Constant               12
+ *     Assignment,                 7
+ *       with array element
+ *     Assignment,                 6
+ *       with record component
+ *                                --
+ *                                34       34
+ *
+ *     X = Y +|-|"&&"|"|" Z        5
+ *     X = Y +|-|"==" Constant     6
+ *     X = X +|- 1                 3
+ *     X = Y *|/ Z                 2
+ *     X = Expression,             1
+ *           two operators
+ *     X = Expression,             1
+ *           three operators
+ *                                --
+ *                                18       18
+ *
+ *     if ....                    14
+ *       with "else"      7
+ *       without "else"   7
+ *           executed        3
+ *           not executed    4
+ *     for ...                     7  |  counted every time
+ *     while ...                   4  |  the loop condition
+ *     do ... while                1  |  is evaluated
+ *     switch ...                  1
+ *     break                       1
+ *     declaration with            1
+ *       initialization
+ *                                --
+ *                                34       34
+ *
+ *     P (...)  procedure call    11
+ *       user procedure      10
+ *       library procedure    1
+ *     X = F (...)
+ *             function  call      6
+ *       user function        5                                         
+ *       library function     1                                               
+ *                                --                                          
+ *                                17       17
+ *                                        ---
+ *                                        103
+ *
+ *    The average number of parameters in procedure or function calls
+ *    is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ *  2. Operators
+ *  ------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *    Arithmetic             32          50.8                                 
+ *
+ *       +                     21          33.3                              
+ *       -                      7          11.1                              
+ *       *                      3           4.8
+ *       / (int div)            1           1.6
+ *
+ *    Comparison             27           42.8
+ *
+ *       ==                     9           14.3
+ *       /=                     4            6.3
+ *       >                      1            1.6
+ *       <                      3            4.8
+ *       >=                     1            1.6
+ *       <=                     9           14.3
+ *
+ *    Logic                   4            6.3
+ *
+ *       && (AND-THEN)          1            1.6
+ *       |  (OR)                1            1.6
+ *       !  (NOT)               2            3.2
+ * 
+ *                           --          -----
+ *                           63          100.1
+ *
+ *
+ *  3. Operand Type (counted once per operand reference):
+ *  ---------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *     Integer               175        72.3 %
+ *     Character              45        18.6 %
+ *     Pointer                12         5.0 %
+ *     String30                6         2.5 %
+ *     Array                   2         0.8 %
+ *     Record                  2         0.8 %
+ *                           ---       -------
+ *                           242       100.0 %
+ *
+ *  When there is an access path leading to the final operand (e.g. a record
+ *  component), only the final data type on the access path is counted.       
+ *
+ *
+ *  4. Operand Locality:                                                      
+ *  -------------------
+ *                                number    approximate
+ *                                          percentage
+ *
+ *     local variable              114        47.1 %
+ *     global variable              22         9.1 %
+ *     parameter                    45        18.6 %
+ *        value                        23         9.5 %
+ *        reference                    22         9.1 %
+ *     function result               6         2.5 %
+ *     constant                     55        22.7 %
+ *                                 ---       -------
+ *                                 242       100.0 %
+ *
+ *
+ *  The program does not compute anything meaningful, but it is syntactically
+ *  and semantically correct. All variables have a value assigned to them
+ *  before they are used as a source operand.
+ *
+ *  There has been no explicit effort to account for the effects of a
+ *  cache, or to balance the use of long or short displacements for code or
+ *  data.
+ *
+ ***************************************************************************
+ */
+
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#define TIMES
+#endif
+                /* Use times(2) time function unless    */
+                /* explicitly defined otherwise         */
+
+#define Mic_secs_Per_Second     1000000.0
+                /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef  NOSTRUCTASSIGN
+#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s)      d = s
+#endif
+
+#ifdef  NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+  typedef int   Enumeration;
+#else
+  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+                Enumeration;
+#endif
+        /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#define Null 0 
+                /* Value of a Null pointer */
+#define true  1
+#define false 0
+
+typedef int     One_Thirty;
+typedef int     One_Fifty;
+typedef char    Capital_Letter;
+typedef int     Boolean;
+typedef char    Str_30 [31];
+typedef int     Arr_1_Dim [50];
+typedef int     Arr_2_Dim [50] [50];
+
+typedef struct record 
+    {
+    struct record *Ptr_Comp;
+    Enumeration    Discr;
+    union {
+          struct {
+                  Enumeration Enum_Comp;
+                  int         Int_Comp;
+                  char        Str_Comp [31];
+                  } var_1;
+          struct {
+                  Enumeration E_Comp_2;
+                  char        Str_2_Comp [31];
+                  } var_2;
+          struct {
+                  char        Ch_1_Comp;
+                  char        Ch_2_Comp;
+                  } var_3;
+          } variant;
+      } Rec_Type, *Rec_Pointer;
+
+
+/*
+ * dhry() - run dhrystone for a given number of iterations
+ *
+ * @iterations:	Number of iterations to run
+ */
+void dhry(int iterations);
diff --git a/lib/dhry/dhry_1.c b/lib/dhry/dhry_1.c
new file mode 100644
index 0000000..be63710
--- /dev/null
+++ b/lib/dhry/dhry_1.c
@@ -0,0 +1,421 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry_1.c   SID: 3.4 5/15/91 19:30:21
+ *          
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben at bytepb.byte.com   rick_g at bytepb.byte.com   tyager at bytepb.byte.com
+ *
+ *****************************************************************************
+ *
+ * *** WARNING ****  With BYTE's modifications applied, results obtained with
+ *     *******       this version of the Dhrystone program may not be applicable
+ *                   to other versions.
+ *                  
+ *  Modification Log:
+ *  10/22/97 - code cleanup to remove ANSI C compiler warnings
+ *             Andy Kahn <kahn@zk3.dec.com>
+ *
+ *  Adapted from:
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_1.c (part 2 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ***************************************************************************/
+char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
+
+#include <common.h>
+#include <malloc.h>
+
+#include "dhry.h"
+
+unsigned long Run_Index;
+
+void report(void)
+{
+	printf("%ld loops\n", Run_Index);
+}
+
+/* Global Variables: */
+
+Rec_Pointer     Ptr_Glob,
+                Next_Ptr_Glob;
+int             Int_Glob;
+Boolean         Bool_Glob;
+char            Ch_1_Glob,
+                Ch_2_Glob;
+int             Arr_1_Glob [50];
+int             Arr_2_Glob [50] [50];
+
+Enumeration     Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
+  /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+        Boolean Reg = false;
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+        Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+#define Too_Small_Time 120
+                /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+extern long     time();
+                /* see library function "time"  */
+#define Too_Small_Time 2
+                /* Measurements should last at least 2 seconds */
+#endif
+
+long            Begin_Time,
+                End_Time,
+                User_Time;
+
+/* end of variables for time measurement */
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty   *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+
+
+extern Boolean Func_2(Str_30, Str_30);
+extern void Proc_6(Enumeration, Enumeration *);
+extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+
+void dhry(int Number_Of_Runs)
+  /* main program, corresponds to procedures        */
+  /* Main and Proc_0 in the Ada version             */
+{
+        One_Fifty       Int_1_Loc;
+  REG   One_Fifty       Int_2_Loc;
+        One_Fifty       Int_3_Loc;
+  REG   char            Ch_Index;
+        Enumeration     Enum_Loc;
+        Str_30          Str_1_Loc;
+        Str_30          Str_2_Loc;
+
+  /* Initializations */
+
+  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+  Ptr_Glob->Discr                       = Ident_1;
+  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+  strcpy (Ptr_Glob->variant.var_1.Str_Comp, 
+          "DHRYSTONE PROGRAM, SOME STRING");
+  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+  Arr_2_Glob [8][7] = 10;
+        /* Was missing in published program. Without this statement,    */
+        /* Arr_2_Glob [8][7] would have an undefined value.             */
+        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+        /* overflow may occur for this array element.                   */
+
+#ifdef PRATTLE
+  printf ("\n");
+  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+  printf ("\n");
+  if (Reg)
+  {
+    printf ("Program compiled with 'register' attribute\n");
+    printf ("\n");
+  }
+  else
+  {
+    printf ("Program compiled without 'register' attribute\n");
+    printf ("\n");
+  }
+  printf ("Please give the number of runs through the benchmark: ");
+  {
+    int n;
+    scanf ("%d", &n);
+    Number_Of_Runs = n;
+  }
+  printf ("\n");
+
+  printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+#endif /* PRATTLE */
+
+  Run_Index = 0;
+
+  /***************/
+  /* Start timer */
+  /***************/
+ 
+#ifdef SELF_TIMED
+#ifdef TIMES
+  times (&time_info);
+  Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  Begin_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+  for (Run_Index = 1; Run_Index < Number_Of_Runs; ++Run_Index)
+  {
+
+    Proc_5();
+    Proc_4();
+      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+    Int_1_Loc = 2;
+    Int_2_Loc = 3;
+    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+    Enum_Loc = Ident_2;
+    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+      /* Bool_Glob == 1 */
+    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+    {
+      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+        /* Int_3_Loc == 7 */
+      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+        /* Int_3_Loc == 7 */
+      Int_1_Loc += 1;
+    } /* while */
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+      /* Int_Glob == 5 */
+    Proc_1 (Ptr_Glob);
+    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+                             /* loop body executed twice */
+    {
+      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+          /* then, not executed */
+        {
+        Proc_6 (Ident_1, &Enum_Loc);
+        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+        Int_2_Loc = Run_Index;
+        Int_Glob = Run_Index;
+        }
+    }
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Int_2_Loc = Int_2_Loc * Int_1_Loc;
+    Int_1_Loc = Int_2_Loc / Int_3_Loc;
+    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+    Proc_2 (&Int_1_Loc);
+      /* Int_1_Loc == 5 */
+
+  } /* loop "for Run_Index" */
+
+  /**************/
+  /* Stop timer */
+  /**************/
+#ifdef SELF_TIMED 
+#ifdef TIMES
+  times (&time_info);
+  End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  End_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+  /* BYTE version never executes this stuff */
+#ifdef SELF_TIMED
+  printf ("Execution ends\n");
+  printf ("\n");
+  printf ("Final values of the variables used in the benchmark:\n");
+  printf ("\n");
+  printf ("Int_Glob:            %d\n", Int_Glob);
+  printf ("        should be:   %d\n", 5);
+  printf ("Bool_Glob:           %d\n", Bool_Glob);
+  printf ("        should be:   %d\n", 1);
+  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
+  printf ("        should be:   %c\n", 'A');
+  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
+  printf ("        should be:   %c\n", 'B');
+  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
+  printf ("        should be:   %d\n", 7);
+  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
+  printf ("        should be:   Number_Of_Runs + 10\n");
+  printf ("Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent)\n");
+  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 2);
+  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 17);
+  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Next_Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent), same as above\n");
+  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 1);
+  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 18);
+  printf ("  Str_Comp:          %s\n",
+                                Next_Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
+  printf ("        should be:   %d\n", 5);
+  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
+  printf ("        should be:   %d\n", 13);
+  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
+  printf ("        should be:   %d\n", 7);
+  printf ("Enum_Loc:            %d\n", Enum_Loc);
+  printf ("        should be:   %d\n", 1);
+  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
+  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
+  printf ("\n");
+
+  User_Time = End_Time - Begin_Time;
+
+  if (User_Time < Too_Small_Time)
+  {
+    printf ("Measured time too small to obtain meaningful results\n");
+    printf ("Please increase number of runs\n");
+    printf ("\n");
+  }
+  else
+  {
+#ifdef TIME
+    Microseconds = (float) User_Time * Mic_secs_Per_Second
+                        / (float) Number_Of_Runs;
+    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+    Microseconds = (float) User_Time * Mic_secs_Per_Second
+                        / ((float) HZ * ((float) Number_Of_Runs));
+    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+                        / (float) User_Time;
+#endif
+    printf ("Microseconds for one run through Dhrystone: ");
+    printf ("%6.1f \n", Microseconds);
+    printf ("Dhrystones per Second:                      ");
+    printf ("%6.1f \n", Dhrystones_Per_Second);
+    printf ("\n");
+  }
+#endif /* SELF_TIMED */
+}
+
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
+    /* executed once */
+{
+  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;  
+                                        /* == Ptr_Glob_Next */
+  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+  /* corresponds to "rename" in Ada, "with" in Pascal           */
+  
+  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 
+  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+  Next_Record->variant.var_1.Int_Comp 
+        = Ptr_Val_Par->variant.var_1.Int_Comp;
+  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+  Proc_3 (&Next_Record->Ptr_Comp);
+    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 
+                        == Ptr_Glob->Ptr_Comp */
+  if (Next_Record->Discr == Ident_1)
+    /* then, executed */
+  {
+    Next_Record->variant.var_1.Int_Comp = 6;
+    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 
+           &Next_Record->variant.var_1.Enum_Comp);
+    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 
+           &Next_Record->variant.var_1.Int_Comp);
+  }
+  else /* not executed */
+    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2 (One_Fifty   *Int_Par_Ref)
+    /* executed once */
+    /* *Int_Par_Ref == 1, becomes 4 */
+{
+  One_Fifty  Int_Loc;  
+  Enumeration   Enum_Loc;
+
+  Enum_Loc = 0;
+
+  Int_Loc = *Int_Par_Ref + 10;
+  do /* executed once */
+    if (Ch_1_Glob == 'A')
+      /* then, executed */
+    {
+      Int_Loc -= 1;
+      *Int_Par_Ref = Int_Loc - Int_Glob;
+      Enum_Loc = Ident_1;
+    } /* if */
+  while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+    /* executed once */
+    /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+  if (Ptr_Glob != Null)
+    /* then, executed */
+    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4 (void) /* without parameters */
+    /* executed once */
+{
+  Boolean Bool_Loc;
+
+  Bool_Loc = Ch_1_Glob == 'A';
+  Bool_Glob = Bool_Loc | Bool_Glob;
+  Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+void Proc_5 (void) /* without parameters */
+/*******/
+    /* executed once */
+{
+  Ch_1_Glob = 'A';
+  Bool_Glob = false;
+} /* Proc_5 */
+
+
+        /* Procedure for the assignment of structures,          */
+        /* if the C compiler doesn't support this feature       */
+#ifdef  NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char   *d;
+register char   *s;
+register int    l;
+{
+        while (l--) *d++ = *s++;
+}
+#endif
diff --git a/lib/dhry/dhry_2.c b/lib/dhry/dhry_2.c
new file mode 100644
index 0000000..59aa458
--- /dev/null
+++ b/lib/dhry/dhry_2.c
@@ -0,0 +1,217 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry_2.c   SID: 3.4 5/15/91 19:30:22
+ *          
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben at bytepb.byte.com   rick_g at bytepb.byte.com   tyager at bytepb.byte.com
+ *
+ *****************************************************************************
+ *  Modification Log:
+ *  10/22/97 - code cleanup to remove ANSI C compiler warnings
+ *             Andy Kahn <kahn@zk3.dec.com>
+ *
+ *  Adapted from:
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *
+ * **** WARNING **** See warning in n.dhry_1.c
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_2.c (part 3 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************/
+/* SCCSid is defined in dhry_1.c */
+
+#include <common.h>
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#endif
+
+extern  int     Int_Glob;
+extern  char    Ch_1_Glob;
+
+void Proc_6(Enumeration, Enumeration *);
+void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+Enumeration Func_1(Capital_Letter, Capital_Letter);
+Boolean Func_2(Str_30, Str_30);
+Boolean Func_3(Enumeration);
+
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+    /* executed once */
+    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+  *Enum_Ref_Par = Enum_Val_Par;
+  if (! Func_3 (Enum_Val_Par))
+    /* then, not executed */
+    *Enum_Ref_Par = Ident_4;
+  switch (Enum_Val_Par)
+  {
+    case Ident_1: 
+      *Enum_Ref_Par = Ident_1;
+      break;
+    case Ident_2: 
+      if (Int_Glob > 100)
+        /* then */
+      *Enum_Ref_Par = Ident_1;
+      else *Enum_Ref_Par = Ident_4;
+      break;
+    case Ident_3: /* executed */
+      *Enum_Ref_Par = Ident_2;
+      break;
+    case Ident_4: break;
+    case Ident_5: 
+      *Enum_Ref_Par = Ident_3;
+      break;
+  } /* switch */
+} /* Proc_6 */
+
+void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+One_Fifty       Int_1_Par_Val;
+One_Fifty       Int_2_Par_Val;
+One_Fifty      *Int_Par_Ref;
+/**********************************************/
+    /* executed three times                                      */ 
+    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+    /*                  Int_Par_Ref becomes 7                    */
+    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+    /*                  Int_Par_Ref becomes 17                   */
+    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+    /*                  Int_Par_Ref becomes 18                   */
+{
+  One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 2;
+  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+    /* executed once      */
+    /* Int_Par_Val_1 == 3 */
+    /* Int_Par_Val_2 == 7 */
+Arr_1_Dim       Arr_1_Par_Ref;
+Arr_2_Dim       Arr_2_Par_Ref;
+int             Int_1_Par_Val;
+int             Int_2_Par_Val;
+{
+  REG One_Fifty Int_Index;
+  REG One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 5;
+  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+  Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
+/*************************************************/
+    /* executed three times                                         */
+    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+{
+  Capital_Letter        Ch_1_Loc;
+  Capital_Letter        Ch_2_Loc;
+
+  Ch_1_Loc = Ch_1_Par_Val;
+  Ch_2_Loc = Ch_1_Loc;
+  if (Ch_2_Loc != Ch_2_Par_Val)
+    /* then, executed */
+    return (Ident_1);
+  else  /* not executed */
+  {
+    Ch_1_Glob = Ch_1_Loc;
+    return (Ident_2);
+   }
+} /* Func_1 */
+
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+    /* executed once */
+    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30  Str_1_Par_Ref;
+Str_30  Str_2_Par_Ref;
+{
+  REG One_Thirty        Int_Loc;
+      Capital_Letter    Ch_Loc;
+
+  Ch_Loc = 'A';
+  Int_Loc = 2;
+  while (Int_Loc <= 2) /* loop body executed once */
+    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+      /* then, executed */
+    {
+      Ch_Loc = 'A';
+      Int_Loc += 1;
+    } /* if, while */
+  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+    /* then, not executed */
+    Int_Loc = 7;
+  if (Ch_Loc == 'R')
+    /* then, not executed */
+    return (true);
+  else /* executed */
+  {
+    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+      /* then, not executed */
+    {
+      Int_Loc += 7;
+      Int_Glob = Int_Loc;
+      return (true);
+    }
+    else /* executed */
+      return (false);
+  } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+    /* executed once        */
+    /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+  Enumeration Enum_Loc;
+
+  Enum_Loc = Enum_Par_Val;
+  if (Enum_Loc == Ident_3)
+    /* then, executed */
+    return (true);
+  else /* not executed */
+    return (false);
+} /* Func_3 */
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types Simon Glass
                   ` (53 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Provide access to the dhrystone benchmark command.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 31fe2f9..3953ec3 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -19,6 +19,7 @@ CONFIG_DM_PCI=y
 CONFIG_PCI_SANDBOX=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_CMD_CROS_EC=y
+CONFIG_CMD_DHRYSTONE=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_KEYB=y
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree Simon Glass
                   ` (52 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Offer to display the available image types in help. Also, rather than
hacking the genimg_get_type_id() function to display a list of types,
do this in the tool. Also, sort the list.

The list of image types is quite long, and hard to discover. Print it out
when we show help information.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Use case-insensitve compare for image params (fixes build break with m53evk)

Changes in v2: None

 common/image.c  | 58 +++++++++++++++++++++++++++++++-------------------------
 include/image.h | 11 +++++++++++
 tools/mkimage.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 95 insertions(+), 33 deletions(-)

diff --git a/common/image.c b/common/image.c
index f0f0135..9efacf8 100644
--- a/common/image.c
+++ b/common/image.c
@@ -543,6 +543,15 @@ void genimg_print_time(time_t timestamp)
 }
 #endif
 
+const table_entry_t *get_table_entry(const table_entry_t *table, int id)
+{
+	for (; table->id >= 0; ++table) {
+		if (table->id == id)
+			return table;
+	}
+	return NULL;
+}
+
 /**
  * get_table_entry_name - translate entry id to long name
  * @table: pointer to a translation table for entries of a specific type
@@ -559,15 +568,14 @@ void genimg_print_time(time_t timestamp)
  */
 char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
 {
-	for (; table->id >= 0; ++table) {
-		if (table->id == id)
+	table = get_table_entry(table, id);
+	if (!table)
+		return msg;
 #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
-			return table->lname;
+	return table->lname;
 #else
-			return table->lname + gd->reloc_off;
+	return table->lname + gd->reloc_off;
 #endif
-	}
-	return (msg);
 }
 
 const char *genimg_get_os_name(uint8_t os)
@@ -586,6 +594,20 @@ const char *genimg_get_type_name(uint8_t type)
 	return (get_table_entry_name(uimage_type, "Unknown Image", type));
 }
 
+const char *genimg_get_type_short_name(uint8_t type)
+{
+	const table_entry_t *table;
+
+	table = get_table_entry(uimage_type, type);
+	if (!table)
+		return "unknown";
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+	return table->sname;
+#else
+	return table->sname + gd->reloc_off;
+#endif
+}
+
 const char *genimg_get_comp_name(uint8_t comp)
 {
 	return (get_table_entry_name(uimage_comp, "Unknown Compression",
@@ -610,34 +632,18 @@ int get_table_entry_id(const table_entry_t *table,
 		const char *table_name, const char *name)
 {
 	const table_entry_t *t;
-#ifdef USE_HOSTCC
-	int first = 1;
-
-	for (t = table; t->id >= 0; ++t) {
-		if (t->sname && strcasecmp(t->sname, name) == 0)
-			return(t->id);
-	}
 
-	fprintf(stderr, "\nInvalid %s Type - valid names are", table_name);
-	for (t = table; t->id >= 0; ++t) {
-		if (t->sname == NULL)
-			continue;
-		fprintf(stderr, "%c %s", (first) ? ':' : ',', t->sname);
-		first = 0;
-	}
-	fprintf(stderr, "\n");
-#else
 	for (t = table; t->id >= 0; ++t) {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
-		if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0)
+		if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0)
 #else
-		if (t->sname && strcmp(t->sname, name) == 0)
+		if (t->sname && strcasecmp(t->sname, name) == 0)
 #endif
 			return (t->id);
 	}
 	debug("Invalid %s Type: %s\n", table_name, name);
-#endif /* USE_HOSTCC */
-	return (-1);
+
+	return -1;
 }
 
 int genimg_get_os_id(const char *name)
diff --git a/include/image.h b/include/image.h
index b6eb57e..63c3d37 100644
--- a/include/image.h
+++ b/include/image.h
@@ -246,6 +246,8 @@ struct lmb;
 #define IH_TYPE_LPC32XXIMAGE	21	/* x86 setup.bin Image		*/
 #define IH_TYPE_LOADABLE	22	/* A list of typeless images	*/
 
+#define IH_TYPE_COUNT		23	/* Number of image types */
+
 /*
  * Compression Types
  */
@@ -411,6 +413,15 @@ char *get_table_entry_name(const table_entry_t *table, char *msg, int id);
 const char *genimg_get_os_name(uint8_t os);
 const char *genimg_get_arch_name(uint8_t arch);
 const char *genimg_get_type_name(uint8_t type);
+
+/**
+ * genimg_get_type_short_name() - get the short name for an image type
+ *
+ * @param type	Image type (IH_TYPE_...)
+ * @return image short name, or "unknown" if unknown
+ */
+const char *genimg_get_type_short_name(uint8_t type);
+
 const char *genimg_get_comp_name(uint8_t comp);
 int genimg_get_os_id(const char *name);
 int genimg_get_arch_id(const char *name);
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 5ccd951..8808d70 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -26,8 +26,48 @@ struct image_tool_params params = {
 	.imagename2 = "",
 };
 
-int
-main (int argc, char **argv)
+static int h_compare_image_name(const void *vtype1, const void *vtype2)
+{
+	const int *type1 = vtype1;
+	const int *type2 = vtype2;
+	const char *name1 = genimg_get_type_short_name(*type1);
+	const char *name2 = genimg_get_type_short_name(*type2);
+
+	return strcmp(name1, name2);
+}
+
+/* Show all image types supported by mkimage */
+static void show_image_types(void)
+{
+	struct image_type_params *tparams;
+	int order[IH_TYPE_COUNT];
+	int count;
+	int type;
+	int i;
+
+	/* Sort the names in order of short name for easier reading */
+	memset(order, '\0', sizeof(order));
+	for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
+		tparams = imagetool_get_type(type);
+		if (tparams)
+			order[count++] = type;
+	}
+	qsort(order, count, sizeof(int), h_compare_image_name);
+
+	fprintf(stderr, "\nInvalid image type. Supported image types:\n");
+	for (i = 0; i < count; i++) {
+		type = order[i];
+		tparams = imagetool_get_type(type);
+		if (tparams) {
+			fprintf(stderr, "\t%-15s  %s\n",
+				genimg_get_type_short_name(type),
+				genimg_get_type_name(type));
+		}
+	}
+	fprintf(stderr, "\n");
+}
+
+int main(int argc, char **argv)
 {
 	int ifd = -1;
 	struct stat sbuf;
@@ -75,12 +115,16 @@ main (int argc, char **argv)
 					usage ();
 				goto NXTARG;
 			case 'T':
-				if ((--argc <= 0) ||
-					(params.type =
-					genimg_get_type_id (*++argv)) < 0)
-					usage ();
+				params.type = -1;
+				if (--argc >= 0 && argv[1]) {
+					params.type =
+						genimg_get_type_id(*++argv);
+				}
+				if (params.type < 0) {
+					show_image_types();
+					usage();
+				}
 				goto NXTARG;
-
 			case 'a':
 				if (--argc <= 0)
 					usage ();
@@ -546,6 +590,7 @@ static void usage(void)
 #endif
 	fprintf (stderr, "       %s -V ==> print version information and exit\n",
 		params.cmdname);
+	fprintf(stderr, "Use -T to see a list of available image types\n");
 
 	exit (EXIT_FAILURE);
 }
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (2 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions Simon Glass
                   ` (51 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Property names are stored in a string table. When a node property is
removed, the string table is not updated since other nodes may have a
property with the same name.

Thus it is possible for the string table to build up a number of unused
strings. Add a function to remove these. This works by building a new device
tree from the old one, adding strings one by one as needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Fix indentation in function comment

Changes in v2:
- Add new patch to remove unused strings from a device tree

 include/libfdt.h    | 17 +++++++++++++++++
 lib/libfdt/fdt_rw.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/include/libfdt.h b/include/libfdt.h
index f3cbb63..610c507 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -1646,6 +1646,23 @@ int fdt_del_node(void *fdt, int nodeoffset);
 
 const char *fdt_strerror(int errval);
 
+/**
+ * fdt_remove_unused_strings() - Remove any unused strings from an FDT
+ *
+ * This creates a new device tree in @new with unused strings removed. The
+ * called can then use fdt_pack() to minimise the space consumed.
+ *
+ * @old:	Old device tree blog
+ * @new:	Place to put new device tree blob, which must be as large as
+ *		@old
+ * @return
+ *	0, on success
+ *	-FDT_ERR_BADOFFSET, corrupt device tree
+ *	-FDT_ERR_NOSPACE, out of space, which should not happen unless there
+ *		is something very wrong with the device tree input
+ */
+int fdt_remove_unused_strings(const void *old, void *new);
+
 struct fdt_region {
 	int offset;
 	int size;
diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c
index bec8b8a..1a358a8 100644
--- a/lib/libfdt/fdt_rw.c
+++ b/lib/libfdt/fdt_rw.c
@@ -449,3 +449,35 @@ int fdt_pack(void *fdt)
 
 	return 0;
 }
+
+int fdt_remove_unused_strings(const void *old, void *new)
+{
+	const struct fdt_property *old_prop;
+	struct fdt_property *new_prop;
+	int size = fdt_totalsize(old);
+	int next_offset, offset;
+	const char *str;
+	int ret;
+	int tag = FDT_PROP;
+
+	/* Make a copy and remove the strings */
+	memcpy(new, old, size);
+	fdt_set_size_dt_strings(new, 0);
+
+	/* Add every property name back into the new string table */
+	for (offset = 0; tag != FDT_END; offset = next_offset) {
+		tag = fdt_next_tag(old, offset, &next_offset);
+		if (tag != FDT_PROP)
+			continue;
+		old_prop = fdt_get_property_by_offset(old, offset, NULL);
+		new_prop = (struct fdt_property *)(unsigned long)
+			fdt_get_property_by_offset(new, offset, NULL);
+		str = fdt_string(old, fdt32_to_cpu(old_prop->nameoff));
+		ret = _fdt_find_add_string(new, str);
+		if (ret < 0)
+			return ret;
+		new_prop->nameoff = cpu_to_fdt32(ret);
+	}
+
+	return 0;
+}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (3 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool Simon Glass
                   ` (50 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

These have been sent upstream but not accepted to libfdt. For now, bring
these into U-Boot to enable fdtgrep to operate. We will use fdtgrep to
cut device tree files down for SPL.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2:
- Add new patch with fdt_first/next_region() functions
- Tidy up commit message a little

 include/libfdt.h        | 239 ++++++++++++++++++++++-
 lib/libfdt/Makefile     |   2 +-
 lib/libfdt/fdt_region.c | 492 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 731 insertions(+), 2 deletions(-)
 create mode 100644 lib/libfdt/fdt_region.c

diff --git a/include/libfdt.h b/include/libfdt.h
index 610c507..b8b1866 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -121,7 +121,12 @@
 	/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
 	 * or similar property with a bad format or value */
 
-#define FDT_ERR_MAX		14
+#define FDT_ERR_TOODEEP		15
+	/* FDT_ERR_TOODEEP: The depth of a node has exceeded the internal
+	 * libfdt limit. This can happen if you have more than
+	 * FDT_MAX_DEPTH nested nodes. */
+
+#define FDT_ERR_MAX		15
 
 /**********************************************************************/
 /* Low-level functions (you probably don't need these)                */
@@ -1668,6 +1673,77 @@ struct fdt_region {
 	int size;
 };
 
+/*
+ * Flags for fdt_find_regions()
+ *
+ * Add a region for the string table (always the last region)
+ */
+#define FDT_REG_ADD_STRING_TAB		(1 << 0)
+
+/*
+ * Add all supernodes of a matching node/property, useful for creating a
+ * valid subset tree
+ */
+#define FDT_REG_SUPERNODES		(1 << 1)
+
+/* Add the FDT_BEGIN_NODE tags of subnodes, including their names */
+#define FDT_REG_DIRECT_SUBNODES	(1 << 2)
+
+/* Add all subnodes of a matching node */
+#define FDT_REG_ALL_SUBNODES		(1 << 3)
+
+/* Add a region for the mem_rsvmap table (always the first region) */
+#define FDT_REG_ADD_MEM_RSVMAP		(1 << 4)
+
+/* Indicates what an fdt part is (node, property, value) */
+#define FDT_IS_NODE			(1 << 0)
+#define FDT_IS_PROP			(1 << 1)
+#define FDT_IS_VALUE			(1 << 2)	/* not supported */
+#define FDT_IS_COMPAT			(1 << 3)	/* used internally */
+#define FDT_NODE_HAS_PROP		(1 << 4)	/* node contains prop */
+
+#define FDT_ANY_GLOBAL		(FDT_IS_NODE | FDT_IS_PROP | FDT_IS_VALUE | \
+					FDT_IS_COMPAT)
+#define FDT_IS_ANY			0x1f		/* all the above */
+
+/* We set a reasonable limit on the number of nested nodes */
+#define FDT_MAX_DEPTH			32
+
+/* Decribes what we want to include from the current tag */
+enum want_t {
+	WANT_NOTHING,
+	WANT_NODES_ONLY,		/* No properties */
+	WANT_NODES_AND_PROPS,		/* Everything for one level */
+	WANT_ALL_NODES_AND_PROPS	/* Everything for all levels */
+};
+
+/* Keeps track of the state at parent nodes */
+struct fdt_subnode_stack {
+	int offset;		/* Offset of node */
+	enum want_t want;	/* The 'want' value here */
+	int included;		/* 1 if we included this node, 0 if not */
+};
+
+struct fdt_region_ptrs {
+	int depth;			/* Current tree depth */
+	int done;			/* What we have completed scanning */
+	enum want_t want;		/* What we are currently including */
+	char *end;			/* Pointer to end of full node path */
+	int nextoffset;			/* Next node offset to check */
+};
+
+/* The state of our finding algortihm */
+struct fdt_region_state {
+	struct fdt_subnode_stack stack[FDT_MAX_DEPTH];	/* node stack */
+	struct fdt_region *region;	/* Contains list of regions found */
+	int count;			/* Numnber of regions found */
+	const void *fdt;		/* FDT blob */
+	int max_regions;		/* Maximum regions to find */
+	int can_merge;		/* 1 if we can merge with previous region */
+	int start;			/* Start position of current region */
+	struct fdt_region_ptrs ptrs;	/* Pointers for what we are up to */
+};
+
 /**
  * fdt_find_regions() - find regions in device tree
  *
@@ -1727,4 +1803,165 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
 		     struct fdt_region region[], int max_regions,
 		     char *path, int path_len, int add_string_tab);
 
+/**
+ * fdt_first_region() - find regions in device tree
+ *
+ * Given a nodes and properties to include and properties to exclude, find
+ * the regions of the device tree which describe those included parts.
+ *
+ * The use for this function is twofold. Firstly it provides a convenient
+ * way of performing a structure-aware grep of the tree. For example it is
+ * possible to grep for a node and get all the properties associated with
+ * that node. Trees can be subsetted easily, by specifying the nodes that
+ * are required, and then writing out the regions returned by this function.
+ * This is useful for small resource-constrained systems, such as boot
+ * loaders, which want to use an FDT but do not need to know about all of
+ * it.
+ *
+ * Secondly it makes it easy to hash parts of the tree and detect changes.
+ * The intent is to get a list of regions which will be invariant provided
+ * those parts are invariant. For example, if you request a list of regions
+ * for all nodes but exclude the property "data", then you will get the
+ * same region contents regardless of any change to "data" properties.
+ *
+ * This function can be used to produce a byte-stream to send to a hashing
+ * function to verify that critical parts of the FDT have not changed.
+ * Note that semantically null changes in order could still cause false
+ * hash misses. Such reordering might happen if the tree is regenerated
+ * from source, and nodes are reordered (the bytes-stream will be emitted
+ * in a different order and mnay hash functions will detect this). However
+ * if an existing tree is modified using libfdt functions, such as
+ * fdt_add_subnode() and fdt_setprop(), then this problem is avoided.
+ *
+ * The nodes/properties to include/exclude are defined by a function
+ * provided by the caller. This function is called for each node and
+ * property, and must return:
+ *
+ *    0 - to exclude this part
+ *    1 - to include this part
+ *   -1 - for FDT_IS_PROP only: no information is available, so include
+ *		if its containing node is included
+ *
+ * The last case is only used to deal with properties. Often a property is
+ * included if its containing node is included - this is the case where
+ * -1 is returned.. However if the property is specifically required to be
+ * included/excluded, then 0 or 1 can be returned. Note that including a
+ * property when the FDT_REG_SUPERNODES flag is given will force its
+ * containing node to be included since it is not valid to have a property
+ * that is not in a node.
+ *
+ * Using the information provided, the inclusion of a node can be controlled
+ * either by a node name or its compatible string, or any other property
+ * that the function can determine.
+ *
+ * As an example, including node "/" means to include the root node and all
+ * root properties. A flag provides a way of also including supernodes (of
+ * which there is none for the root node), and another flag includes
+ * immediate subnodes, so in this case we would get the FDT_BEGIN_NODE and
+ * FDT_END_NODE of all subnodes of /.
+ *
+ * The subnode feature helps in a hashing situation since it prevents the
+ * root node from changing@all. Any change to non-excluded properties,
+ * names of subnodes or number of subnodes would be detected.
+ *
+ * When used with FITs this provides the ability to hash and sign parts of
+ * the FIT based on different configurations in the FIT. Then it is
+ * impossible to change anything about that configuration (include images
+ * attached to the configuration), but it may be possible to add new
+ * configurations, new images or new signatures within the existing
+ * framework.
+ *
+ * Adding new properties to a device tree may result in the string table
+ * being extended (if the new property names are different from those
+ * already added). This function can optionally include a region for
+ * the string table so that this can be part of the hash too. This is always
+ * the last region.
+ *
+ * The FDT also has a mem_rsvmap table which can also be included, and is
+ * always the first region if so.
+ *
+ * The device tree header is not included in the region list. Since the
+ * contents of the FDT are changing (shrinking, often), the caller will need
+ * to regenerate the header anyway.
+ *
+ * @fdt:	Device tree to check
+ * @h_include:	Function to call to determine whether to include a part or
+ *		not:
+ *
+ *		@priv: Private pointer as passed to fdt_find_regions()
+ *		@fdt: Pointer to FDT blob
+ *		@offset: Offset of this node / property
+ *		@type: Type of this part, FDT_IS_...
+ *		@data: Pointer to data (node name, property name, compatible
+ *			string, value (not yet supported)
+ *		@size: Size of data, or 0 if none
+ *		@return 0 to exclude, 1 to include, -1 if no information is
+ *		available
+ * @priv:	Private pointer passed to h_include
+ * @region:	Returns list of regions, sorted by offset
+ * @max_regions: Maximum length of region list
+ * @path:	Pointer to a temporary string for the function to use for
+ *		building path names
+ * @path_len:	Length of path, must be large enough to hold the longest
+ *		path in the tree
+ * @flags:	Various flags that control the region algortihm, see
+ *		FDT_REG_...
+ * @return number of regions in list. If this is >max_regions then the
+ * region array was exhausted. You should increase max_regions and try
+ * the call again. Only the first max_regions elements are available in the
+ * array.
+ *
+ * On error a -ve value is return, which can be:
+ *
+ *	-FDT_ERR_BADSTRUCTURE (too deep or more END tags than BEGIN tags
+ *	-FDT_ERR_BADLAYOUT
+ *	-FDT_ERR_NOSPACE (path area is too small)
+ */
+int fdt_first_region(const void *fdt,
+		int (*h_include)(void *priv, const void *fdt, int offset,
+				 int type, const char *data, int size),
+		void *priv, struct fdt_region *region,
+		char *path, int path_len, int flags,
+		struct fdt_region_state *info);
+
+/** fdt_next_region() - find next region
+ *
+ * See fdt_first_region() for full description. This function finds the
+ * next region according to the provided parameters, which must be the same
+ * as passed to fdt_first_region().
+ *
+ * This function can additionally return -FDT_ERR_NOTFOUND when there are no
+ * more regions
+ */
+int fdt_next_region(const void *fdt,
+		int (*h_include)(void *priv, const void *fdt, int offset,
+				 int type, const char *data, int size),
+		void *priv, struct fdt_region *region,
+		char *path, int path_len, int flags,
+		struct fdt_region_state *info);
+
+/**
+ * fdt_add_alias_regions() - find aliases that point to existing regions
+ *
+ * Once a device tree grep is complete some of the nodes will be present
+ * and some will have been dropped. This function checks all the alias nodes
+ * to figure out which points point to nodes which are still present. These
+ * aliases need to be kept, along with the nodes they reference.
+ *
+ * Given a list of regions function finds the aliases that still apply and
+ * adds more regions to the list for these. This function is called after
+ * fdt_next_region() has finished returning regions and requires the same
+ * state.
+ *
+ * @fdt:	Device tree file to reference
+ * @region:	List of regions that will be kept
+ * @count:	Number of regions
+ * @max_regions: Number of entries that can fit in @region
+ * @info:	Region state as returned from fdt_next_region()
+ * @return new number of regions in @region (i.e. count + the number added)
+ * or -FDT_ERR_NOSPACE if there was not enough space.
+ */
+int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
+			  int max_regions, struct fdt_region_state *info);
+
 #endif /* _LIBFDT_H */
diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile
index 2f5413f..934d614 100644
--- a/lib/libfdt/Makefile
+++ b/lib/libfdt/Makefile
@@ -6,4 +6,4 @@
 #
 
 obj-y += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o \
-	fdt_empty_tree.o fdt_addresses.o
+	fdt_empty_tree.o fdt_addresses.o fdt_region.o
diff --git a/lib/libfdt/fdt_region.c b/lib/libfdt/fdt_region.c
new file mode 100644
index 0000000..9fea775
--- /dev/null
+++ b/lib/libfdt/fdt_region.c
@@ -0,0 +1,492 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2013 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
+ */
+
+#include "libfdt_env.h"
+
+#ifndef USE_HOSTCC
+#include <fdt.h>
+#include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
+
+#include "libfdt_internal.h"
+
+/**
+ * fdt_add_region() - Add a new region to our list
+ *
+ * The region is added if there is space, but in any case we increment the
+ * count. If permitted, and the new region overlaps the last one, we merge
+ * them.
+ *
+ * @info: State information
+ * @offset: Start offset of region
+ * @size: Size of region
+ */
+static int fdt_add_region(struct fdt_region_state *info, int offset, int size)
+{
+	struct fdt_region *reg;
+
+	reg = info->region ? &info->region[info->count - 1] : NULL;
+	if (info->can_merge && info->count &&
+	    info->count <= info->max_regions &&
+	    reg && offset <= reg->offset + reg->size) {
+		reg->size = offset + size - reg->offset;
+	} else if (info->count++ < info->max_regions) {
+		if (reg) {
+			reg++;
+			reg->offset = offset;
+			reg->size = size;
+		}
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static int region_list_contains_offset(struct fdt_region_state *info,
+				       const void *fdt, int target)
+{
+	struct fdt_region *reg;
+	int num;
+
+	target += fdt_off_dt_struct(fdt);
+	for (reg = info->region, num = 0; num < info->count; reg++, num++) {
+		if (target >= reg->offset && target < reg->offset + reg->size)
+			return 1;
+	}
+
+	return 0;
+}
+
+int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
+			  int max_regions, struct fdt_region_state *info)
+{
+	int base = fdt_off_dt_struct(fdt);
+	int node, node_end, offset;
+	int did_alias_header;
+
+	node = fdt_subnode_offset(fdt, 0, "aliases");
+	if (node < 0)
+		return -FDT_ERR_NOTFOUND;
+
+	/* The aliases node must come before the others */
+	node_end = fdt_next_subnode(fdt, node);
+	if (node_end <= 0)
+		return -FDT_ERR_BADLAYOUT;
+	node_end -= sizeof(fdt32_t);
+
+	did_alias_header = 0;
+	info->region = region;
+	info->count = count;
+	info->can_merge = 0;
+	info->max_regions = max_regions;
+
+	for (offset = fdt_first_property_offset(fdt, node);
+	     offset >= 0;
+	     offset = fdt_next_property_offset(fdt, offset)) {
+		const struct fdt_property *prop;
+		const char *name;
+		int target, next;
+
+		prop = fdt_get_property_by_offset(fdt, offset, NULL);
+		name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+		target = fdt_path_offset(fdt, name);
+		if (!region_list_contains_offset(info, fdt, target))
+			continue;
+		next = fdt_next_property_offset(fdt, offset);
+		if (next < 0)
+			next = node_end - sizeof(fdt32_t);
+
+		if (!did_alias_header) {
+			fdt_add_region(info, base + node, 12);
+			did_alias_header = 1;
+		}
+		fdt_add_region(info, base + offset, next - offset);
+	}
+
+	/* Add the 'end' tag */
+	if (did_alias_header)
+		fdt_add_region(info, base + node_end, sizeof(fdt32_t));
+
+	return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE;
+}
+
+/**
+ * fdt_include_supernodes() - Include supernodes required by this node
+ *
+ * When we decided to include a node or property which is not at the top
+ * level, this function forces the inclusion of higher level nodes. For
+ * example, given this tree:
+ *
+ * / {
+ *     testing {
+ *     }
+ * }
+ *
+ * If we decide to include testing then we need the root node to have a valid
+ * tree. This function adds those regions.
+ *
+ * @info: State information
+ * @depth: Current stack depth
+ */
+static int fdt_include_supernodes(struct fdt_region_state *info, int depth)
+{
+	int base = fdt_off_dt_struct(info->fdt);
+	int start, stop_at;
+	int i;
+
+	/*
+	 * Work down the stack looking for supernodes that we didn't include.
+	 * The algortihm here is actually pretty simple, since we know that
+	 * no previous subnode had to include these nodes, or if it did, we
+	 * marked them as included (on the stack) already.
+	 */
+	for (i = 0; i <= depth; i++) {
+		if (!info->stack[i].included) {
+			start = info->stack[i].offset;
+
+			/* Add the FDT_BEGIN_NODE tag of this supernode */
+			fdt_next_tag(info->fdt, start, &stop_at);
+			if (fdt_add_region(info, base + start, stop_at - start))
+				return -1;
+
+			/* Remember that this supernode is now included */
+			info->stack[i].included = 1;
+			info->can_merge = 1;
+		}
+
+		/* Force (later) generation of the FDT_END_NODE tag */
+		if (!info->stack[i].want)
+			info->stack[i].want = WANT_NODES_ONLY;
+	}
+
+	return 0;
+}
+
+enum {
+	FDT_DONE_NOTHING,
+	FDT_DONE_MEM_RSVMAP,
+	FDT_DONE_STRUCT,
+	FDT_DONE_END,
+	FDT_DONE_STRINGS,
+	FDT_DONE_ALL,
+};
+
+int fdt_first_region(const void *fdt,
+		int (*h_include)(void *priv, const void *fdt, int offset,
+				 int type, const char *data, int size),
+		void *priv, struct fdt_region *region,
+		char *path, int path_len, int flags,
+		struct fdt_region_state *info)
+{
+	struct fdt_region_ptrs *p = &info->ptrs;
+
+	/* Set up our state */
+	info->fdt = fdt;
+	info->can_merge = 1;
+	info->max_regions = 1;
+	info->start = -1;
+	p->want = WANT_NOTHING;
+	p->end = path;
+	*p->end = '\0';
+	p->nextoffset = 0;
+	p->depth = -1;
+	p->done = FDT_DONE_NOTHING;
+
+	return fdt_next_region(fdt, h_include, priv, region,
+			       path, path_len, flags, info);
+}
+
+/*
+ * Theory of operation
+ *
+ *
+ *
+
+Note: in this description 'included' means that a node (or other part of
+the tree) should be included in the region list, i.e. it will have a region
+which covers its part of the tree.
+
+This function maintains some state from the last time it is called. It
+checks the next part of the tree that it is supposed to look at
+(p.nextoffset) to see if that should be included or not. When it finds
+something to include, it sets info->start to its offset. This marks the
+start of the region we want to include.
+
+Once info->start is set to the start (i.e. not -1), we continue scanning
+until we find something that we don't want included. This will be the end
+of a region. At this point we can close off the region and add it to the
+list. So we do so, and reset info->start to -1.
+
+One complication here is that we want to merge regions. So when we come to
+add another region later, we may in fact merge it with the previous one if
+one ends where the other starts.
+
+The function fdt_add_region() will return -1 if it fails to add the region,
+because we already have a region ready to be returned, and the new one
+cannot be merged in with it. In this case, we must return the region we
+found, and wait for another call to this function. When it comes, we will
+repeat the processing of the tag and again try to add a region. This time it
+will succeed.
+
+The current state of the pointers (stack, offset, etc.) is maintained in
+a ptrs member. At the start of every loop iteration we make a copy of it.
+The copy is then updated as the tag is processed. Only if we get to the end
+of the loop iteration (and successfully call fdt_add_region() if we need
+to) can we commit the changes we have made to these pointers. For example,
+if we see an FDT_END_NODE tag we will decrement the depth value. But if we
+need to add a region for this tag (let's say because the previous tag is
+included and this FDT_END_NODE tag is not included) then we will only commit
+the result if we were able to add the region. That allows us to retry again
+next time.
+
+We keep track of a variable called 'want' which tells us what we want to
+include when there is no specific information provided by the h_include
+function for a particular property. This basically handles the inclusion of
+properties which are pulled in by virtue of the node they are in. So if you
+include a node, its properties are also included. In this case 'want' will
+be WANT_NODES_AND_PROPS. The FDT_REG_DIRECT_SUBNODES feature also makes use
+of 'want'. While we are inside the subnode, 'want' will be set to
+WANT_NODES_ONLY, so that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE
+tags will be included, and properties will be skipped. If WANT_NOTHING is
+selected, then we will just rely on what the h_include() function tells us.
+
+Using 'want' we work out 'include', which tells us whether this current tag
+should be included or not. As you can imagine, if the value of 'include'
+changes, that means we are on a boundary between nodes to include and nodes
+to exclude. At this point we either close off a previous region and add it
+to the list, or mark the start of a new region.
+
+Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the string
+list. Each of these dealt with as a whole (i.e. we create a region for each
+if it is to be included). For mem_rsvmap we don't allow it to merge with
+the first struct region. For the stringlist we don't allow it to merge with
+the last struct region (which contains at minimum the FDT_END tag).
+*/
+int fdt_next_region(const void *fdt,
+		int (*h_include)(void *priv, const void *fdt, int offset,
+				 int type, const char *data, int size),
+		void *priv, struct fdt_region *region,
+		char *path, int path_len, int flags,
+		struct fdt_region_state *info)
+{
+	int base = fdt_off_dt_struct(fdt);
+	int last_node = 0;
+	const char *str;
+
+	info->region = region;
+	info->count = 0;
+	if (info->ptrs.done < FDT_DONE_MEM_RSVMAP &&
+	    (flags & FDT_REG_ADD_MEM_RSVMAP)) {
+		/* Add the memory reserve map into its own region */
+		if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt),
+				   fdt_off_dt_struct(fdt) -
+				   fdt_off_mem_rsvmap(fdt)))
+			return 0;
+		info->can_merge = 0;	/* Don't allow merging with this */
+		info->ptrs.done = FDT_DONE_MEM_RSVMAP;
+	}
+
+	/*
+	 * Work through the tags one by one, deciding whether each needs to
+	 * be included or not. We set the variable 'include' to indicate our
+	 * decision. 'want' is used to track what we want to include - it
+	 * allows us to pick up all the properties (and/or subnode tags) of
+	 * a node.
+	 */
+	while (info->ptrs.done < FDT_DONE_STRUCT) {
+		const struct fdt_property *prop;
+		struct fdt_region_ptrs p;
+		const char *name;
+		int include = 0;
+		int stop_at = 0;
+		uint32_t tag;
+		int offset;
+		int val;
+		int len;
+
+		/*
+		 * Make a copy of our pointers. If we make it to the end of
+		 * this block then we will commit them back to info->ptrs.
+		 * Otherwise we can try again from the same starting state
+		 * next time we are called.
+		 */
+		p = info->ptrs;
+
+		/*
+		 * Find the tag, and the offset of the next one. If we need to
+		 * stop including tags, then by default we stop *after*
+		 * including the current tag
+		 */
+		offset = p.nextoffset;
+		tag = fdt_next_tag(fdt, offset, &p.nextoffset);
+		stop_at = p.nextoffset;
+
+		switch (tag) {
+		case FDT_PROP:
+			stop_at = offset;
+			prop = fdt_get_property_by_offset(fdt, offset, NULL);
+			str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+			val = h_include(priv, fdt, last_node, FDT_IS_PROP, str,
+					    strlen(str) + 1);
+			if (val == -1) {
+				include = p.want >= WANT_NODES_AND_PROPS;
+			} else {
+				include = val;
+				/*
+				 * Make sure we include the } for this block.
+				 * It might be more correct to have this done
+				 * by the call to fdt_include_supernodes() in
+				 * the case where it adds the node we are
+				 * currently in, but this is equivalent.
+				 */
+				if ((flags & FDT_REG_SUPERNODES) && val &&
+				    !p.want)
+					p.want = WANT_NODES_ONLY;
+			}
+
+			/* Value grepping is not yet supported */
+			break;
+
+		case FDT_NOP:
+			include = p.want >= WANT_NODES_AND_PROPS;
+			stop_at = offset;
+			break;
+
+		case FDT_BEGIN_NODE:
+			last_node = offset;
+			p.depth++;
+			if (p.depth == FDT_MAX_DEPTH)
+				return -FDT_ERR_TOODEEP;
+			name = fdt_get_name(fdt, offset, &len);
+			if (p.end - path + 2 + len >= path_len)
+				return -FDT_ERR_NOSPACE;
+
+			/* Build the full path of this node */
+			if (p.end != path + 1)
+				*p.end++ = '/';
+			strcpy(p.end, name);
+			p.end += len;
+			info->stack[p.depth].want = p.want;
+			info->stack[p.depth].offset = offset;
+
+			/*
+			 * If we are not intending to include this node unless
+			 * it matches, make sure we stop *before* its tag.
+			 */
+			if (p.want == WANT_NODES_ONLY ||
+			    !(flags & (FDT_REG_DIRECT_SUBNODES |
+				       FDT_REG_ALL_SUBNODES))) {
+				stop_at = offset;
+				p.want = WANT_NOTHING;
+			}
+			val = h_include(priv, fdt, offset, FDT_IS_NODE, path,
+					p.end - path + 1);
+
+			/* Include this if requested */
+			if (val) {
+				p.want = (flags & FDT_REG_ALL_SUBNODES) ?
+					WANT_ALL_NODES_AND_PROPS :
+					WANT_NODES_AND_PROPS;
+			}
+
+			/* If not requested, decay our 'p.want' value */
+			else if (p.want) {
+				if (p.want != WANT_ALL_NODES_AND_PROPS)
+					p.want--;
+
+			/* Not including this tag, so stop now */
+			} else {
+				stop_at = offset;
+			}
+
+			/*
+			 * Decide whether to include this tag, and update our
+			 * stack with the state for this node
+			 */
+			include = p.want;
+			info->stack[p.depth].included = include;
+			break;
+
+		case FDT_END_NODE:
+			include = p.want;
+			if (p.depth < 0)
+				return -FDT_ERR_BADSTRUCTURE;
+
+			/*
+			 * If we don't want this node, stop right away, unless
+			 * we are including subnodes
+			 */
+			if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES))
+				stop_at = offset;
+			p.want = info->stack[p.depth].want;
+			p.depth--;
+			while (p.end > path && *--p.end != '/')
+				;
+			*p.end = '\0';
+			break;
+
+		case FDT_END:
+			/* We always include the end tag */
+			include = 1;
+			p.done = FDT_DONE_STRUCT;
+			break;
+		}
+
+		/* If this tag is to be included, mark it as region start */
+		if (include && info->start == -1) {
+			/* Include any supernodes required by this one */
+			if (flags & FDT_REG_SUPERNODES) {
+				if (fdt_include_supernodes(info, p.depth))
+					return 0;
+			}
+			info->start = offset;
+		}
+
+		/*
+		 * If this tag is not to be included, finish up the current
+		 * region.
+		 */
+		if (!include && info->start != -1) {
+			if (fdt_add_region(info, base + info->start,
+					   stop_at - info->start))
+				return 0;
+			info->start = -1;
+			info->can_merge = 1;
+		}
+
+		/* If we have made it this far, we can commit our pointers */
+		info->ptrs = p;
+	}
+
+	/* Add a region for the END tag and a separate one for string table */
+	if (info->ptrs.done < FDT_DONE_END) {
+		if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt))
+			return -FDT_ERR_BADSTRUCTURE;
+
+		if (fdt_add_region(info, base + info->start,
+				   info->ptrs.nextoffset - info->start))
+			return 0;
+		info->ptrs.done++;
+	}
+	if (info->ptrs.done < FDT_DONE_STRINGS) {
+		if (flags & FDT_REG_ADD_STRING_TAB) {
+			info->can_merge = 0;
+			if (fdt_off_dt_strings(fdt) <
+			    base + info->ptrs.nextoffset)
+				return -FDT_ERR_BADLAYOUT;
+			if (fdt_add_region(info, fdt_off_dt_strings(fdt),
+					   fdt_size_dt_strings(fdt)))
+				return 0;
+		}
+		info->ptrs.done++;
+	}
+
+	return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND;
+}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (4 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size Simon Glass
                   ` (49 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This tool allows us to extract subsets of a device tree file. It is used by
the SPL vuild, which needs to cut down the device tree size for use in
limited memory.

This tool was originally written for libfdt but it has not been accepted
upstream, so for now, include it in U-Boot. Several utilfdt library
functions been included inline here.

If fdtgrep is eventually accepted in libfdt then we can bring that version
of libfdt in here, and drop fdtgrep (requiring that fdtgrep is provided by
the user).

If it is not accepted then another approach would be to write a special
tool for chopping down device tree files for SPL. While it would use the
same libfdt support, it would be less code than fdtgrep.c because it would
not have general-purpose functions.

Another approach (which was used with v1 of this series) is to sprinkler all
the device tree files with #ifdef. I don't like that idea.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2:
- Add new patch with fdtgrep tool

 tools/Makefile  |    6 +-
 tools/fdtgrep.c | 1234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1239 insertions(+), 1 deletion(-)
 create mode 100644 tools/fdtgrep.c

diff --git a/tools/Makefile b/tools/Makefile
index 8ff9c2e..98414f7 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -58,7 +58,8 @@ hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
 FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
 # Flattened device tree objects
 LIBFDT_OBJS := $(addprefix lib/libfdt/, \
-			fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
+			fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o \
+			fdt_region.o)
 RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
 					rsa-sign.o rsa-verify.o rsa-checksum.o \
 					rsa-mod-exp.o)
@@ -155,6 +156,9 @@ hostprogs-$(CONFIG_ARMADA_XP) += kwboot
 hostprogs-y += proftool
 hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela
 
+hostprogs-y += fdtgrep
+fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
+
 # We build some files with extra pedantic flags to try to minimize things
 # that won't build on some weird host compiler -- though there are lots of
 # exceptions for files that aren't complaint.
diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c
new file mode 100644
index 0000000..caaf600
--- /dev/null
+++ b/tools/fdtgrep.c
@@ -0,0 +1,1234 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Perform a grep of an FDT either displaying the source subset or producing
+ * a new .dtb subset which can be used as required.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <../include/libfdt.h>
+#include <libfdt_internal.h>
+
+/* Define DEBUG to get some debugging output on stderr */
+#ifdef DEBUG
+#define debug(a, b...) fprintf(stderr, a, ## b)
+#else
+#define debug(a, b...)
+#endif
+
+/* A linked list of values we are grepping for */
+struct value_node {
+	int type;		/* Types this value matches (FDT_IS... mask) */
+	int include;		/* 1 to include matches, 0 to exclude */
+	const char *string;	/* String to match */
+	struct value_node *next;	/* Pointer to next node, or NULL */
+};
+
+/* Output formats we support */
+enum output_t {
+	OUT_DTS,		/* Device tree source */
+	OUT_DTB,		/* Valid device tree binary */
+	OUT_BIN,		/* Fragment of .dtb, for hashing */
+};
+
+/* Holds information which controls our output and options */
+struct display_info {
+	enum output_t output;	/* Output format */
+	int add_aliases;	/* Add aliases node to output */
+	int all;		/* Display all properties/nodes */
+	int colour;		/* Display output in ANSI colour */
+	int region_list;	/* Output a region list */
+	int flags;		/* Flags (FDT_REG_...) */
+	int list_strings;	/* List strings in string table */
+	int show_offset;	/* Show offset */
+	int show_addr;		/* Show address */
+	int header;		/* Output an FDT header */
+	int diff;		/* Show +/- diff markers */
+	int include_root;	/* Include the root node and all properties */
+	int remove_strings;	/* Remove unused strings */
+	int show_dts_version;	/* Put '/dts-v1/;' on the first line */
+	int types_inc;		/* Mask of types that we include (FDT_IS...) */
+	int types_exc;		/* Mask of types that we exclude (FDT_IS...) */
+	int invert;		/* Invert polarity of match */
+	struct value_node *value_head;	/* List of values to match */
+	const char *output_fname;	/* Output filename */
+	FILE *fout;		/* File to write dts/dtb output */
+};
+
+static void report_error(const char *where, int err)
+{
+	fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
+}
+
+/* Supported ANSI colours */
+enum {
+	COL_BLACK,
+	COL_RED,
+	COL_GREEN,
+	COL_YELLOW,
+	COL_BLUE,
+	COL_MAGENTA,
+	COL_CYAN,
+	COL_WHITE,
+
+	COL_NONE = -1,
+};
+
+/**
+ * print_ansi_colour() - Print out the ANSI sequence for a colour
+ *
+ * @fout:	Output file
+ * @col:	Colour to output (COL_...), or COL_NONE to reset colour
+ */
+static void print_ansi_colour(FILE *fout, int col)
+{
+	if (col == COL_NONE)
+		fprintf(fout, "\033[0m");
+	else
+		fprintf(fout, "\033[1;%dm", col + 30);
+}
+
+
+/**
+ * value_add() - Add a new value to our list of things to grep for
+ *
+ * @disp:	Display structure, holding info about our options
+ * @headp:	Pointer to header pointer of list
+ * @type:	Type of this value (FDT_IS_...)
+ * @include:	1 if we want to include matches, 0 to exclude
+ * @str:	String value to match
+ */
+static int value_add(struct display_info *disp, struct value_node **headp,
+		     int type, int include, const char *str)
+{
+	struct value_node *node;
+
+	/*
+	 * Keep track of which types we are excluding/including. We don't
+	 * allow both including and excluding things, because it doesn't make
+	 * sense. 'Including' means that everything not mentioned is
+	 * excluded. 'Excluding' means that everything not mentioned is
+	 * included. So using the two together would be meaningless.
+	 */
+	if (include)
+		disp->types_inc |= type;
+	else
+		disp->types_exc |= type;
+	if (disp->types_inc & disp->types_exc & type) {
+		fprintf(stderr,
+			"Cannot use both include and exclude for '%s'\n", str);
+		return -1;
+	}
+
+	str = strdup(str);
+	node = malloc(sizeof(*node));
+	if (!str || !node) {
+		fprintf(stderr, "Out of memory\n");
+		return -1;
+	}
+	node->next = *headp;
+	node->type = type;
+	node->include = include;
+	node->string = str;
+	*headp = node;
+
+	return 0;
+}
+
+static bool util_is_printable_string(const void *data, int len)
+{
+	const char *s = data;
+	const char *ss, *se;
+
+	/* zero length is not */
+	if (len == 0)
+		return 0;
+
+	/* must terminate with zero */
+	if (s[len - 1] != '\0')
+		return 0;
+
+	se = s + len;
+
+	while (s < se) {
+		ss = s;
+		while (s < se && *s && isprint((unsigned char)*s))
+			s++;
+
+		/* not zero, or not done yet */
+		if (*s != '\0' || s == ss)
+			return 0;
+
+		s++;
+	}
+
+	return 1;
+}
+
+static void utilfdt_print_data(const char *data, int len)
+{
+	int i;
+	const char *p = data;
+	const char *s;
+
+	/* no data, don't print */
+	if (len == 0)
+		return;
+
+	if (util_is_printable_string(data, len)) {
+		printf(" = ");
+
+		s = data;
+		do {
+			printf("\"%s\"", s);
+			s += strlen(s) + 1;
+			if (s < data + len)
+				printf(", ");
+		} while (s < data + len);
+
+	} else if ((len % 4) == 0) {
+		const uint32_t *cell = (const uint32_t *)data;
+
+		printf(" = <");
+		for (i = 0, len /= 4; i < len; i++)
+			printf("0x%08x%s", fdt32_to_cpu(cell[i]),
+			       i < (len - 1) ? " " : "");
+		printf(">");
+	} else {
+		printf(" = [");
+		for (i = 0; i < len; i++)
+			printf("%02x%s", *p++, i < len - 1 ? " " : "");
+		printf("]");
+	}
+}
+
+/**
+ * display_fdt_by_regions() - Display regions of an FDT source
+ *
+ * This dumps an FDT as source, but only certain regions of it. This is the
+ * final stage of the grep - we have a list of regions we want to display,
+ * and this function displays them.
+ *
+ * @disp:	Display structure, holding info about our options
+ * @blob:	FDT blob to display
+ * @region:	List of regions to display
+ * @count:	Number of regions
+ */
+static int display_fdt_by_regions(struct display_info *disp, const void *blob,
+		struct fdt_region region[], int count)
+{
+	struct fdt_region *reg = region, *reg_end = region + count;
+	uint32_t off_mem_rsvmap = fdt_off_mem_rsvmap(blob);
+	int base = fdt_off_dt_struct(blob);
+	int version = fdt_version(blob);
+	int offset, nextoffset;
+	int tag, depth, shift;
+	FILE *f = disp->fout;
+	uint64_t addr, size;
+	int in_region;
+	int file_ofs;
+	int i;
+
+	if (disp->show_dts_version)
+		fprintf(f, "/dts-v1/;\n");
+
+	if (disp->header) {
+		fprintf(f, "// magic:\t\t0x%x\n", fdt_magic(blob));
+		fprintf(f, "// totalsize:\t\t0x%x (%d)\n", fdt_totalsize(blob),
+			fdt_totalsize(blob));
+		fprintf(f, "// off_dt_struct:\t0x%x\n",
+			fdt_off_dt_struct(blob));
+		fprintf(f, "// off_dt_strings:\t0x%x\n",
+			fdt_off_dt_strings(blob));
+		fprintf(f, "// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
+		fprintf(f, "// version:\t\t%d\n", version);
+		fprintf(f, "// last_comp_version:\t%d\n",
+			fdt_last_comp_version(blob));
+		if (version >= 2) {
+			fprintf(f, "// boot_cpuid_phys:\t0x%x\n",
+				fdt_boot_cpuid_phys(blob));
+		}
+		if (version >= 3) {
+			fprintf(f, "// size_dt_strings:\t0x%x\n",
+				fdt_size_dt_strings(blob));
+		}
+		if (version >= 17) {
+			fprintf(f, "// size_dt_struct:\t0x%x\n",
+				fdt_size_dt_struct(blob));
+		}
+		fprintf(f, "\n");
+	}
+
+	if (disp->flags & FDT_REG_ADD_MEM_RSVMAP) {
+		const struct fdt_reserve_entry *p_rsvmap;
+
+		p_rsvmap = (const struct fdt_reserve_entry *)
+				((const char *)blob + off_mem_rsvmap);
+		for (i = 0; ; i++) {
+			addr = fdt64_to_cpu(p_rsvmap[i].address);
+			size = fdt64_to_cpu(p_rsvmap[i].size);
+			if (addr == 0 && size == 0)
+				break;
+
+			fprintf(f, "/memreserve/ %llx %llx;\n",
+				(unsigned long long)addr,
+				(unsigned long long)size);
+		}
+	}
+
+	depth = 0;
+	nextoffset = 0;
+	shift = 4;	/* 4 spaces per indent */
+	do {
+		const struct fdt_property *prop;
+		const char *name;
+		int show;
+		int len;
+
+		offset = nextoffset;
+
+		/*
+		 * Work out the file offset of this offset, and decide
+		 * whether it is in the region list or not
+		 */
+		file_ofs = base + offset;
+		if (reg < reg_end && file_ofs >= reg->offset + reg->size)
+			reg++;
+		in_region = reg < reg_end && file_ofs >= reg->offset &&
+				file_ofs < reg->offset + reg->size;
+		tag = fdt_next_tag(blob, offset, &nextoffset);
+
+		if (tag == FDT_END)
+			break;
+		show = in_region || disp->all;
+		if (show && disp->diff)
+			fprintf(f, "%c", in_region ? '+' : '-');
+
+		if (!show) {
+			/* Do this here to avoid 'if (show)' in every 'case' */
+			if (tag == FDT_BEGIN_NODE)
+				depth++;
+			else if (tag == FDT_END_NODE)
+				depth--;
+			continue;
+		}
+		if (tag != FDT_END) {
+			if (disp->show_addr)
+				fprintf(f, "%4x: ", file_ofs);
+			if (disp->show_offset)
+				fprintf(f, "%4x: ", file_ofs - base);
+		}
+
+		/* Green means included, red means excluded */
+		if (disp->colour)
+			print_ansi_colour(f, in_region ? COL_GREEN : COL_RED);
+
+		switch (tag) {
+		case FDT_PROP:
+			prop = fdt_get_property_by_offset(blob, offset, NULL);
+			name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
+			fprintf(f, "%*s%s", depth * shift, "", name);
+			utilfdt_print_data(prop->data,
+					   fdt32_to_cpu(prop->len));
+			fprintf(f, ";");
+			break;
+
+		case FDT_NOP:
+			fprintf(f, "%*s// [NOP]", depth * shift, "");
+			break;
+
+		case FDT_BEGIN_NODE:
+			name = fdt_get_name(blob, offset, &len);
+			fprintf(f, "%*s%s {", depth++ * shift, "",
+				*name ? name : "/");
+			break;
+
+		case FDT_END_NODE:
+			fprintf(f, "%*s};", --depth * shift, "");
+			break;
+		}
+
+		/* Reset colour back to normal before end of line */
+		if (disp->colour)
+			print_ansi_colour(f, COL_NONE);
+		fprintf(f, "\n");
+	} while (1);
+
+	/* Print a list of strings if requested */
+	if (disp->list_strings) {
+		const char *str;
+		int str_base = fdt_off_dt_strings(blob);
+
+		for (offset = 0; offset < fdt_size_dt_strings(blob);
+				offset += strlen(str) + 1) {
+			str = fdt_string(blob, offset);
+			int len = strlen(str) + 1;
+			int show;
+
+			/* Only print strings that are in the region */
+			file_ofs = str_base + offset;
+			in_region = reg < reg_end &&
+					file_ofs >= reg->offset &&
+					file_ofs + len < reg->offset +
+						reg->size;
+			show = in_region || disp->all;
+			if (show && disp->diff)
+				printf("%c", in_region ? '+' : '-');
+			if (disp->show_addr)
+				printf("%4x: ", file_ofs);
+			if (disp->show_offset)
+				printf("%4x: ", offset);
+			printf("%s\n", str);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * dump_fdt_regions() - Dump regions of an FDT as binary data
+ *
+ * This dumps an FDT as binary, but only certain regions of it. This is the
+ * final stage of the grep - we have a list of regions we want to dump,
+ * and this function dumps them.
+ *
+ * The output of this function may or may not be a valid FDT. To ensure it
+ * is, these disp->flags must be set:
+ *
+ *   FDT_REG_SUPERNODES: ensures that subnodes are preceeded by their
+ *		parents. Without this option, fragments of subnode data may be
+ *		output without the supernodes above them. This is useful for
+ *		hashing but cannot produce a valid FDT.
+ *   FDT_REG_ADD_STRING_TAB: Adds a string table to the end of the FDT.
+ *		Without this none of the properties will have names
+ *   FDT_REG_ADD_MEM_RSVMAP: Adds a mem_rsvmap table - an FDT is invalid
+ *		without this.
+ *
+ * @disp:	Display structure, holding info about our options
+ * @blob:	FDT blob to display
+ * @region:	List of regions to display
+ * @count:	Number of regions
+ * @out:	Output destination
+ */
+static int dump_fdt_regions(struct display_info *disp, const void *blob,
+		struct fdt_region region[], int count, char *out)
+{
+	struct fdt_header *fdt;
+	int size, struct_start;
+	int ptr;
+	int i;
+
+	/* Set up a basic header (even if we don't actually write it) */
+	fdt = (struct fdt_header *)out;
+	memset(fdt, '\0', sizeof(*fdt));
+	fdt_set_magic(fdt, FDT_MAGIC);
+	struct_start = FDT_ALIGN(sizeof(struct fdt_header),
+					sizeof(struct fdt_reserve_entry));
+	fdt_set_off_mem_rsvmap(fdt, struct_start);
+	fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+	fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+
+	/*
+	 * Calculate the total size of the regions we are writing out. The
+	 * first will be the mem_rsvmap if the FDT_REG_ADD_MEM_RSVMAP flag
+	 * is set. The last will be the string table if FDT_REG_ADD_STRING_TAB
+	 * is set.
+	 */
+	for (i = size = 0; i < count; i++)
+		size += region[i].size;
+
+	/* Bring in the mem_rsvmap section from the old file if requested */
+	if (count > 0 && (disp->flags & FDT_REG_ADD_MEM_RSVMAP)) {
+		struct_start += region[0].size;
+		size -= region[0].size;
+	}
+	fdt_set_off_dt_struct(fdt, struct_start);
+
+	/* Update the header to have the correct offsets/sizes */
+	if (count >= 2 && (disp->flags & FDT_REG_ADD_STRING_TAB)) {
+		int str_size;
+
+		str_size = region[count - 1].size;
+		fdt_set_size_dt_struct(fdt, size - str_size);
+		fdt_set_off_dt_strings(fdt, struct_start + size - str_size);
+		fdt_set_size_dt_strings(fdt, str_size);
+		fdt_set_totalsize(fdt, struct_start + size);
+	}
+
+	/* Write the header if required */
+	ptr = 0;
+	if (disp->header) {
+		ptr = sizeof(*fdt);
+		while (ptr < fdt_off_mem_rsvmap(fdt))
+			out[ptr++] = '\0';
+	}
+
+	/* Output all the nodes including any mem_rsvmap/string table */
+	for (i = 0; i < count; i++) {
+		struct fdt_region *reg = &region[i];
+
+		memcpy(out + ptr, (const char *)blob + reg->offset, reg->size);
+		ptr += reg->size;
+	}
+
+	return ptr;
+}
+
+/**
+ * show_region_list() - Print out a list of regions
+ *
+ * The list includes the region offset (absolute offset from start of FDT
+ * blob in bytes) and size
+ *
+ * @reg:	List of regions to print
+ * @count:	Number of regions
+ */
+static void show_region_list(struct fdt_region *reg, int count)
+{
+	int i;
+
+	printf("Regions: %d\n", count);
+	for (i = 0; i < count; i++, reg++) {
+		printf("%d:  %-10x  %-10x\n", i, reg->offset,
+		       reg->offset + reg->size);
+	}
+}
+
+static int check_type_include(void *priv, int type, const char *data, int size)
+{
+	struct display_info *disp = priv;
+	struct value_node *val;
+	int match, none_match = FDT_IS_ANY;
+
+	/* If none of our conditions mention this type, we know nothing */
+	debug("type=%x, data=%s\n", type, data ? data : "(null)");
+	if (!((disp->types_inc | disp->types_exc) & type)) {
+		debug("   - not in any condition\n");
+		return -1;
+	}
+
+	/*
+	 * Go through the list of conditions. For inclusive conditions, we
+	 * return 1 at the first match. For exclusive conditions, we must
+	 * check that there are no matches.
+	 */
+	for (val = disp->value_head; val; val = val->next) {
+		if (!(type & val->type))
+			continue;
+		match = fdt_stringlist_contains(data, size, val->string);
+		debug("      - val->type=%x, str='%s', match=%d\n",
+		      val->type, val->string, match);
+		if (match && val->include) {
+			debug("   - match inc %s\n", val->string);
+			return 1;
+		}
+		if (match)
+			none_match &= ~val->type;
+	}
+
+	/*
+	 * If this is an exclusive condition, and nothing matches, then we
+	 * should return 1.
+	 */
+	if ((type & disp->types_exc) && (none_match & type)) {
+		debug("   - match exc\n");
+		/*
+		 * Allow FDT_IS_COMPAT to make the final decision in the
+		 * case where there is no specific type
+		 */
+		if (type == FDT_IS_NODE && disp->types_exc == FDT_ANY_GLOBAL) {
+			debug("   - supressed exc node\n");
+			return -1;
+		}
+		return 1;
+	}
+
+	/*
+	 * Allow FDT_IS_COMPAT to make the final decision in the
+	 * case where there is no specific type (inclusive)
+	 */
+	if (type == FDT_IS_NODE && disp->types_inc == FDT_ANY_GLOBAL)
+		return -1;
+
+	debug("   - no match, types_inc=%x, types_exc=%x, none_match=%x\n",
+	      disp->types_inc, disp->types_exc, none_match);
+
+	return 0;
+}
+
+/**
+ * h_include() - Include handler function for fdt_find_regions()
+ *
+ * This function decides whether to include or exclude a node, property or
+ * compatible string. The function is defined by fdt_find_regions().
+ *
+ * The algorithm is documented in the code - disp->invert is 0 for normal
+ * operation, and 1 to invert the sense of all matches.
+ *
+ * See
+ */
+static int h_include(void *priv, const void *fdt, int offset, int type,
+		     const char *data, int size)
+{
+	struct display_info *disp = priv;
+	int inc, len;
+
+	inc = check_type_include(priv, type, data, size);
+	if (disp->include_root && type == FDT_IS_PROP && offset == 0 && inc)
+		return 1;
+
+	/*
+	 * If the node name does not tell us anything, check the
+	 * compatible string
+	 */
+	if (inc == -1 && type == FDT_IS_NODE) {
+		debug("   - checking compatible2\n");
+		data = fdt_getprop(fdt, offset, "compatible", &len);
+		inc = check_type_include(priv, FDT_IS_COMPAT, data, len);
+	}
+
+	/* If we still have no idea, check for properties in the node */
+	if (inc != 1 && type == FDT_IS_NODE &&
+	    (disp->types_inc & FDT_NODE_HAS_PROP)) {
+		debug("   - checking node '%s'\n",
+		      fdt_get_name(fdt, offset, NULL));
+		for (offset = fdt_first_property_offset(fdt, offset);
+		     offset > 0 && inc != 1;
+		     offset = fdt_next_property_offset(fdt, offset)) {
+			const struct fdt_property *prop;
+			const char *str;
+
+			prop = fdt_get_property_by_offset(fdt, offset, NULL);
+			if (!prop)
+				continue;
+			str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+			inc = check_type_include(priv, FDT_NODE_HAS_PROP, str,
+						 strlen(str));
+		}
+		if (inc == -1)
+			inc = 0;
+	}
+
+	switch (inc) {
+	case 1:
+		inc = !disp->invert;
+		break;
+	case 0:
+		inc = disp->invert;
+		break;
+	}
+	debug("   - returning %d\n", inc);
+
+	return inc;
+}
+
+static int h_cmp_region(const void *v1, const void *v2)
+{
+	const struct fdt_region *region1 = v1, *region2 = v2;
+
+	return region1->offset - region2->offset;
+}
+
+static int fdtgrep_find_regions(const void *fdt,
+		int (*include_func)(void *priv, const void *fdt, int offset,
+				 int type, const char *data, int size),
+		struct display_info *disp, struct fdt_region *region,
+		int max_regions, char *path, int path_len, int flags)
+{
+	struct fdt_region_state state;
+	int count;
+	int ret;
+
+	count = 0;
+	ret = fdt_first_region(fdt, include_func, disp,
+			&region[count++], path, path_len,
+			disp->flags, &state);
+	while (ret == 0) {
+		ret = fdt_next_region(fdt, include_func, disp,
+				count < max_regions ? &region[count] : NULL,
+				path, path_len, disp->flags, &state);
+		if (!ret)
+			count++;
+	}
+
+	/* Find all the aliases and add those regions back in */
+	if (disp->add_aliases && count < max_regions) {
+		int new_count;
+
+		new_count = fdt_add_alias_regions(fdt, region, count,
+						  max_regions, &state);
+		if (new_count > max_regions) {
+			region = malloc(new_count * sizeof(struct fdt_region));
+			if (!region) {
+				fprintf(stderr,
+					"Out of memory for %d regions\n",
+					count);
+				return -1;
+			}
+			memcpy(region, state.region,
+			       count * sizeof(struct fdt_region));
+			free(state.region);
+			new_count = fdt_add_alias_regions(fdt, region, count,
+							  max_regions, &state);
+		}
+
+		/*
+		 * The alias regions will now be at the end of the list. Sort
+		 * the regions by offset to get things into the right order
+		 */
+		qsort(region, new_count, sizeof(struct fdt_region),
+		      h_cmp_region);
+		count = new_count;
+	}
+
+	if (ret != -FDT_ERR_NOTFOUND)
+		return ret;
+
+	return count;
+}
+
+int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)
+{
+	int fd = 0;	/* assume stdin */
+	char *buf = NULL;
+	off_t bufsize = 1024, offset = 0;
+	int ret = 0;
+
+	*buffp = NULL;
+	if (strcmp(filename, "-") != 0) {
+		fd = open(filename, O_RDONLY);
+		if (fd < 0)
+			return errno;
+	}
+
+	/* Loop until we have read everything */
+	buf = malloc(bufsize);
+	if (!buf)
+		return -ENOMEM;
+	do {
+		/* Expand the buffer to hold the next chunk */
+		if (offset == bufsize) {
+			bufsize *= 2;
+			buf = realloc(buf, bufsize);
+			if (!buf)
+				return -ENOMEM;
+		}
+
+		ret = read(fd, &buf[offset], bufsize - offset);
+		if (ret < 0) {
+			ret = errno;
+			break;
+		}
+		offset += ret;
+	} while (ret != 0);
+
+	/* Clean up, including closing stdin; return errno on error */
+	close(fd);
+	if (ret)
+		free(buf);
+	else
+		*buffp = buf;
+	*len = bufsize;
+	return ret;
+}
+
+int utilfdt_read_err(const char *filename, char **buffp)
+{
+	off_t len;
+	return utilfdt_read_err_len(filename, buffp, &len);
+}
+
+char *utilfdt_read_len(const char *filename, off_t *len)
+{
+	char *buff;
+	int ret = utilfdt_read_err_len(filename, &buff, len);
+
+	if (ret) {
+		fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
+			strerror(ret));
+		return NULL;
+	}
+	/* Successful read */
+	return buff;
+}
+
+char *utilfdt_read(const char *filename)
+{
+	off_t len;
+	return utilfdt_read_len(filename, &len);
+}
+
+/**
+ * Run the main fdtgrep operation, given a filename and valid arguments
+ *
+ * @param disp		Display information / options
+ * @param filename	Filename of blob file
+ * @param return 0 if ok, -ve on error
+ */
+static int do_fdtgrep(struct display_info *disp, const char *filename)
+{
+	struct fdt_region *region;
+	int max_regions;
+	int count = 100;
+	char path[1024];
+	char *blob;
+	int i, ret;
+
+	blob = utilfdt_read(filename);
+	if (!blob)
+		return -1;
+	ret = fdt_check_header(blob);
+	if (ret) {
+		fprintf(stderr, "Error: %s\n", fdt_strerror(ret));
+		return ret;
+	}
+
+	/* Allow old files, but they are untested */
+	if (fdt_version(blob) < 17 && disp->value_head) {
+		fprintf(stderr,
+			"Warning: fdtgrep does not fully support version %d files\n",
+			fdt_version(blob));
+	}
+
+	/*
+	 * We do two passes, since we don't know how many regions we need.
+	 * The first pass will count the regions, but if it is too many,
+	 * we do another pass to actually record them.
+	 */
+	for (i = 0; i < 2; i++) {
+		region = malloc(count * sizeof(struct fdt_region));
+		if (!region) {
+			fprintf(stderr, "Out of memory for %d regions\n",
+				count);
+			return -1;
+		}
+		max_regions = count;
+		count = fdtgrep_find_regions(blob,
+				h_include, disp,
+				region, max_regions, path, sizeof(path),
+				disp->flags);
+		if (count < 0) {
+			report_error("fdt_find_regions", count);
+			return -1;
+		}
+		if (count <= max_regions)
+			break;
+		free(region);
+	}
+
+	/* Optionally print a list of regions */
+	if (disp->region_list)
+		show_region_list(region, count);
+
+	/* Output either source .dts or binary .dtb */
+	if (disp->output == OUT_DTS) {
+		ret = display_fdt_by_regions(disp, blob, region, count);
+	} else {
+		void *fdt;
+		/* Allow reserved memory section to expand slightly */
+		int size = fdt_totalsize(blob) + 16;
+
+		fdt = malloc(size);
+		if (!fdt) {
+			fprintf(stderr, "Out_of_memory\n");
+			ret = -1;
+			goto err;
+		}
+		size = dump_fdt_regions(disp, blob, region, count, fdt);
+		if (disp->remove_strings) {
+			void *out;
+
+			out = malloc(size);
+			if (!out) {
+				fprintf(stderr, "Out_of_memory\n");
+				ret = -1;
+				goto err;
+			}
+			ret = fdt_remove_unused_strings(fdt, out);
+			if (ret < 0) {
+				fprintf(stderr,
+					"Failed to remove unused strings: err=%d\n",
+					ret);
+				goto err;
+			}
+			free(fdt);
+			fdt = out;
+			ret = fdt_pack(fdt);
+			if (ret < 0) {
+				fprintf(stderr, "Failed to pack: err=%d\n",
+					ret);
+				goto err;
+			}
+			size = fdt_totalsize(fdt);
+		}
+
+		if (size != fwrite(fdt, 1, size, disp->fout)) {
+			fprintf(stderr, "Write failure, %d bytes\n", size);
+			free(fdt);
+			ret = 1;
+			goto err;
+		}
+		free(fdt);
+	}
+err:
+	free(blob);
+	free(region);
+
+	return ret;
+}
+
+static const char usage_synopsis[] =
+	"fdtgrep - extract portions from device tree\n"
+	"\n"
+	"Usage:\n"
+	"	fdtgrep <options> <dt file>|-\n\n"
+	"Output formats are:\n"
+	"\tdts - device tree soure text\n"
+	"\tdtb - device tree blob (sets -Hmt automatically)\n"
+	"\tbin - device tree fragment (may not be a valid .dtb)";
+
+/* Helper for usage_short_opts string constant */
+#define USAGE_COMMON_SHORT_OPTS "hV"
+
+/* Helper for aligning long_opts array */
+#define a_argument required_argument
+
+/* Helper for usage_long_opts option array */
+#define USAGE_COMMON_LONG_OPTS \
+	{"help",      no_argument, NULL, 'h'}, \
+	{"version",   no_argument, NULL, 'V'}, \
+	{NULL,        no_argument, NULL, 0x0}
+
+/* Helper for usage_opts_help array */
+#define USAGE_COMMON_OPTS_HELP \
+	"Print this help and exit", \
+	"Print version and exit", \
+	NULL
+
+/* Helper for getopt case statements */
+#define case_USAGE_COMMON_FLAGS \
+	case 'h': usage(NULL); \
+	case 'V': util_version(); \
+	case '?': usage("unknown option");
+
+static const char usage_short_opts[] =
+		"haAc:b:C:defg:G:HIlLmn:N:o:O:p:P:rRsStTv"
+		USAGE_COMMON_SHORT_OPTS;
+static struct option const usage_long_opts[] = {
+	{"show-address",	no_argument, NULL, 'a'},
+	{"colour",		no_argument, NULL, 'A'},
+	{"include-node-with-prop", a_argument, NULL, 'b'},
+	{"include-compat",	a_argument, NULL, 'c'},
+	{"exclude-compat",	a_argument, NULL, 'C'},
+	{"diff",		no_argument, NULL, 'd'},
+	{"enter-node",		no_argument, NULL, 'e'},
+	{"show-offset",		no_argument, NULL, 'f'},
+	{"include-match",	a_argument, NULL, 'g'},
+	{"exclude-match",	a_argument, NULL, 'G'},
+	{"show-header",		no_argument, NULL, 'H'},
+	{"show-version",	no_argument, NULL, 'I'},
+	{"list-regions",	no_argument, NULL, 'l'},
+	{"list-strings",	no_argument, NULL, 'L'},
+	{"include-mem",		no_argument, NULL, 'm'},
+	{"include-node",	a_argument, NULL, 'n'},
+	{"exclude-node",	a_argument, NULL, 'N'},
+	{"include-prop",	a_argument, NULL, 'p'},
+	{"exclude-prop",	a_argument, NULL, 'P'},
+	{"remove-strings",	no_argument, NULL, 'r'},
+	{"include-root",	no_argument, NULL, 'R'},
+	{"show-subnodes",	no_argument, NULL, 's'},
+	{"skip-supernodes",	no_argument, NULL, 'S'},
+	{"show-stringtab",	no_argument, NULL, 't'},
+	{"show-aliases",	no_argument, NULL, 'T'},
+	{"out",			a_argument, NULL, 'o'},
+	{"out-format",		a_argument, NULL, 'O'},
+	{"invert-match",	no_argument, NULL, 'v'},
+	USAGE_COMMON_LONG_OPTS,
+};
+static const char * const usage_opts_help[] = {
+	"Display address",
+	"Show all nodes/tags, colour those that match",
+	"Include contains containing property",
+	"Compatible nodes to include in grep",
+	"Compatible nodes to exclude in grep",
+	"Diff: Mark matching nodes with +, others with -",
+	"Enter direct subnode names of matching nodes",
+	"Display offset",
+	"Node/property/compatible string to include in grep",
+	"Node/property/compatible string to exclude in grep",
+	"Output a header",
+	"Put \"/dts-v1/;\" on first line of dts output",
+	"Output a region list",
+	"List strings in string table",
+	"Include mem_rsvmap section in binary output",
+	"Node to include in grep",
+	"Node to exclude in grep",
+	"Property to include in grep",
+	"Property to exclude in grep",
+	"Remove unused strings from string table",
+	"Include root node and all properties",
+	"Show all subnodes matching nodes",
+	"Don't include supernodes of matching nodes",
+	"Include string table in binary output",
+	"Include matching aliases in output",
+	"-o <output file>",
+	"-O <output format>",
+	"Invert the sense of matching (select non-matching lines)",
+	USAGE_COMMON_OPTS_HELP
+};
+
+/**
+ * Call getopt_long() with standard options
+ *
+ * Since all util code runs getopt in the same way, provide a helper.
+ */
+#define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \
+				       usage_long_opts, NULL)
+
+void util_usage(const char *errmsg, const char *synopsis,
+		const char *short_opts, struct option const long_opts[],
+		const char * const opts_help[])
+{
+	FILE *fp = errmsg ? stderr : stdout;
+	const char a_arg[] = "<arg>";
+	size_t a_arg_len = strlen(a_arg) + 1;
+	size_t i;
+	int optlen;
+
+	fprintf(fp,
+		"Usage: %s\n"
+		"\n"
+		"Options: -[%s]\n", synopsis, short_opts);
+
+	/* prescan the --long opt length to auto-align */
+	optlen = 0;
+	for (i = 0; long_opts[i].name; ++i) {
+		/* +1 is for space between --opt and help text */
+		int l = strlen(long_opts[i].name) + 1;
+		if (long_opts[i].has_arg == a_argument)
+			l += a_arg_len;
+		if (optlen < l)
+			optlen = l;
+	}
+
+	for (i = 0; long_opts[i].name; ++i) {
+		/* helps when adding new applets or options */
+		assert(opts_help[i] != NULL);
+
+		/* first output the short flag if it has one */
+		if (long_opts[i].val > '~')
+			fprintf(fp, "      ");
+		else
+			fprintf(fp, "  -%c, ", long_opts[i].val);
+
+		/* then the long flag */
+		if (long_opts[i].has_arg == no_argument) {
+			fprintf(fp, "--%-*s", optlen, long_opts[i].name);
+		} else {
+			fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg,
+				(int)(optlen - strlen(long_opts[i].name) -
+				a_arg_len), "");
+		}
+
+		/* finally the help text */
+		fprintf(fp, "%s\n", opts_help[i]);
+	}
+
+	if (errmsg) {
+		fprintf(fp, "\nError: %s\n", errmsg);
+		exit(EXIT_FAILURE);
+	} else {
+		exit(EXIT_SUCCESS);
+	}
+}
+
+/**
+ * Show usage and exit
+ *
+ * If you name all your usage variables with usage_xxx, then you can call this
+ * help macro rather than expanding all arguments yourself.
+ *
+ * @param errmsg	If non-NULL, an error message to display
+ */
+#define usage(errmsg) \
+	util_usage(errmsg, usage_synopsis, usage_short_opts, \
+		   usage_long_opts, usage_opts_help)
+
+void util_version(void)
+{
+	printf("Version: %s\n", "(U-Boot)");
+	exit(0);
+}
+
+static void scan_args(struct display_info *disp, int argc, char *argv[])
+{
+	int opt;
+
+	while ((opt = util_getopt_long()) != EOF) {
+		int type = 0;
+		int inc = 1;
+
+		switch (opt) {
+		case_USAGE_COMMON_FLAGS
+		case 'a':
+			disp->show_addr = 1;
+			break;
+		case 'A':
+			disp->all = 1;
+			break;
+		case 'b':
+			type = FDT_NODE_HAS_PROP;
+			break;
+		case 'C':
+			inc = 0;
+			/* no break */
+		case 'c':
+			type = FDT_IS_COMPAT;
+			break;
+		case 'd':
+			disp->diff = 1;
+			break;
+		case 'e':
+			disp->flags |= FDT_REG_DIRECT_SUBNODES;
+			break;
+		case 'f':
+			disp->show_offset = 1;
+			break;
+		case 'G':
+			inc = 0;
+			/* no break */
+		case 'g':
+			type = FDT_ANY_GLOBAL;
+			break;
+		case 'H':
+			disp->header = 1;
+			break;
+		case 'l':
+			disp->region_list = 1;
+			break;
+		case 'L':
+			disp->list_strings = 1;
+			break;
+		case 'm':
+			disp->flags |= FDT_REG_ADD_MEM_RSVMAP;
+			break;
+		case 'N':
+			inc = 0;
+			/* no break */
+		case 'n':
+			type = FDT_IS_NODE;
+			break;
+		case 'o':
+			disp->output_fname = optarg;
+			break;
+		case 'O':
+			if (!strcmp(optarg, "dtb"))
+				disp->output = OUT_DTB;
+			else if (!strcmp(optarg, "dts"))
+				disp->output = OUT_DTS;
+			else if (!strcmp(optarg, "bin"))
+				disp->output = OUT_BIN;
+			else
+				usage("Unknown output format");
+			break;
+		case 'P':
+			inc = 0;
+			/* no break */
+		case 'p':
+			type = FDT_IS_PROP;
+			break;
+		case 'r':
+			disp->remove_strings = 1;
+			break;
+		case 'R':
+			disp->include_root = 1;
+			break;
+		case 's':
+			disp->flags |= FDT_REG_ALL_SUBNODES;
+			break;
+		case 'S':
+			disp->flags &= ~FDT_REG_SUPERNODES;
+			break;
+		case 't':
+			disp->flags |= FDT_REG_ADD_STRING_TAB;
+			break;
+		case 'T':
+			disp->add_aliases = 1;
+			break;
+		case 'v':
+			disp->invert = 1;
+			break;
+		case 'I':
+			disp->show_dts_version = 1;
+			break;
+		}
+
+		if (type && value_add(disp, &disp->value_head, type, inc,
+				      optarg))
+			usage("Cannot add value");
+	}
+
+	if (disp->invert && disp->types_exc)
+		usage("-v has no meaning when used with 'exclude' conditions");
+}
+
+int main(int argc, char *argv[])
+{
+	char *filename = NULL;
+	struct display_info disp;
+	int ret;
+
+	/* set defaults */
+	memset(&disp, '\0', sizeof(disp));
+	disp.flags = FDT_REG_SUPERNODES;	/* Default flags */
+
+	scan_args(&disp, argc, argv);
+
+	/* Show matched lines in colour if we can */
+	disp.colour = disp.all && isatty(0);
+
+	/* Any additional arguments can match anything, just like -g */
+	while (optind < argc - 1) {
+		if (value_add(&disp, &disp.value_head, FDT_IS_ANY, 1,
+			      argv[optind++]))
+			usage("Cannot add value");
+	}
+
+	if (optind < argc)
+		filename = argv[optind++];
+	if (!filename)
+		usage("Missing filename");
+
+	/* If a valid .dtb is required, set flags to ensure we get one */
+	if (disp.output == OUT_DTB) {
+		disp.header = 1;
+		disp.flags |= FDT_REG_ADD_MEM_RSVMAP | FDT_REG_ADD_STRING_TAB;
+	}
+
+	if (disp.output_fname) {
+		disp.fout = fopen(disp.output_fname, "w");
+		if (!disp.fout)
+			usage("Cannot open output file");
+	} else {
+		disp.fout = stdout;
+	}
+
+	/* Run the grep and output the results */
+	ret = do_fdtgrep(&disp, filename);
+	if (disp.output_fname)
+		fclose(disp.fout);
+	if (ret)
+		return 1;
+
+	return 0;
+}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (5 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones Simon Glass
                   ` (48 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

The SPL device tree size must be minimised to save memory. Only include
properties that are needed by SPL - this is determined by the presence
of the "u-boot,dm-pre-reloc" property. Also remove a predefined list of
unused properties from the nodes that remain.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Convert hex number to upper case to keep bc happy

Changes in v2:
- Add new patch to reduce SPL device tree size with fdtgrep

 Makefile                    |  2 +-
 arch/arm/cpu/u-boot-spl.lds |  2 +-
 dts/Kconfig                 | 12 ++++++++++++
 scripts/Makefile.spl        | 28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 0a674bf..4276f13 100644
--- a/Makefile
+++ b/Makefile
@@ -1258,7 +1258,7 @@ u-boot.lds: $(LDSCRIPT) prepare FORCE
 
 spl/u-boot-spl.bin: spl/u-boot-spl
 	@:
-spl/u-boot-spl: tools prepare
+spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
 	$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
 
 spl/sunxi-spl.bin: spl/u-boot-spl
diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds
index a8be204..4b6e0f6 100644
--- a/arch/arm/cpu/u-boot-spl.lds
+++ b/arch/arm/cpu/u-boot-spl.lds
@@ -66,7 +66,7 @@ SECTIONS
 		 . = ALIGN(4);
 		__bss_end = .;
 	}
-
+	__bss_size = __bss_end - __bss_start;
 	.dynsym _image_binary_end : { *(.dynsym) }
 	.dynbss : { *(.dynbss) }
 	.dynstr : { *(.dynstr*) }
diff --git a/dts/Kconfig b/dts/Kconfig
index 957f5c7..09cfefb 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -56,4 +56,16 @@ config DEFAULT_DEVICE_TREE
 	  It can be overridden from the command line:
 	  $ make DEVICE_TREE=<device-tree-name>
 
+config OF_SPL_REMOVE_PROPS
+	string "List of device tree properties to drop for SPL"
+	depends on OF_CONTROL && SPL
+	default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent"
+	help
+	  Since SPL normally runs in a reduced memory space, the device tree
+	  is cut down to only what is needed to load and start U-Boot. Only
+	  nodes marked with the property "u-boot,dm-pre-reloc" will be
+	  included. In addition, some properties are not used by U-Boot and
+	  can be discarded. This option defines the list of properties to
+	  discard.
+
 endmenu
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index fd572f4..bcc7ca2 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -151,6 +151,8 @@ boot.bin: $(obj)/u-boot-spl.bin
 
 ALL-y	+= $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg
 
+ALL-$(CONFIG_OF_SEPARATE) += $(obj)/$(SPL_BIN)-pad.bin $(obj)/$(SPL_BIN)-dtb.bin
+
 ifdef CONFIG_SAMSUNG
 ALL-y	+= $(obj)/$(BOARD)-spl.bin
 endif
@@ -165,6 +167,32 @@ endif
 
 all:	$(ALL-y)
 
+quiet_cmd_cat = CAT     $@
+cmd_cat = cat $(filter-out $(PHONY), $^) > $@
+
+$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN)-pad.bin \
+		$(obj)/$(SPL_BIN).dtb FORCE
+	$(call if_changed,cat)
+
+# Create a file that pads from the end of u-boot-spl.bin to bss_end
+$(obj)/$(SPL_BIN)-pad.bin: $(obj)/$(SPL_BIN)
+	@bss_size_str=$(shell $(NM) $< | awk 'BEGIN {size = 0} /__bss_size/ {size = $$1} END {print "ibase=16; " toupper(size)}' | bc); \
+	dd if=/dev/zero of=$@ bs=1 count=$${bss_size_str} 2>/dev/null;
+
+# Pass the original device tree file through fdtgrep twice. The first pass
+# removes any unwanted nodes (i.e. those which don't have the
+# 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
+# pass removes various unused properties from the remaining nodes.
+# The output is typically a much smaller device tree file.
+quiet_cmd_fdtgrep = FDTGREP $@
+      cmd_fdtgrep = $(objtree)/tools/fdtgrep -b u-boot,dm-pre-reloc -RT $< \
+		-n /chosen -O dtb | \
+	$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
+		$(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
+
+$(obj)/$(SPL_BIN).dtb: dts/dt.dtb
+	$(call cmd,fdtgrep)
+
 quiet_cmd_cpp_cfg = CFG     $@
 cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
 	-DDO_DEPS_ONLY -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (6 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member Simon Glass
                   ` (47 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Driver-model I2C drivers can be picked up by the linker script rule for
legacy drivers. Change the order to avoid this.

We could make the legacy code depend on !CONFIG_DM_I2C but that is not
necessary and it is good to keep conditions to a minimum.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 arch/arm/cpu/u-boot-spl.lds | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds
index 4b6e0f6..c5b4f7c 100644
--- a/arch/arm/cpu/u-boot-spl.lds
+++ b/arch/arm/cpu/u-boot-spl.lds
@@ -32,17 +32,17 @@ SECTIONS
 	}
 
 	. = ALIGN(4);
-	.u_boot_list : {
-		KEEP(*(SORT(.u_boot_list*_i2c_*)));
-	}
-
-	. = .;
 #ifdef CONFIG_SPL_DM
 	.u_boot_list : {
 		KEEP(*(SORT(.u_boot_list_*_driver_*)));
 		KEEP(*(SORT(.u_boot_list_*_uclass_*)));
 	}
 #endif
+	. = .;
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*_i2c_*)));
+	}
+
 	. = ALIGN(4);
 
 	__image_copy_end = .;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (7 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage Simon Glass
                   ` (46 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

U-Boot uses structures for hardware access so it is important that these
structures are correct. Add a way of asserting that a structure member is
at a particular offset. This can be created using the datasheet for the
hardware.

This implementation uses Static_assert() since BUILD_BUG_ON() only works
within functions.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 include/common.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/common.h b/include/common.h
index 8f4b2ec..4566bd1 100644
--- a/include/common.h
+++ b/include/common.h
@@ -1010,6 +1010,17 @@ int cpu_release(int nr, int argc, char * const argv[]);
 #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)			\
 	DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
 
+/*
+ * check_member() - Check the offset of a structure member
+ *
+ * @structure:	Name of structure (e.g. global_data)
+ * @member:	Name of member (e.g. baudrate)
+ * @offset:	Expected offset in bytes
+ */
+#define check_member(structure, member, offset) _Static_assert( \
+	offsetof(struct structure, member) == offset, \
+	"`struct " #structure "` offset for `" #member "` is not " #offset)
+
 /* Pull in stuff for the build system */
 #ifdef DO_DEPS_ONLY
 # include <environment.h>
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (8 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console Simon Glass
                   ` (45 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This does not actually help any current arch. For x86 it makes it harder
to call (requires stack) and for ARM it has no effect. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 include/debug_uart.h | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/include/debug_uart.h b/include/debug_uart.h
index f56797b..a75e377 100644
--- a/include/debug_uart.h
+++ b/include/debug_uart.h
@@ -10,8 +10,6 @@
 #ifndef _DEBUG_UART_H
 #define _DEBUG_UART_H
 
-#include <linux/linkage.h>
-
 /*
  * The debug UART is intended for use very early in U-Boot to debug problems
  * when an ICE or other debug mechanism is not available.
@@ -64,46 +62,46 @@ void debug_uart_init(void);
  *
  * @ch:		Character to output
  */
-asmlinkage void printch(int ch);
+void printch(int ch);
 
 /**
  * printascii() - Output an ASCII string to the debug UART
  *
  * @str:	String to output
  */
-asmlinkage void printascii(const char *str);
+void printascii(const char *str);
 
 /**
  * printhex2() - Output a 2-digit hex value
  *
  * @value:	Value to output
  */
-asmlinkage void printhex2(uint value);
+void printhex2(uint value);
 
 /**
  * printhex4() - Output a 4-digit hex value
  *
  * @value:	Value to output
  */
-asmlinkage void printhex4(uint value);
+void printhex4(uint value);
 
 /**
  * printhex8() - Output a 8-digit hex value
  *
  * @value:	Value to output
  */
-asmlinkage void printhex8(uint value);
+void printhex8(uint value);
 
 /*
  * Now define some functions - this should be inserted into the serial driver
  */
 #define DEBUG_UART_FUNCS \
-	asmlinkage void printch(int ch) \
+	void printch(int ch) \
 	{ \
 		_debug_uart_putc(ch); \
 	} \
 \
-	asmlinkage void printascii(const char *str) \
+	void printascii(const char *str) \
 	{ \
 		while (*str) \
 			_debug_uart_putc(*str++); \
@@ -121,17 +119,17 @@ asmlinkage void printhex8(uint value);
 			printhex1(value >> (4 * digits)); \
 	} \
 \
-	asmlinkage void printhex2(uint value) \
+	void printhex2(uint value) \
 	{ \
 		printhex(value, 2); \
 	} \
 \
-	asmlinkage void printhex4(uint value) \
+	void printhex4(uint value) \
 	{ \
 		printhex(value, 4); \
 	} \
 \
-	asmlinkage void printhex8(uint value) \
+	void printhex8(uint value) \
 	{ \
 		printhex(value, 8); \
 	}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (9 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code Simon Glass
                   ` (44 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

When there is no console ready, allow the debug UART to be used for output.
This makes debugging of early code considerably easier.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/console.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/common/console.c b/common/console.c
index 0058222..acad8bd 100644
--- a/common/console.c
+++ b/common/console.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <debug_uart.h>
 #include <stdarg.h>
 #include <iomux.h>
 #include <malloc.h>
@@ -460,6 +461,13 @@ void putc(const char c)
 		return;
 	}
 #endif
+#ifdef CONFIG_DEBUG_UART
+	/* if we don't have a console yet, use the debug UART */
+	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+		printch(c);
+		return;
+	}
+#endif
 #ifdef CONFIG_SILENT_CONSOLE
 	if (gd->flags & GD_FLG_SILENT)
 		return;
@@ -491,7 +499,18 @@ void puts(const char *s)
 		return;
 	}
 #endif
+#ifdef CONFIG_DEBUG_UART
+	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+		while (*s) {
+			int ch = *s++;
 
+			printch(ch);
+			if (ch == '\n')
+				printch('\r');
+		}
+		return;
+	}
+#endif
 #ifdef CONFIG_SILENT_CONSOLE
 	if (gd->flags & GD_FLG_SILENT)
 		return;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (10 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file Simon Glass
                   ` (43 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

At present printf() skips output if it can see there is no console. This
is really just an optimisation, and is not necessary. Also it is currently
incorrect in some cases. Rather than update the logic, just remove it so
that we don't need to keep it in sync.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/console.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/common/console.c b/common/console.c
index acad8bd..ace206c 100644
--- a/common/console.c
+++ b/common/console.c
@@ -456,6 +456,7 @@ static inline void print_pre_console_buffer(int flushpoint) {}
 void putc(const char c)
 {
 #ifdef CONFIG_SANDBOX
+	/* sandbox can send characters to stdout before it has a console */
 	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
 		os_putc(c);
 		return;
@@ -540,11 +541,6 @@ int printf(const char *fmt, ...)
 	uint i;
 	char printbuffer[CONFIG_SYS_PBSIZE];
 
-#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER)
-	if (!gd->have_console)
-		return 0;
-#endif
-
 	va_start(args, fmt);
 
 	/* For this to work, printbuffer must be larger than
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (11 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures Simon Glass
                   ` (42 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

In SPL it is sometimes useful to be able to obtain a dump of the current
driver model state. Since commands are not available, provide a way to
directly call the functions to output this information.

Adjust the existing commands to use these functions.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/Makefile |  1 +
 drivers/core/dump.c   | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/util.h     |  6 ++++
 test/dm/cmd_dm.c      | 82 ++-----------------------------------------
 4 files changed, 106 insertions(+), 79 deletions(-)
 create mode 100644 drivers/core/dump.c

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index a3fec38..ed21fed 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -9,3 +9,4 @@ ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_OF_CONTROL) += simple-bus.o
 endif
 obj-$(CONFIG_DM_DEVICE_REMOVE)	+= device-remove.o
+obj-$(CONFIG_DM)	+= dump.o
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
new file mode 100644
index 0000000..fd4596e
--- /dev/null
+++ b/drivers/core/dump.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <dm/root.h>
+
+static void show_devices(struct udevice *dev, int depth, int last_flag)
+{
+	int i, is_last;
+	struct udevice *child;
+	char class_name[12];
+
+	/* print the first 11 characters to not break the tree-format. */
+	strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name));
+	printf(" %-11s [ %c ]    ", class_name,
+	       dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ');
+
+	for (i = depth; i >= 0; i--) {
+		is_last = (last_flag >> i) & 1;
+		if (i) {
+			if (is_last)
+				printf("    ");
+			else
+				printf("|   ");
+		} else {
+			if (is_last)
+				printf("`-- ");
+			else
+				printf("|-- ");
+		}
+	}
+
+	printf("%s\n", dev->name);
+
+	list_for_each_entry(child, &dev->child_head, sibling_node) {
+		is_last = list_is_last(&child->sibling_node, &dev->child_head);
+		show_devices(child, depth + 1, (last_flag << 1) | is_last);
+	}
+}
+
+void dm_dump_all(void)
+{
+	struct udevice *root;
+
+	root = dm_root();
+	if (root) {
+		printf(" Class       Probed   Name\n");
+		printf("----------------------------------------\n");
+		show_devices(root, -1, 0);
+	}
+}
+
+/**
+ * dm_display_line() - Display information about a single device
+ *
+ * Displays a single line of information with an option prefix
+ *
+ * @dev:	Device to display
+ */
+static void dm_display_line(struct udevice *dev)
+{
+	printf("- %c %s @ %08lx",
+	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
+	       dev->name, (ulong)map_to_sysmem(dev));
+	if (dev->seq != -1 || dev->req_seq != -1)
+		printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
+	puts("\n");
+}
+
+void dm_dump_uclass(void)
+{
+	struct uclass *uc;
+	int ret;
+	int id;
+
+	for (id = 0; id < UCLASS_COUNT; id++) {
+		struct udevice *dev;
+
+		ret = uclass_get(id, &uc);
+		if (ret)
+			continue;
+
+		printf("uclass %d: %s\n", id, uc->uc_drv->name);
+		if (list_empty(&uc->dev_head))
+			continue;
+		list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+			dm_display_line(dev);
+		}
+		puts("\n");
+	}
+}
diff --git a/include/dm/util.h b/include/dm/util.h
index 0cec17b..7dbed67 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -33,4 +33,10 @@ struct list_head;
  */
 int list_count_items(struct list_head *head);
 
+/* Dump out a tree of all devices */
+void dm_dump_all(void);
+
+/* Dump out a list of uclasses and their devices */
+void dm_dump_uclass(void);
+
 #endif
diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 5bb2a99..5c501ec 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -14,96 +14,20 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <dm/root.h>
-#include <dm/uclass-internal.h>
-
-static void show_devices(struct udevice *dev, int depth, int last_flag)
-{
-	int i, is_last;
-	struct udevice *child;
-	char class_name[12];
-
-	/* print the first 11 characters to not break the tree-format. */
-	strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name));
-	printf(" %-11s [ %c ]    ", class_name,
-	       dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ');
-
-	for (i = depth; i >= 0; i--) {
-		is_last = (last_flag >> i) & 1;
-		if (i) {
-			if (is_last)
-				printf("    ");
-			else
-				printf("|   ");
-		} else {
-			if (is_last)
-				printf("`-- ");
-			else
-				printf("|-- ");
-		}
-	}
-
-	printf("%s\n", dev->name);
-
-	list_for_each_entry(child, &dev->child_head, sibling_node) {
-		is_last = list_is_last(&child->sibling_node, &dev->child_head);
-		show_devices(child, depth + 1, (last_flag << 1) | is_last);
-	}
-}
+#include <dm/util.h>
 
 static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc,
 			  char * const argv[])
 {
-	struct udevice *root;
-
-	root = dm_root();
-	if (root) {
-		printf(" Class       Probed   Name\n");
-		printf("----------------------------------------\n");
-		show_devices(root, -1, 0);
-	}
+	dm_dump_all();
 
 	return 0;
 }
 
-/**
- * dm_display_line() - Display information about a single device
- *
- * Displays a single line of information with an option prefix
- *
- * @dev:	Device to display
- */
-static void dm_display_line(struct udevice *dev)
-{
-	printf("- %c %s @ %08lx",
-	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
-	       dev->name, (ulong)map_to_sysmem(dev));
-	if (dev->seq != -1 || dev->req_seq != -1)
-		printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
-	puts("\n");
-}
-
 static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
 			     char * const argv[])
 {
-	struct uclass *uc;
-	int ret;
-	int id;
-
-	for (id = 0; id < UCLASS_COUNT; id++) {
-		struct udevice *dev;
-
-		ret = uclass_get(id, &uc);
-		if (ret)
-			continue;
-
-		printf("uclass %d: %s\n", id, uc->uc_drv->name);
-		if (list_empty(&uc->dev_head))
-			continue;
-		list_for_each_entry(dev, &uc->dev_head, uclass_node) {
-			dm_display_line(dev);
-		}
-		puts("\n");
-	}
+	dm_dump_uclass();
 
 	return 0;
 }
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (12 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree Simon Glass
                   ` (41 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

To avoid bloating SPL code, use debug() where possible in the driver model
core code. The error code is already returned, and can be investigated as
needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/lists.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 0c49d99..2e52500 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -86,13 +86,13 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
 
 	drv = lists_driver_lookup_name(drv_name);
 	if (!drv) {
-		printf("Cannot find driver '%s'\n", drv_name);
+		debug("Cannot find driver '%s'\n", drv_name);
 		return -ENOENT;
 	}
 	ret = device_bind(parent, drv, dev_name, NULL, node, devp);
 	if (ret) {
-		printf("Cannot create device named '%s' (err=%d)\n",
-		       dev_name, ret);
+		debug("Cannot create device named '%s' (err=%d)\n",
+		      dev_name, ret);
 		return ret;
 	}
 
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (13 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter Simon Glass
                   ` (40 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

In some rare cases it is useful to be able to locate a device given a device
tree node offset. An example is when you have an alias that points to a node
and you want to find the associated device. The device may be SPI, MMC or
something else, but you don't need to know the uclass to find it.

Add a function to do a global search for a device, given its device tree
offset.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/device.c | 25 +++++++++++++++++++++++++
 include/dm/device.h   | 14 ++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 85fd1fc..43aff54 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -470,6 +470,31 @@ int device_get_child_by_of_offset(struct udevice *parent, int seq,
 	return device_get_device_tail(dev, ret, devp);
 }
 
+static struct udevice *_device_find_global_by_of_offset(struct udevice *parent,
+							int of_offset)
+{
+	struct udevice *dev, *found;
+
+	if (parent->of_offset == of_offset)
+		return parent;
+
+	list_for_each_entry(dev, &parent->child_head, sibling_node) {
+		found = _device_find_global_by_of_offset(dev, of_offset);
+		if (found)
+			return found;
+	}
+
+	return NULL;
+}
+
+int device_get_global_by_of_offset(int of_offset, struct udevice **devp)
+{
+	struct udevice *dev;
+
+	dev = _device_find_global_by_of_offset(gd->dm_root, of_offset);
+	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
+
 int device_find_first_child(struct udevice *parent, struct udevice **devp)
 {
 	if (list_empty(&parent->child_head)) {
diff --git a/include/dm/device.h b/include/dm/device.h
index 18296bb..9a94ee1 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -390,6 +390,20 @@ int device_get_child_by_of_offset(struct udevice *parent, int seq,
 				  struct udevice **devp);
 
 /**
+ * device_get_global_by_of_offset() - Get a device based on FDT offset
+ *
+ * Locates a device by its device tree offset, searching globally throughout
+ * the all driver model devices.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @of_offset: Device tree offset to find
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_global_by_of_offset(int of_offset, struct udevice **devp);
+
+/**
  * device_find_first_child() - Find the first child of a device
  *
  * @parent: Parent device to search
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (14 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL Simon Glass
                   ` (39 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This parameter is named 'seq' but should be named 'of_offset'.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/device.c | 4 ++--
 include/dm/device.h   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 43aff54..456426a 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -459,14 +459,14 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
 	return -ENODEV;
 }
 
-int device_get_child_by_of_offset(struct udevice *parent, int seq,
+int device_get_child_by_of_offset(struct udevice *parent, int node,
 				  struct udevice **devp)
 {
 	struct udevice *dev;
 	int ret;
 
 	*devp = NULL;
-	ret = device_find_child_by_of_offset(parent, seq, &dev);
+	ret = device_find_child_by_of_offset(parent, node, &dev);
 	return device_get_device_tail(dev, ret, devp);
 }
 
diff --git a/include/dm/device.h b/include/dm/device.h
index 9a94ee1..9fa0048 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -386,7 +386,7 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
  * @devp: Returns pointer to device if found, otherwise this is set to NULL
  * @return 0 if OK, -ve on error
  */
-int device_get_child_by_of_offset(struct udevice *parent, int seq,
+int device_get_child_by_of_offset(struct udevice *parent, int of_offset,
 				  struct udevice **devp);
 
 /**
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (15 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name Simon Glass
                   ` (38 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Now that we support driver model in SPL, allow GPIO drivers to be used there
also.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/gpio/Makefile | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 5864850..67c6374 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -6,13 +6,9 @@
 #
 
 ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_DM_GPIO)		+= gpio-uclass.o
 obj-$(CONFIG_AXP_GPIO)		+= axp_gpio.o
 endif
-/* TODO(sjg at chromium.org): Only tegra supports driver model in SPL */
-ifdef CONFIG_TEGRA_GPIO
 obj-$(CONFIG_DM_GPIO)		+= gpio-uclass.o
-endif
 
 obj-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)	+= intel_ich6_gpio.o
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (16 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO Simon Glass
                   ` (37 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Provide a driver-model function to look up a GPIO name. Make the standard
function use it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/gpio/gpio-uclass.c | 34 ++++++++++++++++++++++++++--------
 include/asm-generic/gpio.h | 13 +++++++++++++
 2 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index bf982b9..c6fd580 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -48,8 +48,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
 	return ret ? ret : -ENOENT;
 }
 
-int gpio_lookup_name(const char *name, struct udevice **devp,
-		     unsigned int *offsetp, unsigned int *gpiop)
+int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
 {
 	struct gpio_dev_priv *uc_priv = NULL;
 	struct udevice *dev;
@@ -57,8 +56,6 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
 	int numeric;
 	int ret;
 
-	if (devp)
-		*devp = NULL;
 	numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
 	for (ret = uclass_first_device(UCLASS_GPIO, &dev);
 	     dev;
@@ -84,12 +81,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
 	if (!dev)
 		return ret ? ret : -EINVAL;
 
+	desc->dev = dev;
+	desc->offset = offset;
+
+	return 0;
+}
+
+int gpio_lookup_name(const char *name, struct udevice **devp,
+		     unsigned int *offsetp, unsigned int *gpiop)
+{
+	struct gpio_desc desc;
+	int ret;
+
+	if (devp)
+		*devp = NULL;
+	ret = dm_gpio_lookup_name(name, &desc);
+	if (ret)
+		return ret;
+
 	if (devp)
-		*devp = dev;
+		*devp = desc.dev;
 	if (offsetp)
-		*offsetp = offset;
-	if (gpiop)
-		*gpiop = uc_priv->gpio_base + offset;
+		*offsetp = desc.offset;
+	if (gpiop) {
+		struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
+
+		*gpiop = uc_priv->gpio_base + desc.offset;
+	}
 
 	return 0;
 }
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index de91e57..b1cf95c 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -322,6 +322,19 @@ struct gpio_dev_priv {
 const char *gpio_get_bank_info(struct udevice *dev, int *offset_count);
 
 /**
+ * dm_gpio_lookup_name() - Look up a named GPIO and return its description
+ *
+ * The name of a GPIO is typically its bank name followed by a number from 0.
+ * For example A0 is the first GPIO in bank A. Each bank is a separate driver
+ * model device.
+ *
+ * @name:	Name to look up
+ * @desc:	Returns description, on success
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc);
+
+/**
  * gpio_lookup_name - Look up a GPIO name and return its details
  *
  * This is used to convert a named GPIO into a device, offset and GPIO
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (17 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap) Simon Glass
                   ` (36 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This function can be used for testing to manually request a GPIO for use,
without resorting to the legacy GPIO API.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/gpio/gpio-uclass.c |  2 +-
 include/asm-generic/gpio.h | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index c6fd580..4efda31 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -127,7 +127,7 @@ static int gpio_find_and_xlate(struct gpio_desc *desc,
 	return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
 }
 
-static int dm_gpio_request(struct gpio_desc *desc, const char *label)
+int dm_gpio_request(struct gpio_desc *desc, const char *label)
 {
 	struct udevice *dev = desc->dev;
 	struct gpio_dev_priv *uc_priv;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index b1cf95c..0af599f 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -434,6 +434,18 @@ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
 			      int flags);
 
 /**
+ * dm_gpio_request() - manually request a GPIO
+ *
+ * Note: This function should only be used for testing / debugging. Instead.
+ * use gpio_request_by_name() to pull GPIOs from the device tree.
+ *
+ * @desc:	GPIO description of GPIO to request (see dm_gpio_lookup_name())
+ * @label:	Label to attach to the GPIO while claimed
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_request(struct gpio_desc *desc, const char *label);
+
+/**
  * gpio_get_list_count() - Returns the number of GPIOs in a list
  *
  * Counts the GPIOs in a list. See gpio_request_by_name() for additional
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap)
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (18 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon) Simon Glass
                   ` (35 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add a simple implementaton of register maps, supporting only direct I/O
for now. This can be enhanced later to support buses which have registers,
such as I2C, SPI and PCI.

It allows drivers which can operate with multiple buses to avoid dealing
with the particulars of register access on that bus.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/Makefile |  1 +
 drivers/core/regmap.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/regmap.h      | 72 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)
 create mode 100644 drivers/core/regmap.c
 create mode 100644 include/regmap.h

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index ed21fed..7851824 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_CONTROL) += simple-bus.o
 endif
 obj-$(CONFIG_DM_DEVICE_REMOVE)	+= device-remove.o
 obj-$(CONFIG_DM)	+= dump.o
+obj-$(CONFIG_OF_CONTROL)	+= regmap.o
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
new file mode 100644
index 0000000..519832f
--- /dev/null
+++ b/drivers/core/regmap.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <regmap.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
+{
+	const void *blob = gd->fdt_blob;
+	struct regmap_range *range;
+	const fdt32_t *cell;
+	struct regmap *map;
+	int count;
+	int addr_len, size_len, both_len;
+	int parent;
+	int len;
+
+	parent = dev->parent->of_offset;
+	addr_len = fdt_address_cells(blob, parent);
+	size_len = fdt_size_cells(blob, parent);
+	both_len = addr_len + size_len;
+
+	cell = fdt_getprop(blob, dev->of_offset, "reg", &len);
+	len /= sizeof(*cell);
+	count = len / both_len;
+	if (!cell || !count)
+		return -EINVAL;
+
+	map = malloc(sizeof(struct regmap));
+	if (!map)
+		return -ENOMEM;
+
+	if (count <= 1) {
+		map->range = &map->base_range;
+	} else {
+		map->range = malloc(count * sizeof(struct regmap_range));
+		if (!map->range) {
+			free(map);
+			return -ENOMEM;
+		}
+	}
+
+	map->base = fdtdec_get_number(cell, addr_len);
+	map->range_count = count;
+
+	for (range = map->range; count > 0;
+	     count--, cell += both_len, range++) {
+		range->start = fdtdec_get_number(cell, addr_len);
+		range->size = fdtdec_get_number(cell + addr_len, size_len);
+	}
+
+	*mapp = map;
+
+	return 0;
+}
+
+void *regmap_get_range(struct regmap *map, unsigned int range_num)
+{
+	struct regmap_range *range;
+
+	if (range_num >= map->range_count)
+		return NULL;
+	range = &map->range[range_num];
+
+	return map_sysmem(range->start, range->size);
+}
+
+int regmap_uninit(struct regmap *map)
+{
+	if (map->range_count > 1)
+		free(map->range);
+	free(map);
+
+	return 0;
+}
diff --git a/include/regmap.h b/include/regmap.h
new file mode 100644
index 0000000..eccf770
--- /dev/null
+++ b/include/regmap.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __REGMAP_H
+#define __REGMAP_H
+
+/**
+ * struct regmap_range - a register map range
+ *
+ * @start:	Start address
+ * @size:	Size in bytes
+ */
+struct regmap_range {
+	ulong start;
+	ulong size;
+};
+
+/**
+ * struct regmap - a way of accessing hardware/bus registers
+ *
+ * @base:	Base address of register map
+ * @range_count: Number of ranges available within the map
+ * @range:	Pointer to the list of ranges, allocated if @range_count > 1
+ * @base_range:	If @range_count is <= 1, @range points here
+ */
+struct regmap {
+	phys_addr_t base;
+	int range_count;
+	struct regmap_range *range, base_range;
+};
+
+/*
+ * Interface to provide access to registers either through a direct memory
+ * bus or through a peripheral bus like I2C, SPI.
+ */
+int regmap_write(struct regmap *map, uint offset, uint val);
+int regmap_read(struct regmap *map, uint offset, uint *valp);
+
+#define regmap_write32(map, ptr, member, val) \
+	regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
+
+#define regmap_read32(map, ptr, member, valp) \
+	regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
+
+/**
+ * regmap_init_mem() - Set up a new register map that uses memory access
+ *
+ * Use regmap_uninit() to free it.
+ *
+ * @dev:	Device that uses this map
+ * @mapp:	Returns allocated map
+ */
+int regmap_init_mem(struct udevice *dev, struct regmap **mapp);
+
+/**
+ * regmap_get_range() - Obtain the base memory address of a regmap range
+ *
+ * @map:	Regmap to query
+ * @range_num:	Range to look up
+ */
+void *regmap_get_range(struct regmap *map, unsigned int range_num);
+
+/**
+ * regmap_uninit() - free a previously inited regmap
+ */
+int regmap_uninit(struct regmap *map);
+
+#endif
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon)
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (19 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap) Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info() Simon Glass
                   ` (34 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Many SoCs have a number of system controllers which are dealt with as a
group by a single driver. It is a pain to have to add lots of compatible
strings and/or separate drivers for each. Instead we can identify the
controllers by a number and request the address of the one we want.

Add a simple implementation of this which can be used by SoC driver code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/core/Makefile        |  1 +
 drivers/core/syscon-uclass.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h       |  1 +
 include/syscon.h             | 56 +++++++++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 drivers/core/syscon-uclass.c
 create mode 100644 include/syscon.h

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 7851824..54d57e5 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -11,3 +11,4 @@ endif
 obj-$(CONFIG_DM_DEVICE_REMOVE)	+= device-remove.o
 obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_OF_CONTROL)	+= regmap.o
+obj-$(CONFIG_OF_CONTROL)	+= syscon-uclass.o
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c
new file mode 100644
index 0000000..4d66bb5
--- /dev/null
+++ b/drivers/core/syscon-uclass.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <syscon.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <linux/err.h>
+
+struct regmap *syscon_get_regmap(struct udevice *dev)
+{
+	struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+
+	return priv->regmap;
+}
+
+static int syscon_pre_probe(struct udevice *dev)
+{
+	struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+
+	return regmap_init_mem(dev, &priv->regmap);
+}
+
+struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_SYSCON, &uc);
+	if (ret)
+		return ERR_PTR(ret);
+	uclass_foreach_dev(dev, uc) {
+		if (dev->driver_data == driver_data) {
+			struct syscon_uc_info *priv;
+			int ret;
+
+			ret = device_probe(dev);
+			if (ret)
+				return ERR_PTR(ret);
+			priv = dev_get_uclass_priv(dev);
+
+			return priv->regmap;
+		}
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+void *syscon_get_first_range(ulong driver_data)
+{
+	struct regmap *map;
+
+	map = syscon_get_regmap_by_driver_data(driver_data);
+	if (IS_ERR(map))
+		return map;
+	return regmap_get_range(map, 0);
+}
+
+UCLASS_DRIVER(syscon) = {
+	.id		= UCLASS_SYSCON,
+	.name		= "syscon",
+	.per_device_auto_alloc_size = sizeof(struct syscon_uc_info),
+	.pre_probe = syscon_pre_probe,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index c7310d7..24baa5c 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -46,6 +46,7 @@ enum uclass_id {
 	UCLASS_SPI,		/* SPI bus */
 	UCLASS_SPI_FLASH,	/* SPI flash */
 	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
+	UCLASS_SYSCON,		/* System configuration device */
 	UCLASS_THERMAL,		/* Thermal sensor */
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
diff --git a/include/syscon.h b/include/syscon.h
new file mode 100644
index 0000000..c62ccd6
--- /dev/null
+++ b/include/syscon.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __SYSCON_H
+#define __SYSCON_H
+
+/**
+ * struct syscon_uc_info - Information stored by the syscon UCLASS_UCLASS
+ *
+ * @regmap:	Register map for this controller
+ */
+struct syscon_uc_info {
+	struct regmap *regmap;
+};
+
+/* So far there are no ops so this is a placeholder */
+struct syscon_ops {
+};
+
+#define syscon_get_ops(dev)        ((struct syscon_ops *)(dev)->driver->ops)
+
+/**
+ * syscon_get_regmap() - Get access to a register map
+ *
+ * @dev:	Device to check (UCLASS_SCON)
+ * @info:	Returns regmap for the device
+ * @return 0 if OK, -ve on error
+ */
+struct regmap *syscon_get_regmap(struct udevice *dev);
+
+/**
+ * syscon_get_regmap_by_driver_data() - Look up a controller by its ID
+ *
+ * Each system controller can be accessed by its driver data, which is
+ * assumed to be unique through the scope of all system controllers that
+ * are in use. This function looks up the regmap given this driver data.
+ *
+ * @driver_data:	Driver data value to look up
+ * @return register map correponding to @driver_data, or -ve error code
+ */
+struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data);
+
+/**
+ * syscon_get_first_range() - get the first memory range from a syscon regmap
+ *
+ * @driver_data:	Driver data value to look up
+ * @return first region of register map correponding to @driver_data, or
+ *			-ve error code
+ */
+void *syscon_get_first_range(ulong driver_data);
+
+#endif
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info()
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (20 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon) Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-08 14:10   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs Simon Glass
                   ` (33 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This is checking the wrong method. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/cpu/cpu-uclass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index ab18ee2..ffe250d 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -25,7 +25,7 @@ int cpu_get_info(struct udevice *dev, struct cpu_info *info)
 {
 	struct cpu_ops *ops = cpu_get_ops(dev);
 
-	if (!ops->get_desc)
+	if (!ops->get_info)
 		return -ENOSYS;
 
 	return ops->get_info(dev, info);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (21 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info() Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:56   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs Simon Glass
                   ` (32 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add a simple uclass for LEDs, so that these can be controlled by the device
tree and activated when needed. LEDs are referred to by their label.

This implementation requires a driver for each type of LED (e.g GPIO, I2C).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 doc/device-tree-bindings/leds/common.txt | 23 ++++++++++++++
 drivers/Kconfig                          |  2 ++
 drivers/Makefile                         |  1 +
 drivers/led/Kconfig                      | 17 +++++++++++
 drivers/led/Makefile                     |  8 +++++
 drivers/led/led-uclass.c                 | 48 ++++++++++++++++++++++++++++++
 include/dm/uclass-id.h                   |  1 +
 include/led.h                            | 51 ++++++++++++++++++++++++++++++++
 scripts/Makefile.spl                     |  1 +
 9 files changed, 152 insertions(+)
 create mode 100644 doc/device-tree-bindings/leds/common.txt
 create mode 100644 drivers/led/Kconfig
 create mode 100644 drivers/led/Makefile
 create mode 100644 drivers/led/led-uclass.c
 create mode 100644 include/led.h

diff --git a/doc/device-tree-bindings/leds/common.txt b/doc/device-tree-bindings/leds/common.txt
new file mode 100644
index 0000000..2d88816
--- /dev/null
+++ b/doc/device-tree-bindings/leds/common.txt
@@ -0,0 +1,23 @@
+Common leds properties.
+
+Optional properties for child nodes:
+- label : The label for this LED.  If omitted, the label is
+  taken from the node name (excluding the unit address).
+
+- linux,default-trigger :  This parameter, if present, is a
+    string defining the trigger assigned to the LED.  Current triggers are:
+     "backlight" - LED will act as a back-light, controlled by the framebuffer
+		   system
+     "default-on" - LED will turn on (but for leds-gpio see "default-state"
+		    property in Documentation/devicetree/bindings/gpio/led.txt)
+     "heartbeat" - LED "double" flashes at a load average based rate
+     "ide-disk" - LED indicates disk activity
+     "timer" - LED flashes at a fixed, configurable rate
+
+Examples:
+
+system-status {
+	label = "Status";
+	linux,default-trigger = "heartbeat";
+	...
+};
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 1f40887..ee942e2 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -20,6 +20,8 @@ source "drivers/net/Kconfig"
 
 source "drivers/input/Kconfig"
 
+source "drivers/led/Kconfig"
+
 source "drivers/serial/Kconfig"
 
 source "drivers/tpm/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 405b64b..c090aba 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
+obj-$(CONFIG_LED) += led/
 obj-y += misc/
 obj-y += pcmcia/
 obj-y += dfu/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644
index 0000000..e4d9a84
--- /dev/null
+++ b/drivers/led/Kconfig
@@ -0,0 +1,17 @@
+config LED
+	bool "Enable LED support"
+	depends on DM
+	help
+	  Many boards have LEDs which can be used to signal status or alerts.
+	  U-Boot provides a uclass API to implement this feature. LED drivers
+	  can provide access to board-specific LEDs. Use of the device tree
+	  for configuration is encouraged.
+
+config SPL_LED_SUPPORT
+	bool "Enable LED support in SPL"
+	depends on LED
+	help
+	  The LED subsystem adds a small amount of overhead to the image.
+	  If this is acceptable and you have a need to use LEDs in SPL,
+	  enable this option. You will need to enable device tree in SPL
+	  for this to work.
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644
index 0000000..b39b205
--- /dev/null
+++ b/drivers/led/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_LED) += led-uclass.o
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
new file mode 100644
index 0000000..a80ae93
--- /dev/null
+++ b/drivers/led/led-uclass.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+int led_get_by_label(const char *label, struct udevice **devp)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_LED, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(dev, uc) {
+		struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+		if (!strcmp(label, uc_plat->label))
+			return uclass_get_device_tail(dev, 0, devp);
+	}
+
+	return -ENOENT;
+}
+
+int led_set_on(struct udevice *dev, int on)
+{
+	struct led_ops *ops = led_get_ops(dev);
+
+	if (!ops->set_on)
+		return -ENOSYS;
+
+	return ops->set_on(dev, on);
+}
+
+UCLASS_DRIVER(led) = {
+	.id		= UCLASS_LED,
+	.name		= "led",
+	.per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 24baa5c..a961648 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -33,6 +33,7 @@ enum uclass_id {
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
+	UCLASS_LED,		/* Light-emitting diode (LED) */
 	UCLASS_LPC,		/* x86 'low pin count' interface */
 	UCLASS_MASS_STORAGE,	/* Mass storage device */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
diff --git a/include/led.h b/include/led.h
new file mode 100644
index 0000000..8925d75
--- /dev/null
+++ b/include/led.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __LED_H
+#define __LED_H
+
+/**
+ * struct led_uclass_plat - Platform data the uclass stores about each device
+ *
+ * @label:	LED label
+ */
+struct led_uclass_plat {
+	const char *label;
+};
+
+struct led_ops {
+	/**
+	 * set_on() - set the state of an LED
+	 *
+	 * @dev:	LED device to change
+	 * @on:		1 to turn the LED on, 0 to turn it off
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*set_on)(struct udevice *dev, int on);
+};
+
+#define led_get_ops(dev)	((struct led_ops *)(dev)->driver->ops)
+
+/**
+ * led_get_by_label() - Find an LED device by label
+ *
+ * @label:	LED label to look up
+ * @devp:	Returns the associated device, if found
+ * @return 0 if found, -ve on error
+ */
+int led_get_by_label(const char *label, struct udevice **devp);
+
+/**
+ * led_set_on() - set the state of an LED
+ *
+ * @dev:	LED device to change
+ * @on:		1 to turn the LED on, 0 to turn it off
+ * @return 0 if OK, -ve on error
+ */
+int led_set_on(struct udevice *dev, int on);
+
+#endif
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index bcc7ca2..6b32618 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -64,6 +64,7 @@ libs-$(CONFIG_SPL_SERIAL_SUPPORT) += drivers/serial/
 libs-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/
 libs-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/
 libs-y += fs/
+libs-$(CONFIG_SPL_LED_SUPPORT) += drivers/led/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/
 libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (22 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot Simon Glass
                   ` (31 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add a simple driver which allows use of LEDs attached to GPIOs. The linux
device tree binding is used.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 doc/device-tree-bindings/leds/leds-gpio.txt |  52 ++++++++++++++
 drivers/led/Kconfig                         |   9 +++
 drivers/led/Makefile                        |   1 +
 drivers/led/led_gpio.c                      | 101 ++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+)
 create mode 100644 doc/device-tree-bindings/leds/leds-gpio.txt
 create mode 100644 drivers/led/led_gpio.c

diff --git a/doc/device-tree-bindings/leds/leds-gpio.txt b/doc/device-tree-bindings/leds/leds-gpio.txt
new file mode 100644
index 0000000..df1b308
--- /dev/null
+++ b/doc/device-tree-bindings/leds/leds-gpio.txt
@@ -0,0 +1,52 @@
+LEDs connected to GPIO lines
+
+Required properties:
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device.  Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios :  Should specify the LED's GPIO, see "gpios property" in
+  Documentation/devicetree/bindings/gpio/gpio.txt.  Active low LEDs should be
+  indicated using flags in the GPIO specifier.
+- label :  (optional)
+  see Documentation/devicetree/bindings/leds/common.txt
+- linux,default-trigger :  (optional)
+  see Documentation/devicetree/bindings/leds/common.txt
+- default-state:  (optional) The initial state of the LED.  Valid
+  values are "on", "off", and "keep".  If the LED is already on or off
+  and the default-state property is set the to same value, then no
+  glitch should be produced where the LED momentarily turns off (or
+  on).  The "keep" setting will keep the LED at whatever its current
+  state is, without producing a glitch.  The default is off if this
+  property is not present.
+
+Examples:
+
+leds {
+	compatible = "gpio-leds";
+	hdd {
+		label = "IDE Activity";
+		gpios = <&mcu_pio 0 1>; /* Active low */
+		linux,default-trigger = "ide-disk";
+	};
+
+	fault {
+		gpios = <&mcu_pio 1 0>;
+		/* Keep LED on if BIOS detected hardware fault */
+		default-state = "keep";
+	};
+};
+
+run-control {
+	compatible = "gpio-leds";
+	red {
+		gpios = <&mpc8572 6 0>;
+		default-state = "off";
+	};
+	green {
+		gpios = <&mpc8572 7 0>;
+		default-state = "on";
+	};
+};
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index e4d9a84..de5feea 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -15,3 +15,12 @@ config SPL_LED_SUPPORT
 	  If this is acceptable and you have a need to use LEDs in SPL,
 	  enable this option. You will need to enable device tree in SPL
 	  for this to work.
+
+config LED_GPIO
+	bool "LED support for GPIO-connected LEDs"
+	depends on LED && DM_GPIO
+	help
+	  Enable support for LEDs which are connected to GPIO lines. These
+	  GPIOs may be on the SoC or some other device which provides GPIOs.
+	  The GPIO driver must used driver model. LEDs are configured using
+	  the device tree.
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index b39b205..990129e 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_LED) += led-uclass.o
+obj-$(CONFIG_LED_GPIO) += led_gpio.o
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
new file mode 100644
index 0000000..a4cd618
--- /dev/null
+++ b/drivers/led/led_gpio.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <asm/gpio.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct led_gpio_priv {
+	struct gpio_desc gpio;
+};
+
+static int gpio_led_set_on(struct udevice *dev, int on)
+{
+	struct led_gpio_priv *priv = dev_get_priv(dev);
+
+	if (!dm_gpio_is_valid(&priv->gpio))
+		return -EREMOTEIO;
+
+	return dm_gpio_set_value(&priv->gpio, on);
+}
+
+static int led_gpio_probe(struct udevice *dev)
+{
+	struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+	struct led_gpio_priv *priv = dev_get_priv(dev);
+
+	/* Ignore the top-level LED node */
+	if (!uc_plat->label)
+		return 0;
+	return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
+}
+
+static int led_gpio_remove(struct udevice *dev)
+{
+	struct led_gpio_priv *priv = dev_get_priv(dev);
+
+	if (dm_gpio_is_valid(&priv->gpio))
+		dm_gpio_free(dev, &priv->gpio);
+
+	return 0;
+}
+
+static int led_gpio_bind(struct udevice *parent)
+{
+	const void *blob = gd->fdt_blob;
+	struct udevice *dev;
+	int node;
+	int ret;
+
+	for (node = fdt_first_subnode(blob, parent->of_offset);
+	     node > 0;
+	     node = fdt_next_subnode(blob, node)) {
+		struct led_uclass_plat *uc_plat;
+		const char *label;
+
+		label = fdt_getprop(blob, node, "label", NULL);
+		if (!label) {
+			debug("%s: node %s has no label\n", __func__,
+			      fdt_get_name(blob, node, NULL));
+			return -EINVAL;
+		}
+		ret = device_bind_driver_to_node(parent, "gpio_led",
+						 fdt_get_name(blob, node, NULL),
+						 node, &dev);
+		if (ret)
+			return ret;
+		uc_plat = dev_get_uclass_platdata(dev);
+		uc_plat->label = label;
+	}
+
+	return 0;
+}
+
+static const struct led_ops gpio_led_ops = {
+	.set_on		= gpio_led_set_on,
+};
+
+static const struct udevice_id led_gpio_ids[] = {
+	{ .compatible = "gpio-leds" },
+	{ }
+};
+
+U_BOOT_DRIVER(led_gpio) = {
+	.name	= "gpio_led",
+	.id	= UCLASS_LED,
+	.of_match = led_gpio_ids,
+	.ops	= &gpio_led_ops,
+	.priv_auto_alloc_size = sizeof(struct led_gpio_priv),
+	.bind	= led_gpio_bind,
+	.probe	= led_gpio_probe,
+	.remove	= led_gpio_remove,
+};
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (23 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass Simon Glass
                   ` (30 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add a few messages to indicate progress and failure.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/spl/spl_mmc.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 552f80d..51add39 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -26,11 +26,14 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
 
 	/* read image header to find the image size & load address */
 	count = mmc->block_dev.block_read(0, sector, 1, header);
+	debug("read sector %lx, count=%lu\n", sector, count);
 	if (count == 0)
 		goto end;
 
-	if (image_get_magic(header) != IH_MAGIC)
+	if (image_get_magic(header) != IH_MAGIC) {
+		puts("bad magic\n");
 		return -1;
+	}
 
 	spl_parse_image_header(header);
 
@@ -40,7 +43,9 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
 
 	/* Read the header too to avoid extra memcpy */
 	count = mmc->block_dev.block_read(0, sector, image_size_sectors,
-					  (void *) spl_image.load_addr);
+					  (void *)spl_image.load_addr);
+	debug("read %x sectors to %x\n", image_size_sectors,
+	      spl_image.load_addr);
 
 end:
 	if (count == 0) {
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (24 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors Simon Glass
                   ` (29 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add basic support for MMC, providing a uclass which can set up an MMC
device. This allows MMC drivers to move to using driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/Kconfig      | 10 ++++++++++
 drivers/mmc/Makefile     |  2 ++
 drivers/mmc/mmc-uclass.c | 34 ++++++++++++++++++++++++++++++++++
 drivers/mmc/mmc.c        |  2 ++
 include/dm/uclass-id.h   |  1 +
 include/mmc.h            | 22 ++++++++++++++++++++++
 6 files changed, 71 insertions(+)
 create mode 100644 drivers/mmc/mmc-uclass.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 7ba85a2..3e835f7 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -1,5 +1,15 @@
 menu "MMC Host controller Support"
 
+config DM_MMC
+	bool "Enable MMC controllers using Driver Model"
+	depends on DM
+	help
+	  This enables the MultiMediaCard (MMC) uclass which suports MMC and
+	  Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
+	  and non-removable (e.g. eMMC chip) devices are supported. These
+	  appear as block devices in U-Boot and can support filesystems such
+	  as EXT4 and FAT.
+
 config SH_SDHI
 	bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
 	depends on RMOBILE
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index ed73687..2680c63 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -5,6 +5,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-$(CONFIG_DM_MMC) += mmc-uclass.o
+
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
 obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
new file mode 100644
index 0000000..777489f
--- /dev/null
+++ b/drivers/mmc/mmc-uclass.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+struct mmc *mmc_get_mmc_dev(struct udevice *dev)
+{
+	struct mmc_uclass_priv *upriv;
+
+	if (!device_active(dev))
+		return NULL;
+	upriv = dev_get_uclass_priv(dev);
+	return upriv->mmc;
+}
+
+U_BOOT_DRIVER(mmc) = {
+	.name	= "mmc",
+	.id	= UCLASS_MMC,
+};
+
+UCLASS_DRIVER(mmc) = {
+	.id		= UCLASS_MMC,
+	.name		= "mmc",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+	.per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv),
+};
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 79e6fee..4eab274 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1761,8 +1761,10 @@ int mmc_initialize(bd_t *bis)
 	INIT_LIST_HEAD (&mmc_devices);
 	cur_dev_num = 0;
 
+#ifndef CONFIG_DM_MMC
 	if (board_mmc_init(bis) < 0)
 		cpu_mmc_init(bis);
+#endif
 
 #ifndef CONFIG_SPL_BUILD
 	print_mmc_devices(',');
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index a961648..cba7c0a 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -36,6 +36,7 @@ enum uclass_id {
 	UCLASS_LED,		/* Light-emitting diode (LED) */
 	UCLASS_LPC,		/* x86 'low pin count' interface */
 	UCLASS_MASS_STORAGE,	/* Mass storage device */
+	UCLASS_MMC,		/* SD / MMC card or chip */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
 	UCLASS_PCH,		/* x86 platform controller hub */
 	UCLASS_PCI,		/* PCI bus */
diff --git a/include/mmc.h b/include/mmc.h
index dd98b3b..cda9a19 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -266,6 +266,28 @@
 #define MMC_NUM_BOOT_PARTITION	2
 #define MMC_PART_RPMB           3       /* RPMB partition number */
 
+/* Driver model support */
+
+/**
+ * struct mmc_uclass_priv - Holds information about a device used by the uclass
+ */
+struct mmc_uclass_priv {
+	struct mmc *mmc;
+};
+
+/**
+ * mmc_get_mmc_dev() - get the MMC struct pointer for a device
+ *
+ * Provided that the device is already probed and ready for use, this value
+ * will be available.
+ *
+ * @dev:	Device
+ * @return associated mmc struct pointer if available, else NULL
+ */
+struct mmc *mmc_get_mmc_dev(struct udevice *dev);
+
+/* End of driver model support */
+
 struct mmc_cid {
 	unsigned long psn;
 	unsigned short oid;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (25 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-06-24  1:56   ` Chen-Yu Tsai
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors Simon Glass
                   ` (28 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

These bloat the code and cause problems for SPL. Use debug() where possible
and try to return a useful error code instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/dw_mmc.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 53a8aca..8f28d7e 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -8,6 +8,7 @@
 
 #include <bouncebuf.h>
 #include <common.h>
+#include <errno.h>
 #include <malloc.h>
 #include <mmc.h>
 #include <dwmmc.h>
@@ -119,7 +120,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
 		if (get_timer(start) > timeout) {
-			printf("%s: Timeout on data busy\n", __func__);
+			debug("%s: Timeout on data busy\n", __func__);
 			return TIMEOUT;
 		}
 	}
@@ -178,7 +179,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	}
 
 	if (i == retry) {
-		printf("%s: Timeout.\n", __func__);
+		debug("%s: Timeout.\n", __func__);
 		return TIMEOUT;
 	}
 
@@ -194,8 +195,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		debug("%s: Response Timeout.\n", __func__);
 		return TIMEOUT;
 	} else if (mask & DWMCI_INTMSK_RE) {
-		printf("%s: Response Error.\n", __func__);
-		return -1;
+		debug("%s: Response Error.\n", __func__);
+		return -EIO;
 	}
 
 
@@ -214,7 +215,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		do {
 			mask = dwmci_readl(host, DWMCI_RINTSTS);
 			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
-				printf("%s: DATA ERROR!\n", __func__);
+				debug("%s: DATA ERROR!\n", __func__);
 				return -1;
 			}
 		} while (!(mask & DWMCI_INTMSK_DTO));
@@ -251,7 +252,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	else if (host->bus_hz)
 		sclk = host->bus_hz;
 	else {
-		printf("%s: Didn't get source clock value.\n", __func__);
+		debug("%s: Didn't get source clock value.\n", __func__);
 		return -EINVAL;
 	}
 
@@ -270,7 +271,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("%s: Timeout!\n", __func__);
+			debug("%s: Timeout!\n", __func__);
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -285,7 +286,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("%s: Timeout!\n", __func__);
+			debug("%s: Timeout!\n", __func__);
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -339,8 +340,8 @@ static int dwmci_init(struct mmc *mmc)
 	dwmci_writel(host, DWMCI_PWREN, 1);
 
 	if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
-		printf("%s[%d] Fail-reset!!\n", __func__, __LINE__);
-		return -1;
+		debug("%s[%d] Fail-reset!!\n", __func__, __LINE__);
+		return -EIO;
 	}
 
 	/* Enumerate@400KHz */
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (26 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL Simon Glass
                   ` (27 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Allow read errors to be diagnosed more easily.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/mmc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 4eab274..da47037 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -250,14 +250,18 @@ static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
 		return 0;
 	}
 
-	if (mmc_set_blocklen(mmc, mmc->read_bl_len))
+	if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
+		debug("%s: Failed to set blocklen\n", __func__);
 		return 0;
+	}
 
 	do {
 		cur = (blocks_todo > mmc->cfg->b_max) ?
 			mmc->cfg->b_max : blocks_todo;
-		if(mmc_read_blocks(mmc, dst, start, cur) != cur)
+		if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
+			debug("%s: Failed to read blocks\n", __func__);
 			return 0;
+		}
 		blocks_todo -= cur;
 		start += cur;
 		dst += cur * mmc->read_bl_len;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (27 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc Simon Glass
                   ` (26 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Enable MMC using driver model in SPL for consistency with U-Boot proper.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/spl/spl_mmc.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 51add39..5f1cfbf 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -7,6 +7,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
 #include <spl.h>
 #include <linux/compiler.h>
 #include <asm/u-boot.h>
@@ -101,9 +102,18 @@ void spl_mmc_load_image(void)
 {
 	struct mmc *mmc;
 	u32 boot_mode;
-	int err;
+	int err = 0;
 	__maybe_unused int part;
 
+#ifdef CONFIG_DM_MMC
+	struct udevice *dev;
+
+	mmc_initialize(NULL);
+	err = uclass_get_device(UCLASS_MMC, 0, &dev);
+	mmc = NULL;
+	if (!err)
+		mmc = mmc_get_mmc_dev(dev);
+#else
 	mmc_initialize(gd->bd);
 
 	/* We register only one device. So, the dev id is always 0 */
@@ -114,8 +124,11 @@ void spl_mmc_load_image(void)
 #endif
 		hang();
 	}
+#endif
+
+	if (!err)
+		err = mmc_init(mmc);
 
-	err = mmc_init(mmc);
 	if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		printf("spl: mmc init failed with error: %d\n", err);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (28 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
                   ` (25 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

It took a little while to figure this out, so this patch adds documentation
to help the next person who needs to do this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 include/dwmmc.h | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/dwmmc.h b/include/dwmmc.h
index 86a5491..7a7555a 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -129,8 +129,24 @@
 /* quirks */
 #define DWMCI_QUIRK_DISABLE_SMU		(1 << 0)
 
+/**
+ * struct dwmci_host - Information about a designware MMC host
+ *
+ * @name:	Device name
+ * @ioaddr:	Base I/O address of controller
+ * @quirks:	Quick flags - see DWMCI_QUIRK_...
+ * @caps:	Capabilities - see MMC_MODE_...
+ * @bus_hz:	Bus speed in Hz, if @get_mmc_clk() is NULL
+ * @div:	Arbitrary clock divider value for use by controller
+ * @dev_index:	Arbitrary device index for use by controller
+ * @dev_id:	Arbitrary device ID for use by controller
+ * @buswidth:	Bus width in bits (8 or 4)
+ * @fifoth_val:	Value for FIFOTH register (or 0 to leave unset)
+ * @mmc:	Pointer to generic MMC structure for this device
+ * @priv:	Private pointer for use by controller
+ */
 struct dwmci_host {
-	char *name;
+	const char *name;
 	void *ioaddr;
 	unsigned int quirks;
 	unsigned int caps;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (29 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-06-24  1:50   ` Chen-Yu Tsai
  2015-06-25  1:58   ` Jaehoon Chung
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided Simon Glass
                   ` (24 subsequent siblings)
  55 siblings, 2 replies; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Some SoCs want to adjust the input clock to the DWMMC block as a way of
controlling the MMC bus clock. Update the get_mmc_clk() method to support
this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/dw_mmc.c        |  2 +-
 drivers/mmc/exynos_dw_mmc.c |  2 +-
 include/dwmmc.h             | 16 +++++++++++++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 8f28d7e..a034c3f 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -248,7 +248,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	 * host->bus_hz should be set by user.
 	 */
 	if (host->get_mmc_clk)
-		sclk = host->get_mmc_clk(host);
+		sclk = host->get_mmc_clk(host, freq);
 	else if (host->bus_hz)
 		sclk = host->bus_hz;
 	else {
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index e083745..3f702ba 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -39,7 +39,7 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
 	dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
 }
 
-unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
+unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
 {
 	unsigned long sclk;
 	int8_t clk_div;
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 7a7555a..25cf42c 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -163,7 +163,21 @@ struct dwmci_host {
 
 	void (*clksel)(struct dwmci_host *host);
 	void (*board_init)(struct dwmci_host *host);
-	unsigned int (*get_mmc_clk)(struct dwmci_host *host);
+
+	/**
+	 * Get / set a particular MMC clock frequency
+	 *
+	 * This is used to request the current clock frequency of the clock
+	 * that drives the DWMMC peripheral. The caller will then use this
+	 * information to work out the divider it needs to achieve the
+	 * required MMC bus clock frequency. If you want to handle the
+	 * clock external to DWMMC, use @freq to select the frequency and
+	 * return that value too. Then DWMMC will put itself in bypass mode.
+	 *
+	 * @host:	DWMMC host
+	 * @freq:	Frequency the host is trying to achieve
+	 */
+	unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
 
 	struct mmc_config cfg;
 };
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (30 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-06-25  1:58   ` Jaehoon Chung
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 33/54] dm: Add basic support for pin multiplexing (pinctrl) Simon Glass
                   ` (23 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

We can calculate this. Add code to do this if it is not provided.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/dw_mmc.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a034c3f..cce2a5d 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -355,9 +355,15 @@ static int dwmci_init(struct mmc *mmc)
 	dwmci_writel(host, DWMCI_IDINTEN, 0);
 	dwmci_writel(host, DWMCI_BMOD, 1);
 
-	if (host->fifoth_val) {
-		dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
+	if (!host->fifoth_val) {
+		uint32_t fifo_size;
+
+		fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
+		fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
+		host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
+				TX_WMARK(fifo_size / 2);
 	}
+	dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
 
 	dwmci_writel(host, DWMCI_CLKENA, 0);
 	dwmci_writel(host, DWMCI_CLKSRC, 0);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 33/54] dm: Add basic support for pin multiplexing (pinctrl)
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (31 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names Simon Glass
                   ` (22 subsequent siblings)
  55 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Add a uclass which permits pin multiplexing to be configured for a
particular function. It uses the concept of a peripheral ID to specify
the peripheral to adjust. Typically peripheral IDs are SPI0, SPI1,
MMC0, etc.

The uclass provides two methods:

- get_periph_id() - returns the peripheral ID for a particular driver model
device. This can be used to look up (say) an I2C device, and then find
its peripheral ID so that the pins for that device can be requested.

- request() - allows a particular function to be requested. This change
may impact multiple pins on the chip. For example, an I2C bus requires
two pins (clock and data) and the request() method will set up both pins.

This also allows GPIO drivers which sit under the 'pinctrl' device tree
node to be detected and used.

At some point this could be expanded to support a full interface with
support for the full device tree bindings. In that case the concept of
peripheral ID might not be needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/Kconfig                  |  2 ++
 drivers/Makefile                 |  1 +
 drivers/pinctrl/Kconfig          | 19 +++++++++++
 drivers/pinctrl/Makefile         |  8 +++++
 drivers/pinctrl/pinctrl-uclass.c | 51 +++++++++++++++++++++++++++
 include/dm/uclass-id.h           |  1 +
 include/pinctrl.h                | 74 ++++++++++++++++++++++++++++++++++++++++
 scripts/Makefile.spl             |  1 +
 8 files changed, 157 insertions(+)
 create mode 100644 drivers/pinctrl/Kconfig
 create mode 100644 drivers/pinctrl/Makefile
 create mode 100644 drivers/pinctrl/pinctrl-uclass.c
 create mode 100644 include/pinctrl.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index ee942e2..17a61e4 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -32,6 +32,8 @@ source "drivers/spi/Kconfig"
 
 source "drivers/gpio/Kconfig"
 
+source "drivers/pinctrl/Kconfig"
+
 source "drivers/power/Kconfig"
 
 source "drivers/hwmon/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index c090aba..b68c4ee 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LED) += led/
 obj-y += misc/
 obj-y += pcmcia/
 obj-y += dfu/
+obj-$(CONFIG_PINCTRL) += pinctrl/
 obj-y += rtc/
 obj-y += sound/
 obj-y += tpm/
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
new file mode 100644
index 0000000..e667361
--- /dev/null
+++ b/drivers/pinctrl/Kconfig
@@ -0,0 +1,19 @@
+config PINCTRL
+	bool "Pin multiplexing driver support"
+	help
+	  Support pin multiplexing control in U-Boot. Most SoCs have their own
+	  own multiplexing arrangement where a single pin can be used for
+	  several functions. An SoC pinctrl driver allows the required
+	  function to be selected for each pin. The driver is typically
+	  controlled by the device tree.
+
+config SPL_PINCTRL_SUPPORT
+	bool "Enable pin multiplexing (pinctrl) support in SPL"
+	depends on PINCTRL
+	help
+	  The pinctrl subsystem can add a substantial overhead to the SPL
+	  image since it typically requires quite a few tables either in the
+	  driver or in the device tree. If this is acceptable and you need
+	  to adjust pin multiplexing in SPL in order to boot into U-Boot,
+	  enable this option. You will need to enable device tree in SPL
+	  for this to work.
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
new file mode 100644
index 0000000..6e63ee7
--- /dev/null
+++ b/drivers/pinctrl/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_PINCTRL) += pinctrl-uclass.o
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
new file mode 100644
index 0000000..82bd980
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <pinctrl.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int pinctrl_request(struct udevice *dev, int func, int flags)
+{
+	struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+	if (!ops->request)
+		return -ENOSYS;
+
+	return ops->request(dev, func, flags);
+}
+
+int pinctrl_request_noflags(struct udevice *dev, int func)
+{
+	return pinctrl_request(dev, func, 0);
+}
+
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph)
+{
+	struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+	if (!ops->get_periph_id)
+		return -ENOSYS;
+
+	return ops->get_periph_id(dev, periph);
+}
+
+static int pinctrl_post_bind(struct udevice *dev)
+{
+	/* Scan the bus for devices */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+UCLASS_DRIVER(pinctrl) = {
+	.id		= UCLASS_PINCTRL,
+	.name		= "pinctrl",
+	.post_bind	= pinctrl_post_bind,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index cba7c0a..14a1614 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -41,6 +41,7 @@ enum uclass_id {
 	UCLASS_PCH,		/* x86 platform controller hub */
 	UCLASS_PCI,		/* PCI bus */
 	UCLASS_PCI_GENERIC,	/* Generic PCI bus device */
+	UCLASS_PINCTRL,		/* Pin multiplexing control */
 	UCLASS_PMIC,		/* PMIC I/O device */
 	UCLASS_REGULATOR,	/* Regulator device */
 	UCLASS_RTC,		/* Real time clock device */
diff --git a/include/pinctrl.h b/include/pinctrl.h
new file mode 100644
index 0000000..e7aca2e
--- /dev/null
+++ b/include/pinctrl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __PINCTRL_H
+#define __PINCTRL_H
+
+struct pinctrl_ops {
+	/**
+	 * request() - Request a particular pinctrl function
+	 *
+	 * This activates the selected function.
+	 *
+	 * @dev:	Device to adjust (UCLASS_PINCTRL)
+	 * @func:	Function number (driver-specific)
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*request)(struct udevice *dev, int func, int flags);
+
+	/**
+	* get_periph_id() - get the peripheral ID for a device
+	*
+	* This generally looks at the peripheral's device tree node to work
+	* out the peripheral ID. The return value is normally interpreted as
+	* enum periph_id. so long as this is defined by the platform (which it
+	* should be).
+	*
+	* @dev:		Pinctrl device to use for decoding
+	* @periph:	Device to check
+	* @return peripheral ID of @periph, or -ENOENT on error
+	*/
+	int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
+};
+
+#define pinctrl_get_ops(dev)	((struct pinctrl_ops *)(dev)->driver->ops)
+
+/**
+ * pinctrl_request() - Request a particular pinctrl function
+ *
+ * @dev:	Device to check (UCLASS_PINCTRL)
+ * @func:	Function number (driver-specific)
+ * @flags:	Flags (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request(struct udevice *dev, int func, int flags);
+
+/**
+ * pinctrl_request_noflags() - Request a particular pinctrl function
+ *
+ * This is similar to pinctrl_request() but uses 0 for @flags.
+ *
+ * @dev:	Device to check (UCLASS_PINCTRL)
+ * @func:	Function number (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request_noflags(struct udevice *dev, int func);
+
+/**
+ * pinctrl_get_periph_id() - get the peripheral ID for a device
+ *
+ * This generally looks at the peripheral's device tree node to work out the
+ * peripheral ID. The return value is normally interpreted as enum periph_id.
+ * so long as this is defined by the platform (which it should be).
+ *
+ * @dev:	Pinctrl device to use for decoding
+ * @periph:	Device to check
+ * @return peripheral ID of @periph, or -ENOENT on error
+ */
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
+
+#endif
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 6b32618..24ca58b 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -77,6 +77,7 @@ libs-$(CONFIG_SPL_NET_SUPPORT) += net/
 libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/
 libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/
 libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/
+libs-$(CONFIG_SPL_PINCTRL_SUPPORT) += drivers/pinctrl/
 libs-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/
 libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/
 libs-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (32 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 33/54] dm: Add basic support for pin multiplexing (pinctrl) Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic Simon Glass
                   ` (21 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

This is not user input (i.e. from the command line). It should be possible
to get the case correct and avoid the case-insensitive match. This will
help avoid sloppy device tree setups.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/pmic/pmic-uclass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 812ac13..40b5135 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -55,7 +55,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 		child = NULL;
 		for (info = child_info; info->prefix && info->driver; info++) {
 			prefix_len = strlen(info->prefix);
-			if (strncasecmp(info->prefix, node_name, prefix_len))
+			if (strncmp(info->prefix, node_name, prefix_len))
 				continue;
 
 			debug("  - compatible prefix: '%s'\n", info->prefix);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (33 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function Simon Glass
                   ` (20 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

Decide when the regulator is set up whether we want to auto-set the voltage
or current. This avoids the complex logic spilling into the processing code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 12 ++++++++++++
 include/power/regulator.h                  |  8 ++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 31ffd44..0f1ca77 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -319,6 +319,18 @@ static int regulator_pre_probe(struct udevice *dev)
 	uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
 					    "regulator-boot-on");
 
+	/* Those values are optional (-ENODATA if unset) */
+	if ((uc_pdata->min_uV != -ENODATA) &&
+	    (uc_pdata->max_uV != -ENODATA) &&
+	    (uc_pdata->min_uV == uc_pdata->max_uV))
+		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
+
+	/* Those values are optional (-ENODATA if unset) */
+	if ((uc_pdata->min_uA != -ENODATA) &&
+	    (uc_pdata->max_uA != -ENODATA) &&
+	    (uc_pdata->min_uA == uc_pdata->max_uA))
+		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
+
 	return 0;
 }
 
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 03a2cef..79ce0a4 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -128,6 +128,11 @@ struct dm_regulator_mode {
 	const char *name;
 };
 
+enum regulator_flag {
+	REGULATOR_FLAG_AUTOSET_UV	= 1 << 0,
+	REGULATOR_FLAG_AUTOSET_UA	= 1 << 1,
+};
+
 /**
  * struct dm_regulator_uclass_platdata - pointed by dev->uclass_platdata, and
  * allocated on each regulator bind. This structure holds an information
@@ -143,6 +148,8 @@ struct dm_regulator_mode {
  * @max_uA*    - maximum amperage (micro Amps)
  * @always_on* - bool type, true or false
  * @boot_on*   - bool type, true or false
+ * TODO(sjg at chromium.org): Consider putting the above two into @flags
+ * @flags:     - flags value (see REGULATOR_FLAG_...)
  * @name**     - fdt regulator name - should be taken from the device tree
  *
  * Note:
@@ -162,6 +169,7 @@ struct dm_regulator_uclass_platdata {
 	bool always_on;
 	bool boot_on;
 	const char *name;
+	int flags;
 };
 
 /* Regulator device operations */
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (34 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators Simon Glass
                   ` (19 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

The regulator_autoset() function mixes printf() output and PMIC adjustment
code. It provides a boolean to control the output. It is better to avoid
missing logic and output, and this permits a smaller SPL code size. So
split the output into a separate function.

Also rename the function to have a by_name() suffix, since we would like
to be able to pass a device when we know it, and thus avoid the name
search.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 98 +++++++++++-------------------
 include/power/regulator.h                  | 34 ++++++++---
 include/power/sandbox_pmic.h               |  4 +-
 test/dm/regulator.c                        |  2 +-
 4 files changed, 63 insertions(+), 75 deletions(-)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 0f1ca77..687d3b1 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -138,87 +138,57 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp)
 	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
 }
 
-static int failed(int ret, bool verbose, const char *fmt, ...)
+int regulator_autoset(struct udevice *dev)
 {
-	va_list args;
-	char buf[64];
-
-	if (verbose == false)
-		return ret;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	int ret = 0;
 
-	va_start(args, fmt);
-	vscnprintf(buf, sizeof(buf), fmt, args);
-	va_end(args);
+	uc_pdata = dev_get_uclass_platdata(dev);
+	if (!uc_pdata->always_on && !uc_pdata->boot_on)
+		return -EMEDIUMTYPE;
 
-	printf(buf);
+	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+		ret = regulator_set_value(dev, uc_pdata->min_uV);
+	if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
+		ret = regulator_set_current(dev, uc_pdata->min_uA);
 
 	if (!ret)
-		return 0;
-
-	printf(" (ret: %d)", ret);
+		ret = regulator_set_enable(dev, true);
 
 	return ret;
 }
 
-int regulator_autoset(const char *platname,
-		      struct udevice **devp,
-		      bool verbose)
+static void regulator_show(struct udevice *dev, int ret)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
-	struct udevice *dev;
-	int ret;
-
-	if (devp)
-		*devp = NULL;
-
-	ret = regulator_get_by_platname(platname, &dev);
-	if (ret) {
-		error("Can get the regulator: %s!", platname);
-		return ret;
-	}
 
 	uc_pdata = dev_get_uclass_platdata(dev);
-	if (!uc_pdata) {
-		error("Can get the regulator %s uclass platdata!", platname);
-		return -ENXIO;
-	}
-
-	if (!uc_pdata->always_on && !uc_pdata->boot_on)
-		goto retdev;
 
-	if (verbose)
-		printf("%s@%s: ", dev->name, uc_pdata->name);
-
-	/* Those values are optional (-ENODATA if unset) */
-	if ((uc_pdata->min_uV != -ENODATA) &&
-	    (uc_pdata->max_uV != -ENODATA) &&
-	    (uc_pdata->min_uV == uc_pdata->max_uV)) {
-		ret = regulator_set_value(dev, uc_pdata->min_uV);
-		if (failed(ret, verbose, "set %d uV", uc_pdata->min_uV))
-			goto exit;
-	}
-
-	/* Those values are optional (-ENODATA if unset) */
-	if ((uc_pdata->min_uA != -ENODATA) &&
-	    (uc_pdata->max_uA != -ENODATA) &&
-	    (uc_pdata->min_uA == uc_pdata->max_uA)) {
-		ret = regulator_set_current(dev, uc_pdata->min_uA);
-		if (failed(ret, verbose, "; set %d uA", uc_pdata->min_uA))
-			goto exit;
-	}
+	printf("%s@%s: ", dev->name, uc_pdata->name);
+	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+		printf("set %d uV", uc_pdata->min_uV);
+	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
+		printf("; set %d uA", uc_pdata->min_uA);
+	printf("; enabling");
+	if (ret)
+		printf(" (ret: %d)\n", ret);
+	printf("\n");
+}
 
-	ret = regulator_set_enable(dev, true);
-	if (failed(ret, verbose, "; enabling", uc_pdata->min_uA))
-		goto exit;
+int regulator_autoset_by_name(const char *platname, struct udevice **devp)
+{
+	struct udevice *dev;
+	int ret;
 
-retdev:
+	ret = regulator_get_by_platname(platname, &dev);
 	if (devp)
 		*devp = dev;
-exit:
-	if (verbose)
-		printf("\n");
+	if (ret) {
+		debug("Can get the regulator: %s!", platname);
+		return ret;
+	}
 
-	return ret;
+	return regulator_autoset(dev);
 }
 
 int regulator_list_autoset(const char *list_platname[],
@@ -229,7 +199,9 @@ int regulator_list_autoset(const char *list_platname[],
 	int error = 0, i = 0, ret;
 
 	while (list_platname[i]) {
-		ret = regulator_autoset(list_platname[i], &dev, verbose);
+		ret = regulator_autoset_by_name(list_platname[i], &dev);
+		if (ret != -EMEDIUMTYPE && verbose)
+			regulator_show(dev, ret);
 		if (ret & !error)
 			error = ret;
 
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 79ce0a4..86e9c3b 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -316,9 +316,28 @@ int regulator_get_mode(struct udevice *dev);
 int regulator_set_mode(struct udevice *dev, int mode_id);
 
 /**
- * regulator_autoset: setup the regulator given by its uclass's platform data
- * name field. The setup depends on constraints found in device's uclass's
- * platform data (struct dm_regulator_uclass_platdata):
+ * regulator_autoset: setup the the voltage/current on a regulator
+ *
+ * The setup depends on constraints found in device's uclass's platform data
+ * (struct dm_regulator_uclass_platdata):
+ *
+ * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
+ *   or if both are unset, then the function returns
+ * - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
+ * - Current limit - will set - if '.min_uA' and '.max_uA' values are equal
+ *
+ * The function returns on the first-encountered error.
+ *
+ * @platname - expected string for dm_regulator_uclass_platdata .name field
+ * @devp     - returned pointer to the regulator device - if non-NULL passed
+ * @return: 0 on success or negative value of errno.
+ */
+int regulator_autoset(struct udevice *dev);
+
+/**
+ * regulator_autoset_by_name: setup the regulator given by its uclass's
+ * platform data name field. The setup depends on constraints found in device's
+ * uclass's platform data (struct dm_regulator_uclass_platdata):
  * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
  *   or if both are unset, then the function returns
  * - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
@@ -328,21 +347,18 @@ int regulator_set_mode(struct udevice *dev, int mode_id);
  *
  * @platname - expected string for dm_regulator_uclass_platdata .name field
  * @devp     - returned pointer to the regulator device - if non-NULL passed
- * @verbose  - (true/false) print regulator setup info, or be quiet
  * @return: 0 on success or negative value of errno.
  *
  * The returned 'regulator' device can be used with:
  * - regulator_get/set_*
  */
-int regulator_autoset(const char *platname,
-		      struct udevice **devp,
-		      bool verbose);
+int regulator_autoset_by_name(const char *platname, struct udevice **devp);
 
 /**
  * regulator_list_autoset: setup the regulators given by list of their uclass's
  * platform data name field. The setup depends on constraints found in device's
  * uclass's platform data. The function loops with calls to:
- * regulator_autoset() for each name from the list.
+ * regulator_autoset_by_name() for each name from the list.
  *
  * @list_platname - an array of expected strings for .name field of each
  *                  regulator's uclass platdata
@@ -383,7 +399,7 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp);
  * Search by name, found in regulator uclass platdata.
  *
  * @platname - expected string for uc_pdata->name of regulator uclass platdata
- * @devp     - returned pointer to the regulator device
+ * @devp     - returns pointer to the regulator device or NULL on error
  * @return 0 on success or negative value of errno.
  *
  * The returned 'regulator' device is probed and can be used with:
diff --git a/include/power/sandbox_pmic.h b/include/power/sandbox_pmic.h
index ae14292..8547674 100644
--- a/include/power/sandbox_pmic.h
+++ b/include/power/sandbox_pmic.h
@@ -117,11 +117,11 @@ enum {
 
 /*
  * Expected regulators setup after call of:
- * - regulator_autoset()
+ * - regulator_autoset_by_name()
  * - regulator_list_autoset()
  */
 
-/* BUCK1: for testing regulator_autoset() */
+/* BUCK1: for testing regulator_autoset_by_name() */
 #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UV	1200000
 #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UA	200000
 #define SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE	true
diff --git a/test/dm/regulator.c b/test/dm/regulator.c
index d279c04..3d0056f 100644
--- a/test/dm/regulator.c
+++ b/test/dm/regulator.c
@@ -210,7 +210,7 @@ static int dm_test_power_regulator_autoset(struct unit_test_state *uts)
 	 * Expected output state: uV=1200000; uA=200000; output enabled
 	 */
 	platname = regulator_names[BUCK1][PLATNAME];
-	ut_assertok(regulator_autoset(platname, &dev_autoset, false));
+	ut_assertok(regulator_autoset_by_name(platname, &dev_autoset));
 
 	/* Check, that the returned device is proper */
 	ut_assertok(regulator_get_by_platname(platname, &dev));
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (35 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function Simon Glass
@ 2015-06-23 21:38 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass Simon Glass
                   ` (18 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:38 UTC (permalink / raw)
  To: u-boot

The device tree provides information about which regulators should be
on at boot, or always on. Use this to set them up automatically.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 22 ++++++++++++++++++++++
 include/power/regulator.h                  | 11 +++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 687d3b1..a2d0b9f 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -306,6 +306,28 @@ static int regulator_pre_probe(struct udevice *dev)
 	return 0;
 }
 
+int regulators_enable_boot_on(bool verbose)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_REGULATOR, &uc);
+	if (ret)
+		return ret;
+	for (uclass_first_device(UCLASS_REGULATOR, &dev);
+	     dev && !ret;
+	     uclass_next_device(&dev)) {
+		ret = regulator_autoset(dev);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (verbose)
+			regulator_show(dev, ret);
+	}
+
+	return ret;
+}
+
 UCLASS_DRIVER(regulator) = {
 	.id		= UCLASS_REGULATOR,
 	.name		= "regulator",
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 86e9c3b..0bdb496 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -316,6 +316,17 @@ int regulator_get_mode(struct udevice *dev);
 int regulator_set_mode(struct udevice *dev, int mode_id);
 
 /**
+ * regulators_enable_boot_on() - enable regulators needed for boot
+ *
+ * This enables all regulators which are marked to be on at boot time. This
+ * only works for regulators which don't have a range for voltage/current,
+ * since in that case it is not possible to know which value to use.
+ *
+ * This effectively caslls regulator_autoset() for every regulator.
+ */
+int regulators_enable_boot_on(bool verbose);
+
+/**
  * regulator_autoset: setup the the voltage/current on a regulator
  *
  * The setup depends on constraints found in device's uclass's platform data
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (36 preceding siblings ...)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers Simon Glass
                   ` (17 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

To reduce unnecessary code size in an uncommon code path, use debug()
where possible(). The driver returns an error which indicates failure.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index a2d0b9f..12e141b 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -262,7 +262,7 @@ static int regulator_post_bind(struct udevice *dev)
 	if (regulator_name_is_unique(dev, uc_pdata->name))
 		return 0;
 
-	error("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
+	debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
 	      property, dev->name, uc_pdata->name);
 
 	return -EINVAL;
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (37 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL Simon Glass
                   ` (16 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

It is a common requirement to update some PMIC registers. Provide some
simple convenience functions to do this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/power/pmic/pmic-uclass.c | 32 ++++++++++++++++++++++++++++++++
 include/power/pmic.h             | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 40b5135..dbab3e3 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -139,6 +139,38 @@ int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len)
 	return ops->write(dev, reg, buffer, len);
 }
 
+int pmic_reg_read(struct udevice *dev, uint reg)
+{
+	u8 byte;
+	int ret;
+
+	ret = pmic_read(dev, reg, &byte, 1);
+	debug("%s: reg=%x, value=%x\n", __func__, reg, byte);
+
+	return ret ? ret : byte;
+}
+
+int pmic_reg_write(struct udevice *dev, uint reg, uint value)
+{
+	u8 byte = value;
+
+	debug("%s: reg=%x, value=%x\n", __func__, reg, value);
+	return pmic_read(dev, reg, &byte, 1);
+}
+
+int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
+{
+	u8 byte;
+	int ret;
+
+	ret = pmic_reg_read(dev, reg);
+	if (ret < 0)
+		return ret;
+	byte = (ret & ~clr) | set;
+
+	return pmic_reg_write(dev, reg, byte);
+}
+
 UCLASS_DRIVER(pmic) = {
 	.id		= UCLASS_PMIC,
 	.name		= "pmic",
diff --git a/include/power/pmic.h b/include/power/pmic.h
index eb152ef..6ba4b6e 100644
--- a/include/power/pmic.h
+++ b/include/power/pmic.h
@@ -264,6 +264,40 @@ int pmic_reg_count(struct udevice *dev);
  */
 int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len);
 int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len);
+
+/**
+ * pmic_reg_read() - read a PMIC register value
+ *
+ * @dev:	PMIC device to read
+ * @reg:	Register to read
+ * @return value read on success or negative value of errno.
+ */
+int pmic_reg_read(struct udevice *dev, uint reg);
+
+/**
+ * pmic_reg_write() - write a PMIC register value
+ *
+ * @dev:	PMIC device to write
+ * @reg:	Register to write
+ * @value:	Value to write
+ * @return 0 on success or negative value of errno.
+ */
+int pmic_reg_write(struct udevice *dev, uint reg, uint value);
+
+/**
+ * pmic_clrsetbits() - clear and set bits in a PMIC register
+ *
+ * This reads a register, optionally clears some bits, optionally sets some
+ * bits, then writes the register.
+ *
+ * @dev:	PMIC device to update
+ * @reg:	Register to update
+ * @clr:	Bit mask to clear (set those bits that you want cleared)
+ * @set:	Bit mask to set (set those bits that you want set)
+ * @return 0 on success or negative value of errno.
+ */
+int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set);
+
 #endif /* CONFIG_DM_PMIC */
 
 #ifdef CONFIG_POWER
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (38 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL Simon Glass
                   ` (15 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

This functionality may be useful for setting up regulators early during
boot.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 scripts/Makefile.spl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 24ca58b..1e58be9 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -67,6 +67,7 @@ libs-y += fs/
 libs-$(CONFIG_SPL_LED_SUPPORT) += drivers/led/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/
+libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/regulator/
 libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/
 libs-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/
 libs-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += drivers/misc/
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (39 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers Simon Glass
                   ` (14 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

This bloats the code size quite a bit and is less useful in SPL where there
is no command line.

Avoid including this code in SPL.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 lib/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/Makefile b/lib/Makefile
index ca72187..1139f9b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_USB_TTY) += circbuf.o
 obj-y += crc7.o
 obj-y += crc8.o
 obj-y += crc16.o
+obj-$(CONFIG_ERRNO_STR) += errno_str.o
 obj-$(CONFIG_FIT) += fdtdec_common.o
 obj-$(CONFIG_OF_CONTROL) += fdtdec_common.o
 obj-$(CONFIG_OF_CONTROL) += fdtdec.o
@@ -59,7 +60,6 @@ endif
 obj-$(CONFIG_ADDR_MAP) += addr_map.o
 obj-y += hashtable.o
 obj-y += errno.o
-obj-$(CONFIG_ERRNO_STR) += errno_str.o
 obj-y += display_options.o
 obj-$(CONFIG_BCH) += bch.o
 obj-y += crc32.o
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (40 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static Simon Glass
                   ` (13 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Add support for a driver which sets up DRAM and can return information about
the amount of RAM available. This is a first step towards moving RAM init
to driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/ram/Kconfig      | 18 ++++++++++++++++++
 drivers/ram/Makefile     |  7 +++++++
 drivers/ram/ram-uclass.c | 28 ++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 include/ram.h            | 38 ++++++++++++++++++++++++++++++++++++++
 scripts/Makefile.spl     |  1 +
 8 files changed, 96 insertions(+)
 create mode 100644 drivers/ram/Kconfig
 create mode 100644 drivers/ram/Makefile
 create mode 100644 drivers/ram/ram-uclass.c
 create mode 100644 include/ram.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 17a61e4..7c9eefc 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -36,6 +36,8 @@ source "drivers/pinctrl/Kconfig"
 
 source "drivers/power/Kconfig"
 
+source "drivers/ram/Kconfig"
+
 source "drivers/hwmon/Kconfig"
 
 source "drivers/watchdog/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index b68c4ee..39b7919 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -12,6 +12,7 @@ obj-y += misc/
 obj-y += pcmcia/
 obj-y += dfu/
 obj-$(CONFIG_PINCTRL) += pinctrl/
+obj-$(CONFIG_RAM) += ram/
 obj-y += rtc/
 obj-y += sound/
 obj-y += tpm/
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
new file mode 100644
index 0000000..642a2d8
--- /dev/null
+++ b/drivers/ram/Kconfig
@@ -0,0 +1,18 @@
+config RAM
+	bool "Enable RAM drivers using Driver Model"
+	depends on DM
+	help
+	  This allows drivers to be provided for SDRAM and other RAM
+	  controllers and their type to be specified in the board's device
+	  tree. Generally some parameters are required to set up the RAM and
+	  the RAM size can either be statically defined or dynamically
+	  detected.
+
+config SPL_RAM_SUPPORT
+	bool "Enable RAM support in SPL"
+	depends on RAM
+	help
+	  The RAM subsystem adds a small amount of overhead to the image.
+	  If this is acceptable and you have a need to use RAM drivers in
+	  SPL, enable this option. It might provide a cleaner interface to
+	  setting up RAM (e.g. SDRAM / DDR) within SPL.
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
new file mode 100644
index 0000000..4494d81
--- /dev/null
+++ b/drivers/ram/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+obj-$(CONFIG_RAM) += ram-uclass.o
diff --git a/drivers/ram/ram-uclass.c b/drivers/ram/ram-uclass.c
new file mode 100644
index 0000000..2f1fbe7
--- /dev/null
+++ b/drivers/ram/ram-uclass.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+int ram_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct ram_ops *ops = ram_get_ops(dev);
+
+	if (!ops->get_info)
+		return -ENOSYS;
+
+	return ops->get_info(dev, info);
+}
+
+UCLASS_DRIVER(ram) = {
+	.id		= UCLASS_RAM,
+	.name		= "ram",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 14a1614..5bb602f 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -28,6 +28,7 @@ enum uclass_id {
 	UCLASS_CPU,		/* CPU, typically part of an SoC */
 	UCLASS_CROS_EC,		/* Chrome OS EC */
 	UCLASS_DISPLAY_PORT,	/* Display port video */
+	UCLASS_RAM,		/* RAM controller */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
 	UCLASS_I2C,		/* I2C bus */
diff --git a/include/ram.h b/include/ram.h
new file mode 100644
index 0000000..e2172a8
--- /dev/null
+++ b/include/ram.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RAM_H
+#define __RAM_H
+
+struct ram_info {
+	phys_addr_t base;
+	size_t size;
+};
+
+struct ram_ops {
+	/**
+	 * get_info() - Get basic memory info
+	 *
+	 * @dev:	Device to check (UCLASS_RAM)
+	 * @info:	Place to put info
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*get_info)(struct udevice *dev, struct ram_info *info);
+};
+
+#define ram_get_ops(dev)        ((struct ram_ops *)(dev)->driver->ops)
+
+/**
+ * ram_get_info() - Get information about a RAM device
+ *
+ * @dev:	Device to check (UCLASS_RAM)
+ * @info:	Returns RAM info
+ * @return 0 if OK, -ve on error
+ */
+int ram_get_info(struct udevice *dev, struct ram_info *info);
+
+#endif
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 1e58be9..c4e83bb 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -79,6 +79,7 @@ libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/
 libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/
 libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/
 libs-$(CONFIG_SPL_PINCTRL_SUPPORT) += drivers/pinctrl/
+libs-$(CONFIG_SPL_RAM_SUPPORT) += drivers/ram/
 libs-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/
 libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/
 libs-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (41 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access Simon Glass
                   ` (12 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Several functions in this file should be marked as static. Update them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/spi/spi-uclass.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 737ae64..d666272 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -95,13 +95,13 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 	return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
 }
 
-int spi_post_bind(struct udevice *dev)
+static int spi_post_bind(struct udevice *dev)
 {
 	/* Scan the bus for devices */
 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
-int spi_child_post_bind(struct udevice *dev)
+static int spi_child_post_bind(struct udevice *dev)
 {
 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 
@@ -111,7 +111,7 @@ int spi_child_post_bind(struct udevice *dev)
 	return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
 }
 
-int spi_post_probe(struct udevice *bus)
+static int spi_post_probe(struct udevice *bus)
 {
 	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 
@@ -121,7 +121,7 @@ int spi_post_probe(struct udevice *bus)
 	return 0;
 }
 
-int spi_child_pre_probe(struct udevice *dev)
+static int spi_child_pre_probe(struct udevice *dev)
 {
 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 	struct spi_slave *slave = dev_get_parentdata(dev);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (42 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation Simon Glass
                   ` (11 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Since Rockchip requires 32-bit serial access, add this to the driver.
Refactor a little to make this easier.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/serial/ns16550.c | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 9b044a3..c8a77e2 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -246,6 +246,17 @@ int NS16550_tstc(NS16550_t com_port)
 
 #include <debug_uart.h>
 
+#define serial_dout(reg, value)	\
+	serial_out_shift((char *)com_port + \
+		((char *)reg - (char *)com_port) * \
+			(1 << CONFIG_DEBUG_UART_SHIFT), \
+		CONFIG_DEBUG_UART_SHIFT, value)
+#define serial_din(reg) \
+	serial_in_shift((char *)com_port + \
+		((char *)reg - (char *)com_port) * \
+			(1 << CONFIG_DEBUG_UART_SHIFT), \
+		CONFIG_DEBUG_UART_SHIFT)
+
 void debug_uart_init(void)
 {
 	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
@@ -259,28 +270,23 @@ void debug_uart_init(void)
 	 */
 	baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
 				    CONFIG_BAUDRATE);
-	serial_out_shift(&com_port->ier, CONFIG_DEBUG_UART_SHIFT,
-			 CONFIG_SYS_NS16550_IER);
-	serial_out_shift(&com_port->mcr, CONFIG_DEBUG_UART_SHIFT, UART_MCRVAL);
-	serial_out_shift(&com_port->fcr, CONFIG_DEBUG_UART_SHIFT, UART_FCRVAL);
-
-	serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
-			 UART_LCR_BKSE | UART_LCRVAL);
-	serial_out_shift(&com_port->dll, CONFIG_DEBUG_UART_SHIFT,
-			 baud_divisor & 0xff);
-	serial_out_shift(&com_port->dlm, CONFIG_DEBUG_UART_SHIFT,
-			 (baud_divisor >> 8) & 0xff);
-	serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
-			 UART_LCRVAL);
+	serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
+	serial_dout(&com_port->mcr, UART_MCRVAL);
+	serial_dout(&com_port->fcr, UART_FCRVAL);
+
+	serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
+	serial_dout(&com_port->dll, baud_divisor & 0xff);
+	serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);
+	serial_dout(&com_port->lcr, UART_LCRVAL);
 }
 
 static inline void _debug_uart_putc(int ch)
 {
 	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
 
-	while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE))
+	while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
 		;
-	serial_out_shift(&com_port->thr, CONFIG_DEBUG_UART_SHIFT, ch);
+	serial_dout(&com_port->thr, ch);
 }
 
 DEBUG_UART_FUNCS
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (43 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:57   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string Simon Glass
                   ` (10 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Add an implementation of RC4. This will be used by Rockchip booting but may
be useful in other situations.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 include/rc4.h | 21 +++++++++++++++++++++
 lib/Makefile  |  1 +
 lib/rc4.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)
 create mode 100644 include/rc4.h
 create mode 100644 lib/rc4.c

diff --git a/include/rc4.h b/include/rc4.h
new file mode 100644
index 0000000..ea409c2
--- /dev/null
+++ b/include/rc4.h
@@ -0,0 +1,21 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RC4_H
+#define __RC4_H
+
+/**
+ * rc4_encode() - encode a buf with the RC4 cipher
+ *
+ * @buf:	Buffer to encode (it is overwrite in the process
+ * @len:	Length of buffer in bytes
+ * @key:	16-byte key to use
+ */
+void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16]);
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index 1139f9b..fd106b9 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_MD5) += md5.o
 obj-y += net_utils.o
 obj-$(CONFIG_PHYSMEM) += physmem.o
 obj-y += qsort.o
+obj-y += rc4.o
 obj-$(CONFIG_SHA1) += sha1.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
 obj-$(CONFIG_SHA256) += sha256.o
diff --git a/lib/rc4.c b/lib/rc4.c
new file mode 100644
index 0000000..89d15f3
--- /dev/null
+++ b/lib/rc4.c
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ *
+ * Rivest Cipher 4 (RC4) implementation
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif
+#include <rc4.h>
+
+void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16])
+{
+	unsigned char s[256], k[256], temp;
+	unsigned short i, j, t;
+	int ptr;
+
+	j = 0;
+	for (i = 0; i < 256; i++) {
+		s[i] = (unsigned char)i;
+		j &= 0x0f;
+		k[i] = key[j];
+		j++;
+	}
+
+	j = 0;
+	for (i = 0; i < 256; i++) {
+		j = (j + s[i] + k[i]) % 256;
+		temp = s[i];
+		s[i] = s[j];
+		s[j] = temp;
+	}
+
+	i = 0;
+	j = 0;
+	for (ptr = 0; ptr < len; ptr++) {
+		i = (i + 1) % 256;
+		j = (j + s[i]) % 256;
+		temp = s[i];
+		s[i] = s[j];
+		s[j] = temp;
+		t = (s[i] + (s[j] % 256)) % 256;
+		buf[ptr] = buf[ptr] ^ s[t];
+	}
+}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (44 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found Simon Glass
                   ` (9 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Split out the code in fdtdec which finds a number at the end of a string. It
can be useful in other situations.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 include/vsprintf.h | 26 ++++++++++++++++++++++++++
 lib/fdtdec.c       | 14 ++++++--------
 lib/vsprintf.c     | 19 +++++++++++++++++++
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/include/vsprintf.h b/include/vsprintf.h
index 09c8abd..3af8a4f 100644
--- a/include/vsprintf.h
+++ b/include/vsprintf.h
@@ -41,6 +41,32 @@ unsigned long long simple_strtoull(const char *cp, char **endp,
 long simple_strtol(const char *cp, char **endp, unsigned int base);
 
 /**
+ * trailing_strtol() - extract a trailing integer from a string
+ *
+ * Given a string this finds a trailing number on the string and returns it.
+ * For example, "abc123" would return 123.
+ *
+ * @str:	String to exxamine
+ * @return training number if found, else -1
+ */
+long trailing_strtol(const char *str);
+
+/**
+ * trailing_strtoln() - extract a trailing integer from a fixed-length string
+ *
+ * Given a fixed-length string this finds a trailing number on the string
+ * and returns it. For example, "abc123" would return 123. Only the
+ * characters between @str and @end - 1 are examined. If @end is NULL, it is
+ * set to str + strlen(str).
+ *
+ * @str:	String to exxamine
+ * @end:	Pointer to end of string to examine, or NULL to use the
+ *		whole string
+ * @return training number if found, else -1
+ */
+long trailing_strtoln(const char *str, const char *end);
+
+/**
  * panic() - Print a message and reset/hang
  *
  * Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9877849..add9adc 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -505,8 +505,7 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 		const char *prop;
 		const char *name;
 		const char *slash;
-		const char *p;
-		int len;
+		int len, val;
 
 		prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
 		debug("   - %s, %s\n", name, prop);
@@ -517,12 +516,11 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 		slash = strrchr(prop, '/');
 		if (strcmp(slash + 1, find_name))
 			continue;
-		for (p = name + strlen(name) - 1; p > name; p--) {
-			if (!isdigit(*p)) {
-				*seqp = simple_strtoul(p + 1, NULL, 10);
-				debug("Found seq %d\n", *seqp);
-				return 0;
-			}
+		val = trailing_strtol(name);
+		if (val != -1) {
+			*seqp = val;
+			debug("Found seq %d\n", *seqp);
+			return 0;
 		}
 	}
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index bedc865..e7e569e 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -166,6 +166,25 @@ unsigned long long simple_strtoull(const char *cp, char **endp,
 	return result;
 }
 
+long trailing_strtoln(const char *str, const char *end)
+{
+	const char *p;
+
+	if (!end)
+		end = str + strlen(str);
+	for (p = end - 1; p > str; p--) {
+		if (!isdigit(*p))
+			return simple_strtoul(p + 1, NULL, 10);
+	}
+
+	return -1;
+}
+
+long trailing_strtol(const char *str)
+{
+	return trailing_strtoln(str, NULL);
+}
+
 /* we use this so that we can do without the ctype library */
 #define is_digit(c)	((c) >= '0' && (c) <= '9')
 
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (45 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f() Simon Glass
                   ` (8 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

It can be quite confusing with a new platform to figure out why the device
tree cannot be located. Add some debug information for this case.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 lib/fdtdec.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index add9adc..a78d577 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -568,6 +568,13 @@ int fdtdec_prepare_fdt(void)
 		puts("Missing DTB\n");
 #else
 		puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
+# ifdef DEBUG
+		if (gd->fdt_blob) {
+			printf("fdt_blob=%p\n", gd->fdt_blob);
+			print_buffer((ulong)gd->fdt_blob, gd->fdt_blob, 4,
+				     32, 0);
+		}
+# endif
 #endif
 		return -1;
 	}
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f()
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (46 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot Simon Glass
                   ` (7 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Add an spl_init() function that does basic init such that board_init_f() can
use simple malloc(), device tree and driver model. Each one is set up only
if enabled for SPL.

Note: We really should refactor SPL such that there is a single
board_init_f() and rename the existing weak board_init_f() functions
provided by boards, calling them from the single board_init_f().

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/spl/spl.c                  | 35 ++++++++++++++++++++++++-----------
 include/asm-generic/global_data.h |  1 +
 include/spl.h                     | 12 ++++++++++++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index aeb0645..074c41d 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -148,18 +148,12 @@ static void spl_ram_load_image(void)
 }
 #endif
 
-void board_init_r(gd_t *dummy1, ulong dummy2)
+int spl_init(void)
 {
-	u32 boot_device;
 	int ret;
 
-	debug(">>spl:board_init_r()\n");
-
-#if defined(CONFIG_SYS_SPL_MALLOC_START)
-	mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
-			CONFIG_SYS_SPL_MALLOC_SIZE);
-	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
-#elif defined(CONFIG_SYS_MALLOC_F_LEN)
+	debug("spl_init()\n");
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
 	gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
 	gd->malloc_ptr = 0;
 #endif
@@ -168,17 +162,36 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 		ret = fdtdec_setup();
 		if (ret) {
 			debug("fdtdec_setup() returned error %d\n", ret);
-			hang();
+			return ret;
 		}
 	}
 	if (IS_ENABLED(CONFIG_SPL_DM)) {
 		ret = dm_init_and_scan(true);
 		if (ret) {
 			debug("dm_init_and_scan() returned error %d\n", ret);
-			hang();
+			return ret;
 		}
 	}
+	gd->flags |= GD_FLG_SPL_INIT;
+
+	return 0;
+}
 
+void board_init_r(gd_t *dummy1, ulong dummy2)
+{
+	u32 boot_device;
+
+	debug(">>spl:board_init_r()\n");
+
+#if defined(CONFIG_SYS_SPL_MALLOC_START)
+	mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
+			CONFIG_SYS_SPL_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
+#endif
+	if (!(gd->flags & GD_FLG_SPL_INIT)) {
+		if (spl_init())
+			hang();
+	}
 #ifndef CONFIG_PPC
 	/*
 	 * timer_init() does not exist on PPC systems. The timer is initialized
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 6747619..73c61e6 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -115,5 +115,6 @@ typedef struct global_data {
 #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_FULL_MALLOC_INIT	0x00200	/* Full malloc() is ready	   */
+#define GD_FLG_SPL_INIT		0x00400	/* spl_init() has been called	   */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
diff --git a/include/spl.h b/include/spl.h
index d19940f..8e53426 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -81,6 +81,18 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image);
 int spl_load_image_ext(block_dev_desc_t *block_dev, int partition, const char *filename);
 int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);
 
+/**
+ * spl_init() - Set up device tree and driver model in SPL if enabled
+ *
+ * Call this function in board_init_f() if you want to use device tree and
+ * driver model early, before board_init_r() is called. This function will
+ * be called from board_init_r() if not called earlier.
+ *
+ * If this is not called, then driver model will be inactive in SPL's
+ * board_init_f(), and no device tree will be available.
+ */
+int spl_init(void);
+
 #ifdef CONFIG_SPL_BOARD_INIT
 void spl_board_init(void);
 #endif
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (47 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f() Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated Simon Glass
                   ` (6 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

As a debug option, add positive confirmation that SPL has completed
execution. This can help with diagnosing the location of unexpected hangs.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/spl/spl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 074c41d..94b01da 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -298,6 +298,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 	      gd->malloc_ptr / 1024);
 #endif
 
+	debug("loaded - jumping to U-Boot...");
 	jump_to_image_no_args(&spl_image);
 }
 
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (48 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-06-25 22:51   ` Joe Hershberger
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass Simon Glass
                   ` (5 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Some functions called by mkimage would like to know the output file size.
Initially this is the same as the input file size, but it may be affected by
adding headers, etc.

Add this information to the image parameters.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 tools/imagetool.h |  1 +
 tools/mkimage.c   | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/tools/imagetool.h b/tools/imagetool.h
index b7874f4..99bbf2f 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -59,6 +59,7 @@ struct image_tool_params {
 	const char *keydest;	/* Destination .dtb for public key */
 	const char *comment;	/* Comment to add to signature node */
 	int require_keys;	/* 1 to mark signing keys as 'required' */
+	int file_size;		/* Total size of output file */
 };
 
 /*
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 8808d70..e81d455 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -75,6 +75,7 @@ int main(int argc, char **argv)
 	int retval = 0;
 	struct image_type_params *tparams = NULL;
 	int pad_len = 0;
+	int dfd;
 
 	params.cmdname = *argv;
 	params.addr = params.ep = 0;
@@ -310,6 +311,22 @@ NXTARG:		;
 		exit (retval);
 	}
 
+	dfd = open(params.datafile, O_RDONLY | O_BINARY);
+	if (dfd < 0) {
+		fprintf(stderr, "%s: Can't open %s: %s\n",
+			params.cmdname, params.datafile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	if (fstat(dfd, &sbuf) < 0) {
+		fprintf(stderr, "%s: Can't stat %s: %s\n",
+			params.cmdname, params.datafile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	params.file_size = sbuf.st_size + tparams->header_size;
+	close(dfd);
+
 	/*
 	 * In case there an header with a variable
 	 * length will be added, the corresponding
@@ -409,6 +426,7 @@ NXTARG:		;
 			params.cmdname, params.imagefile, strerror(errno));
 		exit (EXIT_FAILURE);
 	}
+	params.file_size = sbuf.st_size;
 
 	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
 	if (ptr == MAP_FAILED) {
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (49 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops Simon Glass
                   ` (4 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

It is common for system reset to be available at multiple levels in modern
hardware. For example, an SoC may provide a reset option, and a board may
provide its own reset for reasons of security or thoroughness. It is useful
to be able to model this hardware without hard-coding the behaviour in the
SoC or board. Also there is a distinction sometimes between resetting just
the CPU (leaving GPIO state alone) and resetting all the PMICs, just cutting
power.

To achieve this, add a simple system reset uclass. It allows multiple devices
to provide reset functionality and provides a way to walk through them,
requesting a particular reset type until is it provided.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/misc/Kconfig        |  9 +++++++
 drivers/misc/Makefile       |  1 +
 drivers/misc/reset-uclass.c | 62 +++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h      |  1 +
 include/reset.h             | 62 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+)
 create mode 100644 drivers/misc/reset-uclass.c
 create mode 100644 include/reset.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 64b07a3..3b7f76a 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -73,3 +73,12 @@ config PCA9551_I2C_ADDR
 	default 0x60
 	help
 	  The I2C address of the PCA9551 LED controller.
+
+config RESET
+	bool "Enable support for reset drivers"
+	depends on DM
+	help
+	  Enable reset drivers which can be used to reset the CPU or board.
+	  Each driver can provide a reset method which will be called to
+	  effect a reset. The uclass will try all available drivers when
+	  reset_walk() is called.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 120babc..5da5178 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
 obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
 obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
+obj-$(CONFIG_RESET) += reset-uclass.o
diff --git a/drivers/misc/reset-uclass.c b/drivers/misc/reset-uclass.c
new file mode 100644
index 0000000..ba27757
--- /dev/null
+++ b/drivers/misc/reset-uclass.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <reset.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <linux/err.h>
+
+int reset_request(struct udevice *dev, enum reset_t type)
+{
+	struct reset_ops *ops = reset_get_ops(dev);
+
+	if (!ops->request)
+		return -ENOSYS;
+
+	return ops->request(dev, type);
+}
+
+void reset_walk(enum reset_t type)
+{
+	struct udevice *dev;
+	int ret = 0;
+
+	while (ret != -EINPROGRESS && type < RESET_COUNT) {
+		for (uclass_first_device(UCLASS_RESET, &dev);
+		dev;
+		uclass_next_device(&dev)) {
+			ret = reset_request(dev, type);
+			if (ret == -EINPROGRESS)
+				break;
+		}
+	}
+
+	/* Wait for the reset to take effect */
+	mdelay(100);
+
+	/* Still no reset? Give up */
+	printf("Reset not supported on this platform\n");
+	hang();
+}
+
+/**
+ * reset_cpu() - calls reset_walk(RESET_WARM)
+ */
+void reset_cpu(ulong addr)
+{
+	reset_walk(RESET_WARM);
+}
+
+UCLASS_DRIVER(reset) = {
+	.id		= UCLASS_RESET,
+	.name		= "reset",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 5bb602f..fc486f2 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -45,6 +45,7 @@ enum uclass_id {
 	UCLASS_PINCTRL,		/* Pin multiplexing control */
 	UCLASS_PMIC,		/* PMIC I/O device */
 	UCLASS_REGULATOR,	/* Regulator device */
+	UCLASS_RESET,		/* Reset device */
 	UCLASS_RTC,		/* Real time clock device */
 	UCLASS_SERIAL,		/* Serial UART */
 	UCLASS_SPI,		/* SPI bus */
diff --git a/include/reset.h b/include/reset.h
new file mode 100644
index 0000000..d29e108
--- /dev/null
+++ b/include/reset.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RESET_H
+#define __RESET_H
+
+enum reset_t {
+	RESET_WARM,	/* Reset CPU, keep GPIOs active */
+	RESET_COLD,	/* Reset CPU and GPIOs */
+	RESET_POWER,	/* Reset PMIC (remove and restore power) */
+
+	RESET_COUNT,
+};
+
+struct reset_ops {
+	/**
+	 * request() - request a reset of the given type
+	 *
+	 * Note that this function may return before the reset takes effect.
+	 *
+	 * @type:	Reset type to request
+	 * @return -EINPROGRESS if the reset has been started and
+	 *		will complete soon, -EPROTONOSUPPORT if not supported
+	 *		by this device, 0 if the reset has already happened
+	 *		(in which case this method will not actually return)
+	 */
+	int (*request)(struct udevice *dev, enum reset_t type);
+};
+
+#define reset_get_ops(dev)        ((struct reset_ops *)(dev)->driver->ops)
+
+/**
+ * reset_request() - request a reset
+ *
+ * @type:	Reset type to request
+ * @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
+ */
+int reset_request(struct udevice *dev, enum reset_t type);
+
+/**
+ * reset_walk() - cause a reset
+ *
+ * This works through the available reset devices until it finds one that can
+ * perform a reset. If the provided reset type is not available, the next one
+ * will be tried.
+ *
+ * If this function fails to reset, it will display a message and halt
+ *
+ * @type:	Reset type to request
+ */
+void reset_walk(enum reset_t type);
+
+/**
+ * reset_cpu() - calls reset_walk(RESET_WARM)
+ */
+void reset_cpu(ulong addr);
+
+#endif
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (50 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass Simon Glass
                   ` (3 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Since we want clk_ops to be used in U-Boot as a whole, rename the Zynq
version until it can be converted to driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 arch/arm/mach-zynq/clk.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index d2885dc..6444be8 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -48,11 +48,11 @@ DECLARE_GLOBAL_DATA_PTR;
 struct clk;
 
 /**
- * struct clk_ops:
+ * struct zynq_clk_ops:
  * @set_rate:	Function pointer to set_rate() implementation
  * @get_rate:	Function pointer to get_rate() implementation
  */
-struct clk_ops {
+struct zynq_clk_ops {
 	int (*set_rate)(struct clk *clk, unsigned long rate);
 	unsigned long (*get_rate)(struct clk *clk);
 };
@@ -72,7 +72,7 @@ struct clk {
 	enum zynq_clk	parent;
 	unsigned int	flags;
 	u32		*reg;
-	struct clk_ops	ops;
+	struct zynq_clk_ops	ops;
 };
 #define ZYNQ_CLK_FLAGS_HAS_2_DIVS	1
 
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (51 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-17 23:58   ` Simon Glass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function Simon Glass
                   ` (2 subsequent siblings)
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Clocks are an important feature of platforms and have become increasing
complex with time. Most modern SoCs have multiple PLLs and dozens of clock
dividers which distribute clocks to on-chip peripherals.

Some SoC implementations have a clock API which is private to that SoC family,
e.g. Tegra and Exynos. This is useful but it would be better to have a
common API that can be understood and used throughout U-Boot.

Add a simple clock API as a starting point. It supports querying and setting
the rate of a clock. Each clock is a device. To reduce memory and processing
overhead the concept of peripheral clocks is provided. These do not need to
be explicit devices - it is possible to write a driver that can adjust the
I2C clock (for example) without an explicit I2C clock device. This can
dramatically reduce the number of devices (and associated overhead) in a
complex SoC.

Clocks are referenced by a number, and it is expected that SoCs will define
that numbering themselves via an enum.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/clk/Kconfig      | 19 ++++++++++++
 drivers/clk/Makefile     |  8 +++++
 drivers/clk/clk-uclass.c | 58 +++++++++++++++++++++++++++++++++++
 include/clk.h            | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 scripts/Makefile.spl     |  1 +
 8 files changed, 170 insertions(+)
 create mode 100644 drivers/clk/Kconfig
 create mode 100644 drivers/clk/Makefile
 create mode 100644 drivers/clk/clk-uclass.c

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7c9eefc..619d93a 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -1,5 +1,7 @@
 menu "Device Drivers"
 
+source "drivers/clk/Kconfig"
+
 source "drivers/core/Kconfig"
 
 source "drivers/cpu/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 39b7919..9f5cec7 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_CLK) += clk/
 obj-$(CONFIG_DM) += core/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
new file mode 100644
index 0000000..07eb54c
--- /dev/null
+++ b/drivers/clk/Kconfig
@@ -0,0 +1,19 @@
+config CLK
+	bool "Enable clock driver support"
+	depends on DM
+	help
+	  This allows drivers to be provided for clock generators, including
+	  oscillators and PLLs. Devices can use a common clock API to request
+	  a particular clock rate and check on available clocks. Clocks can
+	  feed into other clocks in a tree structure, with multiplexers to
+	  choose the source for each clock.
+
+config SPL_CLK_SUPPORT
+	bool "Enable clock support in SPL"
+	depends on CLK
+	help
+	  The clock subsystem adds a small amount of overhead to the image.
+	  If this is acceptable and you have a need to use clock drivers in
+	  SPL, enable this option. It might provide a cleaner interface to
+	  setting up clocks within SPL, and allows the same drivers to be
+	  used as U-Boot proper.
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
new file mode 100644
index 0000000..b51cf23
--- /dev/null
+++ b/drivers/clk/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_CLK) += clk-uclass.o
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
new file mode 100644
index 0000000..73dfd7d
--- /dev/null
+++ b/drivers/clk/clk-uclass.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+ulong clk_get_rate(struct udevice *dev)
+{
+	struct clk_ops *ops = clk_get_ops(dev);
+
+	if (!ops->get_rate)
+		return -ENOSYS;
+
+	return ops->get_rate(dev);
+}
+
+ulong clk_set_rate(struct udevice *dev, ulong rate)
+{
+	struct clk_ops *ops = clk_get_ops(dev);
+
+	if (!ops->set_rate)
+		return -ENOSYS;
+
+	return ops->set_rate(dev, rate);
+}
+
+ulong clk_get_periph_rate(struct udevice *dev, int periph)
+{
+	struct clk_ops *ops = clk_get_ops(dev);
+
+	if (!ops->get_periph_rate)
+		return -ENOSYS;
+
+	return ops->get_periph_rate(dev, periph);
+}
+
+ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate)
+{
+	struct clk_ops *ops = clk_get_ops(dev);
+
+	if (!ops->set_periph_rate)
+		return -ENOSYS;
+
+	return ops->set_periph_rate(dev, periph, rate);
+}
+
+UCLASS_DRIVER(clk) = {
+	.id		= UCLASS_CLK,
+	.name		= "clk",
+};
diff --git a/include/clk.h b/include/clk.h
index df4570c..254ad2b 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -1,6 +1,86 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
 #ifndef _CLK_H_
 #define _CLK_H_
 
 int soc_clk_dump(void);
 
+struct clk_ops {
+	/**
+	 * get_rate() - Get current clock rate
+	 *
+	 * @dev:	Device to check (UCLASS_CLK)
+	 * @return clock rate in Hz, or -ve error code
+	 */
+	ulong (*get_rate)(struct udevice *dev);
+
+	/**
+	 * set_rate() - Set current clock rate
+	 *
+	 * @dev:	Device to adjust
+	 * @rate:	New clock rate in Hz
+	 * @return new rate, or -ve error code
+	 */
+	ulong (*set_rate)(struct udevice *dev, ulong rate);
+
+	/**
+	* clk_set_periph_rate() - Set clock rate for a peripheral
+	*
+	* @dev:	Device to adjust (UCLASS_CLK)
+	* @rate:	New clock rate in Hz
+	* @return new clock rate in Hz, or -ve error code
+	*/
+	ulong (*get_periph_rate)(struct udevice *dev, int periph);
+
+	/**
+	 * clk_set_periph_rate() - Set current clock rate for a peripheral
+	 *
+	 * @dev:	Device to update (UCLASS_CLK)
+	 * @periph:	Peripheral ID to cupdate
+	 * @return new clock rate in Hz, or -ve error code
+	 */
+	ulong (*set_periph_rate)(struct udevice *dev, int periph, ulong rate);
+};
+
+#define clk_get_ops(dev)	((struct clk_ops *)(dev)->driver->ops)
+
+/**
+ * clk_get_rate() - Get current clock rate
+ *
+ * @dev:	Device to check (UCLASS_CLK)
+ * @return clock rate in Hz, or -ve error code
+ */
+ulong clk_get_rate(struct udevice *dev);
+
+/**
+ * set_rate() - Set current clock rate
+ *
+ * @dev:	Device to adjust
+ * @rate:	New clock rate in Hz
+ * @return new rate, or -ve error code
+ */
+ulong clk_set_rate(struct udevice *dev, ulong rate);
+
+/**
+ * clk_get_periph_rate() - Get current clock rate for a peripheral
+ *
+ * @dev:	Device to check (UCLASS_CLK)
+ * @return clock rate in Hz, -ve error code
+ */
+ulong clk_get_periph_rate(struct udevice *dev, int periph);
+
+/**
+ * clk_set_periph_rate() - Set current clock rate for a peripheral
+ *
+ * @dev:	Device to update (UCLASS_CLK)
+ * @periph:	Peripheral ID to cupdate
+ * @return new clock rate in Hz, or -ve error code
+ */
+ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate);
+
 #endif /* _CLK_H_ */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index fc486f2..72512b5 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -25,6 +25,7 @@ enum uclass_id {
 	UCLASS_SIMPLE_BUS,	/* bus with child devices */
 
 	/* U-Boot uclasses start here - in alphabetical order */
+	UCLASS_CLK,		/* Clock source, e.g. used by peripherals */
 	UCLASS_CPU,		/* CPU, typically part of an SoC */
 	UCLASS_CROS_EC,		/* Chrome OS EC */
 	UCLASS_DISPLAY_PORT,	/* Display port video */
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index c4e83bb..9d7ac99 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -54,6 +54,7 @@ libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
 libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
 libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/
 libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
+libs-$(CONFIG_SPL_CLK_SUPPORT) += drivers/clk/
 libs-$(CONFIG_SPL_DM) += drivers/core/
 libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/
 libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (52 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass Simon Glass
@ 2015-06-23 21:39 ` Simon Glass
  2015-07-01  9:44   ` Przemyslaw Marczak
  2015-06-30 16:08 ` [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses York Sun
  2015-07-03  3:28 ` Simon Glass
  55 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-23 21:39 UTC (permalink / raw)
  To: u-boot

Use the common function to obtain the number from the end of the string,
instead of a local function. Also tweak the position of a debug() statement.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Split this series apart from the Rockchip series

Changes in v2: None

 drivers/power/pmic/pmic-uclass.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index dbab3e3..d99cb9a 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -9,6 +9,7 @@
 #include <fdtdec.h>
 #include <errno.h>
 #include <dm.h>
+#include <vsprintf.h>
 #include <dm/lists.h>
 #include <dm/device-internal.h>
 #include <dm/uclass-internal.h>
@@ -17,16 +18,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static ulong str_get_num(const char *ptr, const char *maxptr)
-{
-	if (!ptr || !maxptr)
-		return 0;
-
-	while (!isdigit(*ptr) && ptr++ < maxptr);
-
-	return simple_strtoul(ptr, NULL, 0);
-}
-
 int pmic_bind_children(struct udevice *pmic, int offset,
 		       const struct pmic_child_info *child_info)
 {
@@ -35,7 +26,6 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 	struct driver *drv;
 	struct udevice *child;
 	const char *node_name;
-	int node_name_len;
 	int bind_count = 0;
 	int node;
 	int prefix_len;
@@ -47,19 +37,19 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 	for (node = fdt_first_subnode(blob, offset);
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
-		node_name = fdt_get_name(blob, node, &node_name_len);
+		node_name = fdt_get_name(blob, node, NULL);
 
 		debug("* Found child node: '%s' at offset:%d\n", node_name,
 								 node);
 
 		child = NULL;
 		for (info = child_info; info->prefix && info->driver; info++) {
+			debug("  - compatible prefix: '%s'\n", info->prefix);
+
 			prefix_len = strlen(info->prefix);
 			if (strncmp(info->prefix, node_name, prefix_len))
 				continue;
 
-			debug("  - compatible prefix: '%s'\n", info->prefix);
-
 			drv = lists_driver_lookup_name(info->driver);
 			if (!drv) {
 				debug("  - driver: '%s' not found!\n",
@@ -78,10 +68,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 
 			debug("  - bound child device: '%s'\n", child->name);
 
-			child->driver_data = str_get_num(node_name +
-							 prefix_len,
-							 node_name +
-							 node_name_len);
+			child->driver_data = trailing_strtol(node_name);
 
 			debug("  - set 'child->driver_data': %lu\n",
 			      child->driver_data);
-- 
2.4.3.573.g4eafbef

^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
@ 2015-06-24  1:50   ` Chen-Yu Tsai
  2015-06-25  1:58   ` Jaehoon Chung
  1 sibling, 0 replies; 133+ messages in thread
From: Chen-Yu Tsai @ 2015-06-24  1:50 UTC (permalink / raw)
  To: u-boot

Hi,

On Wed, Jun 24, 2015 at 5:38 AM, Simon Glass <sjg@chromium.org> wrote:
> Some SoCs want to adjust the input clock to the DWMMC block as a way of
> controlling the MMC bus clock. Update the get_mmc_clk() method to support
> this.

The subject line should probably reflect this is a DWMMC only patch?
There are systems that have MMC and don't use the DWMMC controller.

ChenYu

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/dw_mmc.c        |  2 +-
>  drivers/mmc/exynos_dw_mmc.c |  2 +-
>  include/dwmmc.h             | 16 +++++++++++++++-
>  3 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 8f28d7e..a034c3f 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -248,7 +248,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>          * host->bus_hz should be set by user.
>          */
>         if (host->get_mmc_clk)
> -               sclk = host->get_mmc_clk(host);
> +               sclk = host->get_mmc_clk(host, freq);
>         else if (host->bus_hz)
>                 sclk = host->bus_hz;
>         else {
> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
> index e083745..3f702ba 100644
> --- a/drivers/mmc/exynos_dw_mmc.c
> +++ b/drivers/mmc/exynos_dw_mmc.c
> @@ -39,7 +39,7 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
>         dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
>  }
>
> -unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
> +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
>  {
>         unsigned long sclk;
>         int8_t clk_div;
> diff --git a/include/dwmmc.h b/include/dwmmc.h
> index 7a7555a..25cf42c 100644
> --- a/include/dwmmc.h
> +++ b/include/dwmmc.h
> @@ -163,7 +163,21 @@ struct dwmci_host {
>
>         void (*clksel)(struct dwmci_host *host);
>         void (*board_init)(struct dwmci_host *host);
> -       unsigned int (*get_mmc_clk)(struct dwmci_host *host);
> +
> +       /**
> +        * Get / set a particular MMC clock frequency
> +        *
> +        * This is used to request the current clock frequency of the clock
> +        * that drives the DWMMC peripheral. The caller will then use this
> +        * information to work out the divider it needs to achieve the
> +        * required MMC bus clock frequency. If you want to handle the
> +        * clock external to DWMMC, use @freq to select the frequency and
> +        * return that value too. Then DWMMC will put itself in bypass mode.
> +        *
> +        * @host:       DWMMC host
> +        * @freq:       Frequency the host is trying to achieve
> +        */
> +       unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
>
>         struct mmc_config cfg;
>  };
> --
> 2.4.3.573.g4eafbef
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors Simon Glass
@ 2015-06-24  1:56   ` Chen-Yu Tsai
  0 siblings, 0 replies; 133+ messages in thread
From: Chen-Yu Tsai @ 2015-06-24  1:56 UTC (permalink / raw)
  To: u-boot

On Wed, Jun 24, 2015 at 5:38 AM, Simon Glass <sjg@chromium.org> wrote:
> These bloat the code and cause problems for SPL. Use debug() where possible
> and try to return a useful error code instead.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/dw_mmc.c | 21 +++++++++++----------

Subject line and description should show this is dwmmc specific.

ChenYu

>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 53a8aca..8f28d7e 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -8,6 +8,7 @@
>
>  #include <bouncebuf.h>
>  #include <common.h>
> +#include <errno.h>
>  #include <malloc.h>
>  #include <mmc.h>
>  #include <dwmmc.h>
> @@ -119,7 +120,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>
>         while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
>                 if (get_timer(start) > timeout) {
> -                       printf("%s: Timeout on data busy\n", __func__);
> +                       debug("%s: Timeout on data busy\n", __func__);
>                         return TIMEOUT;
>                 }
>         }
> @@ -178,7 +179,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>         }
>
>         if (i == retry) {
> -               printf("%s: Timeout.\n", __func__);
> +               debug("%s: Timeout.\n", __func__);
>                 return TIMEOUT;
>         }
>
> @@ -194,8 +195,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>                 debug("%s: Response Timeout.\n", __func__);
>                 return TIMEOUT;
>         } else if (mask & DWMCI_INTMSK_RE) {
> -               printf("%s: Response Error.\n", __func__);
> -               return -1;
> +               debug("%s: Response Error.\n", __func__);
> +               return -EIO;
>         }
>
>
> @@ -214,7 +215,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>                 do {
>                         mask = dwmci_readl(host, DWMCI_RINTSTS);
>                         if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
> -                               printf("%s: DATA ERROR!\n", __func__);
> +                               debug("%s: DATA ERROR!\n", __func__);
>                                 return -1;
>                         }
>                 } while (!(mask & DWMCI_INTMSK_DTO));
> @@ -251,7 +252,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>         else if (host->bus_hz)
>                 sclk = host->bus_hz;
>         else {
> -               printf("%s: Didn't get source clock value.\n", __func__);
> +               debug("%s: Didn't get source clock value.\n", __func__);
>                 return -EINVAL;
>         }
>
> @@ -270,7 +271,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>         do {
>                 status = dwmci_readl(host, DWMCI_CMD);
>                 if (timeout-- < 0) {
> -                       printf("%s: Timeout!\n", __func__);
> +                       debug("%s: Timeout!\n", __func__);
>                         return -ETIMEDOUT;
>                 }
>         } while (status & DWMCI_CMD_START);
> @@ -285,7 +286,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>         do {
>                 status = dwmci_readl(host, DWMCI_CMD);
>                 if (timeout-- < 0) {
> -                       printf("%s: Timeout!\n", __func__);
> +                       debug("%s: Timeout!\n", __func__);
>                         return -ETIMEDOUT;
>                 }
>         } while (status & DWMCI_CMD_START);
> @@ -339,8 +340,8 @@ static int dwmci_init(struct mmc *mmc)
>         dwmci_writel(host, DWMCI_PWREN, 1);
>
>         if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
> -               printf("%s[%d] Fail-reset!!\n", __func__, __LINE__);
> -               return -1;
> +               debug("%s[%d] Fail-reset!!\n", __func__, __LINE__);
> +               return -EIO;
>         }
>
>         /* Enumerate at 400KHz */
> --
> 2.4.3.573.g4eafbef
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
  2015-06-24  1:50   ` Chen-Yu Tsai
@ 2015-06-25  1:58   ` Jaehoon Chung
  1 sibling, 0 replies; 133+ messages in thread
From: Jaehoon Chung @ 2015-06-25  1:58 UTC (permalink / raw)
  To: u-boot

Hi, Simon.

On 06/24/2015 06:38 AM, Simon Glass wrote:
> Some SoCs want to adjust the input clock to the DWMMC block as a way of
> controlling the MMC bus clock. Update the get_mmc_clk() method to support
> this.

I didn't see your other patches.
But i don't know this patch's purpose.
I think that @freq usage seems like host->bus_hz ("bus_hz" property), doesn't it?

Best Regards,
Jaehoon Chung

> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/dw_mmc.c        |  2 +-
>  drivers/mmc/exynos_dw_mmc.c |  2 +-
>  include/dwmmc.h             | 16 +++++++++++++++-
>  3 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 8f28d7e..a034c3f 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -248,7 +248,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>  	 * host->bus_hz should be set by user.
>  	 */
>  	if (host->get_mmc_clk)
> -		sclk = host->get_mmc_clk(host);
> +		sclk = host->get_mmc_clk(host, freq);
>  	else if (host->bus_hz)
>  		sclk = host->bus_hz;
>  	else {
> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
> index e083745..3f702ba 100644
> --- a/drivers/mmc/exynos_dw_mmc.c
> +++ b/drivers/mmc/exynos_dw_mmc.c
> @@ -39,7 +39,7 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
>  	dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
>  }
>  
> -unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
> +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
>  {
>  	unsigned long sclk;
>  	int8_t clk_div;
> diff --git a/include/dwmmc.h b/include/dwmmc.h
> index 7a7555a..25cf42c 100644
> --- a/include/dwmmc.h
> +++ b/include/dwmmc.h
> @@ -163,7 +163,21 @@ struct dwmci_host {
>  
>  	void (*clksel)(struct dwmci_host *host);
>  	void (*board_init)(struct dwmci_host *host);
> -	unsigned int (*get_mmc_clk)(struct dwmci_host *host);
> +
> +	/**
> +	 * Get / set a particular MMC clock frequency
> +	 *
> +	 * This is used to request the current clock frequency of the clock
> +	 * that drives the DWMMC peripheral. The caller will then use this
> +	 * information to work out the divider it needs to achieve the
> +	 * required MMC bus clock frequency. If you want to handle the
> +	 * clock external to DWMMC, use @freq to select the frequency and
> +	 * return that value too. Then DWMMC will put itself in bypass mode.
> +	 *
> +	 * @host:	DWMMC host
> +	 * @freq:	Frequency the host is trying to achieve
> +	 */
> +	unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
>  
>  	struct mmc_config cfg;
>  };
> 

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided Simon Glass
@ 2015-06-25  1:58   ` Jaehoon Chung
  2015-06-25 19:26     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Jaehoon Chung @ 2015-06-25  1:58 UTC (permalink / raw)
  To: u-boot

Hi, Simon.

On 06/24/2015 06:38 AM, Simon Glass wrote:
> We can calculate this. Add code to do this if it is not provided.

Did you consider the kernel side?

Best Regards,
Jaehoon Chung

> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/dw_mmc.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index a034c3f..cce2a5d 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -355,9 +355,15 @@ static int dwmci_init(struct mmc *mmc)
>  	dwmci_writel(host, DWMCI_IDINTEN, 0);
>  	dwmci_writel(host, DWMCI_BMOD, 1);
>  
> -	if (host->fifoth_val) {
> -		dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
> +	if (!host->fifoth_val) {
> +		uint32_t fifo_size;
> +
> +		fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
> +		fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
> +		host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
> +				TX_WMARK(fifo_size / 2);
>  	}
> +	dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
>  
>  	dwmci_writel(host, DWMCI_CLKENA, 0);
>  	dwmci_writel(host, DWMCI_CLKSRC, 0);
> 

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided
  2015-06-25  1:58   ` Jaehoon Chung
@ 2015-06-25 19:26     ` Simon Glass
  2015-06-26  4:49       ` Jaehoon Chung
  0 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-25 19:26 UTC (permalink / raw)
  To: u-boot

Hi Jaehoon,

On 24 June 2015 at 19:58, Jaehoon Chung <jh80.chung@gmail.com> wrote:
>
> Hi, Simon.
>
> On 06/24/2015 06:38 AM, Simon Glass wrote:
> > We can calculate this. Add code to do this if it is not provided.
>
> Did you consider the kernel side?

Can you please be more specific?

Regards,
Simon

>
> Best Regards,
> Jaehoon Chung
>
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> > Changes in v3: None
> > Changes in v2: None
> >
> >  drivers/mmc/dw_mmc.c | 10 ++++++++--
> >  1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> > index a034c3f..cce2a5d 100644
> > --- a/drivers/mmc/dw_mmc.c
> > +++ b/drivers/mmc/dw_mmc.c
> > @@ -355,9 +355,15 @@ static int dwmci_init(struct mmc *mmc)
> >       dwmci_writel(host, DWMCI_IDINTEN, 0);
> >       dwmci_writel(host, DWMCI_BMOD, 1);
> >
> > -     if (host->fifoth_val) {
> > -             dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
> > +     if (!host->fifoth_val) {
> > +             uint32_t fifo_size;
> > +
> > +             fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
> > +             fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
> > +             host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
> > +                             TX_WMARK(fifo_size / 2);
> >       }
> > +     dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
> >
> >       dwmci_writel(host, DWMCI_CLKENA, 0);
> >       dwmci_writel(host, DWMCI_CLKSRC, 0);
> >
>

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated Simon Glass
@ 2015-06-25 22:51   ` Joe Hershberger
  2015-07-17 23:58     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Joe Hershberger @ 2015-06-25 22:51 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jun 23, 2015 at 4:39 PM, Simon Glass <sjg@chromium.org> wrote:
> Some functions called by mkimage would like to know the output file size.
> Initially this is the same as the input file size, but it may be affected by
> adding headers, etc.
>
> Add this information to the image parameters.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided
  2015-06-25 19:26     ` Simon Glass
@ 2015-06-26  4:49       ` Jaehoon Chung
  0 siblings, 0 replies; 133+ messages in thread
From: Jaehoon Chung @ 2015-06-26  4:49 UTC (permalink / raw)
  To: u-boot

Hi, Simon.

On 06/26/2015 04:26 AM, Simon Glass wrote:
> Hi Jaehoon,
> 
> On 24 June 2015 at 19:58, Jaehoon Chung <jh80.chung@gmail.com> wrote:
>>
>> Hi, Simon.
>>
>> On 06/24/2015 06:38 AM, Simon Glass wrote:
>>> We can calculate this. Add code to do this if it is not provided.
>>
>> Did you consider the kernel side?
> 
> Can you please be more specific?

I didn't check now for fifoth value.
But as i know (in my experiment), if it's not defined fifoth_val into kernel dt file,
fifoth value is calculated with value of reading register.

Well, i think your patch is right.
(It needs to calculate the exactly fifoth_val.)

The below case should be problem.

1. Calculate and set the fifoth value at bootloader.
fifoth register = 0x203f0040
2. If fifoth_val doesn't set into dt-file(kernel), on kernel side re-calculate fifoth value.
Should be fifo_size = 3f, since fifoth register's value is 0x203f0040.
and fifoth register should be set to 0x201e001f.(just example.)

So i will try to find more generic solution for this problem.
If i missed something, let me know, plz. :)

Actually, this case is complicated case.

Best Regards,
Jaehoon Chung

> 
> Regards,1
> Simon
> 
>>
>> Best Regards,
>> Jaehoon Chung
>>
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> Changes in v3: None
>>> Changes in v2: None
>>>
>>>  drivers/mmc/dw_mmc.c | 10 ++++++++--
>>>  1 file changed, 8 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>>> index a034c3f..cce2a5d 100644
>>> --- a/drivers/mmc/dw_mmc.c
>>> +++ b/drivers/mmc/dw_mmc.c
>>> @@ -355,9 +355,15 @@ static int dwmci_init(struct mmc *mmc)
>>>       dwmci_writel(host, DWMCI_IDINTEN, 0);
>>>       dwmci_writel(host, DWMCI_BMOD, 1);
>>>
>>> -     if (host->fifoth_val) {
>>> -             dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
>>> +     if (!host->fifoth_val) {
>>> +             uint32_t fifo_size;
>>> +
>>> +             fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
>>> +             fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
>>> +             host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
>>> +                             TX_WMARK(fifo_size / 2);
>>>       }
>>> +     dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
>>>
>>>       dwmci_writel(host, DWMCI_CLKENA, 0);
>>>       dwmci_writel(host, DWMCI_CLKSRC, 0);
>>>
>>
> 

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (53 preceding siblings ...)
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function Simon Glass
@ 2015-06-30 16:08 ` York Sun
  2015-06-30 18:33   ` Simon Glass
  2015-07-03  3:28 ` Simon Glass
  55 siblings, 1 reply; 133+ messages in thread
From: York Sun @ 2015-06-30 16:08 UTC (permalink / raw)
  To: u-boot

Simon,

Does the dm force using device tree? I was reviewing a patch set regarding SPI
and found OF_CONTROL has to be selected in order to get the driver model happy.

My understanding of the driver model is both device tree and platform data are
allowed, like Linux. Is that still true?

York

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 16:08 ` [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses York Sun
@ 2015-06-30 18:33   ` Simon Glass
  2015-06-30 18:42     ` York Sun
  0 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-30 18:33 UTC (permalink / raw)
  To: u-boot

Hi York,

On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
> Simon,
>
> Does the dm force using device tree? I was reviewing a patch set regarding SPI
> and found OF_CONTROL has to be selected in order to get the driver model happy.
>
> My understanding of the driver model is both device tree and platform data are
> allowed, like Linux. Is that still true?

For buses you need device tree. I was rather hoping that we could
avoid platform data on platforms that have device tree. What is the
point?

Regards,
Simon

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 18:33   ` Simon Glass
@ 2015-06-30 18:42     ` York Sun
  2015-06-30 19:01       ` Tom Rini
  2015-06-30 19:01       ` Jagan Teki
  0 siblings, 2 replies; 133+ messages in thread
From: York Sun @ 2015-06-30 18:42 UTC (permalink / raw)
  To: u-boot



On 06/30/2015 11:33 AM, Simon Glass wrote:
> Hi York,
> 
> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>> Simon,
>>
>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>
>> My understanding of the driver model is both device tree and platform data are
>> allowed, like Linux. Is that still true?
> 
> For buses you need device tree. I was rather hoping that we could
> avoid platform data on platforms that have device tree. What is the
> point?
> 

Simon,

It happens on a platform not using device tree, but DM will be used.

I prefer DM to have both, rather than being forced to use device tree, unless we
are going to enforce using device tree on all new platforms. Since device tree
is still an option, I feel it is best to support platform data, like Linux
drivers do.

York

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 18:42     ` York Sun
@ 2015-06-30 19:01       ` Tom Rini
  2015-06-30 20:10         ` York Sun
  2015-06-30 19:01       ` Jagan Teki
  1 sibling, 1 reply; 133+ messages in thread
From: Tom Rini @ 2015-06-30 19:01 UTC (permalink / raw)
  To: u-boot

On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
> 
> 
> On 06/30/2015 11:33 AM, Simon Glass wrote:
> > Hi York,
> > 
> > On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
> >> Simon,
> >>
> >> Does the dm force using device tree? I was reviewing a patch set regarding SPI
> >> and found OF_CONTROL has to be selected in order to get the driver model happy.
> >>
> >> My understanding of the driver model is both device tree and platform data are
> >> allowed, like Linux. Is that still true?
> > 
> > For buses you need device tree. I was rather hoping that we could
> > avoid platform data on platforms that have device tree. What is the
> > point?
> > 
> 
> Simon,
> 
> It happens on a platform not using device tree, but DM will be used.
> 
> I prefer DM to have both, rather than being forced to use device tree, unless we
> are going to enforce using device tree on all new platforms. Since device tree
> is still an option, I feel it is best to support platform data, like Linux
> drivers do.

Well, to what end?  My recollection is that in short, the kernel has
both since platform data predates device tree (and converting platform
data to device tree is still a thing that happens).  But we're trying to
skip that intermediate step.  Are there platforms where you do not plan
to use a device tree, ever?

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150630/2a48a2b6/attachment.sig>

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 18:42     ` York Sun
  2015-06-30 19:01       ` Tom Rini
@ 2015-06-30 19:01       ` Jagan Teki
  1 sibling, 0 replies; 133+ messages in thread
From: Jagan Teki @ 2015-06-30 19:01 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 00:12, York Sun <yorksun@freescale.com> wrote:
>
>
> On 06/30/2015 11:33 AM, Simon Glass wrote:
>> Hi York,
>>
>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>>> Simon,
>>>
>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>>
>>> My understanding of the driver model is both device tree and platform data are
>>> allowed, like Linux. Is that still true?
>>
>> For buses you need device tree. I was rather hoping that we could
>> avoid platform data on platforms that have device tree. What is the
>> point?
>>
>
> Simon,
>
> It happens on a platform not using device tree, but DM will be used.
>
> I prefer DM to have both, rather than being forced to use device tree, unless we
> are going to enforce using device tree on all new platforms. Since device tree
> is still an option, I feel it is best to support platform data, like Linux
> drivers do.

I can understand your concern about pdata, but the dts is more dynamic approach
to get the device data and at least some of the architecture in u-boot
had a support
for it. And if we start with dts boards will turn it on to use dts
instead of going back to
use legacy pdata which is so called static approach (which might
increase the board
code, some times increasing configs)

Using/adding/going by dts support is more generic and dynamic instead
of static, IMHO

thanks!
-- 
Jagan | openedev.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 19:01       ` Tom Rini
@ 2015-06-30 20:10         ` York Sun
  2015-06-30 20:31           ` Tom Rini
  0 siblings, 1 reply; 133+ messages in thread
From: York Sun @ 2015-06-30 20:10 UTC (permalink / raw)
  To: u-boot



On 06/30/2015 12:01 PM, Tom Rini wrote:
> On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
>>
>>
>> On 06/30/2015 11:33 AM, Simon Glass wrote:
>>> Hi York,
>>>
>>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>>>> Simon,
>>>>
>>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>>>
>>>> My understanding of the driver model is both device tree and platform data are
>>>> allowed, like Linux. Is that still true?
>>>
>>> For buses you need device tree. I was rather hoping that we could
>>> avoid platform data on platforms that have device tree. What is the
>>> point?
>>>
>>
>> Simon,
>>
>> It happens on a platform not using device tree, but DM will be used.
>>
>> I prefer DM to have both, rather than being forced to use device tree, unless we
>> are going to enforce using device tree on all new platforms. Since device tree
>> is still an option, I feel it is best to support platform data, like Linux
>> drivers do.
> 
> Well, to what end?  My recollection is that in short, the kernel has
> both since platform data predates device tree (and converting platform
> data to device tree is still a thing that happens).  But we're trying to
> skip that intermediate step.  Are there platforms where you do not plan
> to use a device tree, ever?
> 

Tom,

I am not against using device tree at all. It is more dynamic and flexible. But
I don't see any indication that we favor device tree over pdata (except in the
code). If we are skipping pdata for new drivers, a clear message will be
helpful. That's what I am trying to get clarification.

York

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 20:10         ` York Sun
@ 2015-06-30 20:31           ` Tom Rini
  2015-06-30 21:08             ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Tom Rini @ 2015-06-30 20:31 UTC (permalink / raw)
  To: u-boot

On Tue, Jun 30, 2015 at 01:10:45PM -0700, York Sun wrote:
> 
> 
> On 06/30/2015 12:01 PM, Tom Rini wrote:
> > On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
> >>
> >>
> >> On 06/30/2015 11:33 AM, Simon Glass wrote:
> >>> Hi York,
> >>>
> >>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
> >>>> Simon,
> >>>>
> >>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
> >>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
> >>>>
> >>>> My understanding of the driver model is both device tree and platform data are
> >>>> allowed, like Linux. Is that still true?
> >>>
> >>> For buses you need device tree. I was rather hoping that we could
> >>> avoid platform data on platforms that have device tree. What is the
> >>> point?
> >>>
> >>
> >> Simon,
> >>
> >> It happens on a platform not using device tree, but DM will be used.
> >>
> >> I prefer DM to have both, rather than being forced to use device tree, unless we
> >> are going to enforce using device tree on all new platforms. Since device tree
> >> is still an option, I feel it is best to support platform data, like Linux
> >> drivers do.
> > 
> > Well, to what end?  My recollection is that in short, the kernel has
> > both since platform data predates device tree (and converting platform
> > data to device tree is still a thing that happens).  But we're trying to
> > skip that intermediate step.  Are there platforms where you do not plan
> > to use a device tree, ever?
> > 
> 
> Tom,
> 
> I am not against using device tree at all. It is more dynamic and flexible. But
> I don't see any indication that we favor device tree over pdata (except in the
> code). If we are skipping pdata for new drivers, a clear message will be
> helpful. That's what I am trying to get clarification.

OK.  I think we'd agreed to that at ELC-E last year and it might have
been in a few here-and-there emails but it's worth spelling out
somewhere.

Hey Simon?  doc/driver-model/README.txt has a pdata example, so maybe
the answer here is it's time to update README.txt in a few ways :)

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150630/3485f1d4/attachment.sig>

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 20:31           ` Tom Rini
@ 2015-06-30 21:08             ` Simon Glass
  2015-07-02  7:03               ` Jagan Teki
  0 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-06-30 21:08 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On 30 June 2015 at 14:31, Tom Rini <trini@konsulko.com> wrote:
> On Tue, Jun 30, 2015 at 01:10:45PM -0700, York Sun wrote:
>>
>>
>> On 06/30/2015 12:01 PM, Tom Rini wrote:
>> > On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
>> >>
>> >>
>> >> On 06/30/2015 11:33 AM, Simon Glass wrote:
>> >>> Hi York,
>> >>>
>> >>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>> >>>> Simon,
>> >>>>
>> >>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>> >>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>> >>>>
>> >>>> My understanding of the driver model is both device tree and platform data are
>> >>>> allowed, like Linux. Is that still true?
>> >>>
>> >>> For buses you need device tree. I was rather hoping that we could
>> >>> avoid platform data on platforms that have device tree. What is the
>> >>> point?
>> >>>
>> >>
>> >> Simon,
>> >>
>> >> It happens on a platform not using device tree, but DM will be used.
>> >>
>> >> I prefer DM to have both, rather than being forced to use device tree, unless we
>> >> are going to enforce using device tree on all new platforms. Since device tree
>> >> is still an option, I feel it is best to support platform data, like Linux
>> >> drivers do.
>> >
>> > Well, to what end?  My recollection is that in short, the kernel has
>> > both since platform data predates device tree (and converting platform
>> > data to device tree is still a thing that happens).  But we're trying to
>> > skip that intermediate step.  Are there platforms where you do not plan
>> > to use a device tree, ever?
>> >
>>
>> Tom,
>>
>> I am not against using device tree at all. It is more dynamic and flexible. But
>> I don't see any indication that we favor device tree over pdata (except in the
>> code). If we are skipping pdata for new drivers, a clear message will be
>> helpful. That's what I am trying to get clarification.
>
> OK.  I think we'd agreed to that at ELC-E last year and it might have
> been in a few here-and-there emails but it's worth spelling out
> somewhere.
>
> Hey Simon?  doc/driver-model/README.txt has a pdata example, so maybe
> the answer here is it's time to update README.txt in a few ways :)

I'll prepare a patch.

Regards,
Simon

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello,

On 06/23/2015 11:38 PM, Simon Glass wrote:
> This is not user input (i.e. from the command line). It should be possible
> to get the case correct and avoid the case-insensitive match. This will
> help avoid sloppy device tree setups.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/pmic/pmic-uclass.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
> index 812ac13..40b5135 100644
> --- a/drivers/power/pmic/pmic-uclass.c
> +++ b/drivers/power/pmic/pmic-uclass.c
> @@ -55,7 +55,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>   		child = NULL;
>   		for (info = child_info; info->prefix && info->driver; info++) {
>   			prefix_len = strlen(info->prefix);
> -			if (strncasecmp(info->prefix, node_name, prefix_len))
> +			if (strncmp(info->prefix, node_name, prefix_len))
>   				continue;
>
>   			debug("  - compatible prefix: '%s'\n", info->prefix);
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:38 PM, Simon Glass wrote:
> Decide when the regulator is set up whether we want to auto-set the voltage
> or current. This avoids the complex logic spilling into the processing code.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/regulator/regulator-uclass.c | 12 ++++++++++++
>   include/power/regulator.h                  |  8 ++++++++
>   2 files changed, 20 insertions(+)
>
> diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
> index 31ffd44..0f1ca77 100644
> --- a/drivers/power/regulator/regulator-uclass.c
> +++ b/drivers/power/regulator/regulator-uclass.c
> @@ -319,6 +319,18 @@ static int regulator_pre_probe(struct udevice *dev)
>   	uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
>   					    "regulator-boot-on");
>
> +	/* Those values are optional (-ENODATA if unset) */
> +	if ((uc_pdata->min_uV != -ENODATA) &&
> +	    (uc_pdata->max_uV != -ENODATA) &&
> +	    (uc_pdata->min_uV == uc_pdata->max_uV))
> +		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
> +
> +	/* Those values are optional (-ENODATA if unset) */
> +	if ((uc_pdata->min_uA != -ENODATA) &&
> +	    (uc_pdata->max_uA != -ENODATA) &&
> +	    (uc_pdata->min_uA == uc_pdata->max_uA))
> +		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
> +
>   	return 0;
>   }
>
> diff --git a/include/power/regulator.h b/include/power/regulator.h
> index 03a2cef..79ce0a4 100644
> --- a/include/power/regulator.h
> +++ b/include/power/regulator.h
> @@ -128,6 +128,11 @@ struct dm_regulator_mode {
>   	const char *name;
>   };
>
> +enum regulator_flag {
> +	REGULATOR_FLAG_AUTOSET_UV	= 1 << 0,
> +	REGULATOR_FLAG_AUTOSET_UA	= 1 << 1,
> +};
> +
>   /**
>    * struct dm_regulator_uclass_platdata - pointed by dev->uclass_platdata, and
>    * allocated on each regulator bind. This structure holds an information
> @@ -143,6 +148,8 @@ struct dm_regulator_mode {
>    * @max_uA*    - maximum amperage (micro Amps)
>    * @always_on* - bool type, true or false
>    * @boot_on*   - bool type, true or false
> + * TODO(sjg at chromium.org): Consider putting the above two into @flags
> + * @flags:     - flags value (see REGULATOR_FLAG_...)
>    * @name**     - fdt regulator name - should be taken from the device tree
>    *
>    * Note:
> @@ -162,6 +169,7 @@ struct dm_regulator_uclass_platdata {
>   	bool always_on;
>   	bool boot_on;
>   	const char *name;
> +	int flags;
>   };
>
>   /* Regulator device operations */
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:38 PM, Simon Glass wrote:
> The regulator_autoset() function mixes printf() output and PMIC adjustment
> code. It provides a boolean to control the output. It is better to avoid
> missing logic and output, and this permits a smaller SPL code size. So
> split the output into a separate function.
>
> Also rename the function to have a by_name() suffix, since we would like
> to be able to pass a device when we know it, and thus avoid the name
> search.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/regulator/regulator-uclass.c | 98 +++++++++++-------------------
>   include/power/regulator.h                  | 34 ++++++++---
>   include/power/sandbox_pmic.h               |  4 +-
>   test/dm/regulator.c                        |  2 +-
>   4 files changed, 63 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
> index 0f1ca77..687d3b1 100644
> --- a/drivers/power/regulator/regulator-uclass.c
> +++ b/drivers/power/regulator/regulator-uclass.c
> @@ -138,87 +138,57 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp)
>   	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
>   }
>
> -static int failed(int ret, bool verbose, const char *fmt, ...)
> +int regulator_autoset(struct udevice *dev)
>   {
> -	va_list args;
> -	char buf[64];
> -
> -	if (verbose == false)
> -		return ret;
> +	struct dm_regulator_uclass_platdata *uc_pdata;
> +	int ret = 0;
>
> -	va_start(args, fmt);
> -	vscnprintf(buf, sizeof(buf), fmt, args);
> -	va_end(args);
> +	uc_pdata = dev_get_uclass_platdata(dev);
> +	if (!uc_pdata->always_on && !uc_pdata->boot_on)
> +		return -EMEDIUMTYPE;
>
> -	printf(buf);
> +	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
> +		ret = regulator_set_value(dev, uc_pdata->min_uV);
> +	if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
> +		ret = regulator_set_current(dev, uc_pdata->min_uA);
>
>   	if (!ret)
> -		return 0;
> -
> -	printf(" (ret: %d)", ret);
> +		ret = regulator_set_enable(dev, true);
>
>   	return ret;
>   }
>
> -int regulator_autoset(const char *platname,
> -		      struct udevice **devp,
> -		      bool verbose)
> +static void regulator_show(struct udevice *dev, int ret)
>   {
>   	struct dm_regulator_uclass_platdata *uc_pdata;
> -	struct udevice *dev;
> -	int ret;
> -
> -	if (devp)
> -		*devp = NULL;
> -
> -	ret = regulator_get_by_platname(platname, &dev);
> -	if (ret) {
> -		error("Can get the regulator: %s!", platname);
> -		return ret;
> -	}
>
>   	uc_pdata = dev_get_uclass_platdata(dev);
> -	if (!uc_pdata) {
> -		error("Can get the regulator %s uclass platdata!", platname);
> -		return -ENXIO;
> -	}
> -
> -	if (!uc_pdata->always_on && !uc_pdata->boot_on)
> -		goto retdev;
>
> -	if (verbose)
> -		printf("%s@%s: ", dev->name, uc_pdata->name);
> -
> -	/* Those values are optional (-ENODATA if unset) */
> -	if ((uc_pdata->min_uV != -ENODATA) &&
> -	    (uc_pdata->max_uV != -ENODATA) &&
> -	    (uc_pdata->min_uV == uc_pdata->max_uV)) {
> -		ret = regulator_set_value(dev, uc_pdata->min_uV);
> -		if (failed(ret, verbose, "set %d uV", uc_pdata->min_uV))
> -			goto exit;
> -	}
> -
> -	/* Those values are optional (-ENODATA if unset) */
> -	if ((uc_pdata->min_uA != -ENODATA) &&
> -	    (uc_pdata->max_uA != -ENODATA) &&
> -	    (uc_pdata->min_uA == uc_pdata->max_uA)) {
> -		ret = regulator_set_current(dev, uc_pdata->min_uA);
> -		if (failed(ret, verbose, "; set %d uA", uc_pdata->min_uA))
> -			goto exit;
> -	}
> +	printf("%s@%s: ", dev->name, uc_pdata->name);
> +	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
> +		printf("set %d uV", uc_pdata->min_uV);
> +	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
> +		printf("; set %d uA", uc_pdata->min_uA);
> +	printf("; enabling");
> +	if (ret)
> +		printf(" (ret: %d)\n", ret);
> +	printf("\n");
> +}
>
> -	ret = regulator_set_enable(dev, true);
> -	if (failed(ret, verbose, "; enabling", uc_pdata->min_uA))
> -		goto exit;
> +int regulator_autoset_by_name(const char *platname, struct udevice **devp)
> +{
> +	struct udevice *dev;
> +	int ret;
>
> -retdev:
> +	ret = regulator_get_by_platname(platname, &dev);
>   	if (devp)
>   		*devp = dev;
> -exit:
> -	if (verbose)
> -		printf("\n");
> +	if (ret) {
> +		debug("Can get the regulator: %s!", platname);
> +		return ret;
> +	}
>
> -	return ret;
> +	return regulator_autoset(dev);
>   }
>
>   int regulator_list_autoset(const char *list_platname[],
> @@ -229,7 +199,9 @@ int regulator_list_autoset(const char *list_platname[],
>   	int error = 0, i = 0, ret;
>
>   	while (list_platname[i]) {
> -		ret = regulator_autoset(list_platname[i], &dev, verbose);
> +		ret = regulator_autoset_by_name(list_platname[i], &dev);
> +		if (ret != -EMEDIUMTYPE && verbose)
> +			regulator_show(dev, ret);
>   		if (ret & !error)
>   			error = ret;
>
> diff --git a/include/power/regulator.h b/include/power/regulator.h
> index 79ce0a4..86e9c3b 100644
> --- a/include/power/regulator.h
> +++ b/include/power/regulator.h
> @@ -316,9 +316,28 @@ int regulator_get_mode(struct udevice *dev);
>   int regulator_set_mode(struct udevice *dev, int mode_id);
>
>   /**
> - * regulator_autoset: setup the regulator given by its uclass's platform data
> - * name field. The setup depends on constraints found in device's uclass's
> - * platform data (struct dm_regulator_uclass_platdata):
> + * regulator_autoset: setup the the voltage/current on a regulator

duplicated "the"

> + *
> + * The setup depends on constraints found in device's uclass's platform data
> + * (struct dm_regulator_uclass_platdata):
> + *
> + * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
> + *   or if both are unset, then the function returns
> + * - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
> + * - Current limit - will set - if '.min_uA' and '.max_uA' values are equal
> + *
> + * The function returns on the first-encountered error.
> + *
> + * @platname - expected string for dm_regulator_uclass_platdata .name field
> + * @devp     - returned pointer to the regulator device - if non-NULL passed
> + * @return: 0 on success or negative value of errno.
> + */
> +int regulator_autoset(struct udevice *dev);
> +
> +/**
> + * regulator_autoset_by_name: setup the regulator given by its uclass's
> + * platform data name field. The setup depends on constraints found in device's
> + * uclass's platform data (struct dm_regulator_uclass_platdata):
>    * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
>    *   or if both are unset, then the function returns
>    * - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
> @@ -328,21 +347,18 @@ int regulator_set_mode(struct udevice *dev, int mode_id);
>    *
>    * @platname - expected string for dm_regulator_uclass_platdata .name field
>    * @devp     - returned pointer to the regulator device - if non-NULL passed
> - * @verbose  - (true/false) print regulator setup info, or be quiet
>    * @return: 0 on success or negative value of errno.
>    *
>    * The returned 'regulator' device can be used with:
>    * - regulator_get/set_*
>    */
> -int regulator_autoset(const char *platname,
> -		      struct udevice **devp,
> -		      bool verbose);
> +int regulator_autoset_by_name(const char *platname, struct udevice **devp);
>
>   /**
>    * regulator_list_autoset: setup the regulators given by list of their uclass's
>    * platform data name field. The setup depends on constraints found in device's
>    * uclass's platform data. The function loops with calls to:
> - * regulator_autoset() for each name from the list.
> + * regulator_autoset_by_name() for each name from the list.
>    *
>    * @list_platname - an array of expected strings for .name field of each
>    *                  regulator's uclass platdata
> @@ -383,7 +399,7 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp);
>    * Search by name, found in regulator uclass platdata.
>    *
>    * @platname - expected string for uc_pdata->name of regulator uclass platdata
> - * @devp     - returned pointer to the regulator device
> + * @devp     - returns pointer to the regulator device or NULL on error
>    * @return 0 on success or negative value of errno.
>    *
>    * The returned 'regulator' device is probed and can be used with:
> diff --git a/include/power/sandbox_pmic.h b/include/power/sandbox_pmic.h
> index ae14292..8547674 100644
> --- a/include/power/sandbox_pmic.h
> +++ b/include/power/sandbox_pmic.h
> @@ -117,11 +117,11 @@ enum {
>
>   /*
>    * Expected regulators setup after call of:
> - * - regulator_autoset()
> + * - regulator_autoset_by_name()
>    * - regulator_list_autoset()
>    */
>
> -/* BUCK1: for testing regulator_autoset() */
> +/* BUCK1: for testing regulator_autoset_by_name() */
>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UV	1200000
>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UA	200000
>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE	true
> diff --git a/test/dm/regulator.c b/test/dm/regulator.c
> index d279c04..3d0056f 100644
> --- a/test/dm/regulator.c
> +++ b/test/dm/regulator.c
> @@ -210,7 +210,7 @@ static int dm_test_power_regulator_autoset(struct unit_test_state *uts)
>   	 * Expected output state: uV=1200000; uA=200000; output enabled
>   	 */
>   	platname = regulator_names[BUCK1][PLATNAME];
> -	ut_assertok(regulator_autoset(platname, &dev_autoset, false));
> +	ut_assertok(regulator_autoset_by_name(platname, &dev_autoset));
>
>   	/* Check, that the returned device is proper */
>   	ut_assertok(regulator_get_by_platname(platname, &dev));
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:38 PM, Simon Glass wrote:
> The device tree provides information about which regulators should be
> on at boot, or always on. Use this to set them up automatically.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/regulator/regulator-uclass.c | 22 ++++++++++++++++++++++
>   include/power/regulator.h                  | 11 +++++++++++
>   2 files changed, 33 insertions(+)
>
> diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
> index 687d3b1..a2d0b9f 100644
> --- a/drivers/power/regulator/regulator-uclass.c
> +++ b/drivers/power/regulator/regulator-uclass.c
> @@ -306,6 +306,28 @@ static int regulator_pre_probe(struct udevice *dev)
>   	return 0;
>   }
>
> +int regulators_enable_boot_on(bool verbose)
> +{
> +	struct udevice *dev;
> +	struct uclass *uc;
> +	int ret;
> +
> +	ret = uclass_get(UCLASS_REGULATOR, &uc);
> +	if (ret)
> +		return ret;
> +	for (uclass_first_device(UCLASS_REGULATOR, &dev);
> +	     dev && !ret;
> +	     uclass_next_device(&dev)) {
> +		ret = regulator_autoset(dev);
> +		if (ret == -EMEDIUMTYPE)
> +			continue;
> +		if (verbose)
> +			regulator_show(dev, ret);
> +	}
> +
> +	return ret;
> +}
> +
>   UCLASS_DRIVER(regulator) = {
>   	.id		= UCLASS_REGULATOR,
>   	.name		= "regulator",
> diff --git a/include/power/regulator.h b/include/power/regulator.h
> index 86e9c3b..0bdb496 100644
> --- a/include/power/regulator.h
> +++ b/include/power/regulator.h
> @@ -316,6 +316,17 @@ int regulator_get_mode(struct udevice *dev);
>   int regulator_set_mode(struct udevice *dev, int mode_id);
>
>   /**
> + * regulators_enable_boot_on() - enable regulators needed for boot
> + *
> + * This enables all regulators which are marked to be on at boot time. This
> + * only works for regulators which don't have a range for voltage/current,
> + * since in that case it is not possible to know which value to use.
> + *
> + * This effectively caslls regulator_autoset() for every regulator.

"calls"

> + */
> +int regulators_enable_boot_on(bool verbose);
> +
> +/**
>    * regulator_autoset: setup the the voltage/current on a regulator
>    *
>    * The setup depends on constraints found in device's uclass's platform data
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:39 PM, Simon Glass wrote:
> To reduce unnecessary code size in an uncommon code path, use debug()
> where possible(). The driver returns an error which indicates failure.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/regulator/regulator-uclass.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
> index a2d0b9f..12e141b 100644
> --- a/drivers/power/regulator/regulator-uclass.c
> +++ b/drivers/power/regulator/regulator-uclass.c
> @@ -262,7 +262,7 @@ static int regulator_post_bind(struct udevice *dev)
>   	if (regulator_name_is_unique(dev, uc_pdata->name))
>   		return 0;
>
> -	error("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
> +	debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
>   	      property, dev->name, uc_pdata->name);
>
>   	return -EINVAL;
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:57     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:39 PM, Simon Glass wrote:
> It is a common requirement to update some PMIC registers. Provide some
> simple convenience functions to do this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>   drivers/power/pmic/pmic-uclass.c | 32 ++++++++++++++++++++++++++++++++
>   include/power/pmic.h             | 34 ++++++++++++++++++++++++++++++++++
>   2 files changed, 66 insertions(+)
>
> diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
> index 40b5135..dbab3e3 100644
> --- a/drivers/power/pmic/pmic-uclass.c
> +++ b/drivers/power/pmic/pmic-uclass.c
> @@ -139,6 +139,38 @@ int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len)
>   	return ops->write(dev, reg, buffer, len);
>   }
>
> +int pmic_reg_read(struct udevice *dev, uint reg)
> +{
> +	u8 byte;
> +	int ret;
> +
> +	ret = pmic_read(dev, reg, &byte, 1);
> +	debug("%s: reg=%x, value=%x\n", __func__, reg, byte);
> +
> +	return ret ? ret : byte;
> +}
> +
> +int pmic_reg_write(struct udevice *dev, uint reg, uint value)
> +{
> +	u8 byte = value;
> +
> +	debug("%s: reg=%x, value=%x\n", __func__, reg, value);
> +	return pmic_read(dev, reg, &byte, 1);
> +}
> +
> +int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
> +{
> +	u8 byte;
> +	int ret;
> +
> +	ret = pmic_reg_read(dev, reg);
> +	if (ret < 0)
> +		return ret;
> +	byte = (ret & ~clr) | set;
> +
> +	return pmic_reg_write(dev, reg, byte);
> +}
> +
>   UCLASS_DRIVER(pmic) = {
>   	.id		= UCLASS_PMIC,
>   	.name		= "pmic",
> diff --git a/include/power/pmic.h b/include/power/pmic.h
> index eb152ef..6ba4b6e 100644
> --- a/include/power/pmic.h
> +++ b/include/power/pmic.h
> @@ -264,6 +264,40 @@ int pmic_reg_count(struct udevice *dev);
>    */
>   int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len);
>   int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len);
> +
> +/**
> + * pmic_reg_read() - read a PMIC register value
> + *
> + * @dev:	PMIC device to read
> + * @reg:	Register to read
> + * @return value read on success or negative value of errno.
> + */
> +int pmic_reg_read(struct udevice *dev, uint reg);
> +
> +/**
> + * pmic_reg_write() - write a PMIC register value
> + *
> + * @dev:	PMIC device to write
> + * @reg:	Register to write
> + * @value:	Value to write
> + * @return 0 on success or negative value of errno.
> + */
> +int pmic_reg_write(struct udevice *dev, uint reg, uint value);
> +
> +/**
> + * pmic_clrsetbits() - clear and set bits in a PMIC register
> + *
> + * This reads a register, optionally clears some bits, optionally sets some
> + * bits, then writes the register.
> + *
> + * @dev:	PMIC device to update
> + * @reg:	Register to update
> + * @clr:	Bit mask to clear (set those bits that you want cleared)
> + * @set:	Bit mask to set (set those bits that you want set)
> + * @return 0 on success or negative value of errno.
> + */
> +int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set);
> +
>   #endif /* CONFIG_DM_PMIC */
>
>   #ifdef CONFIG_POWER
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function Simon Glass
@ 2015-07-01  9:44   ` Przemyslaw Marczak
  2015-07-17 23:58     ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Przemyslaw Marczak @ 2015-07-01  9:44 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On 06/23/2015 11:39 PM, Simon Glass wrote:
> Use the common function to obtain the number from the end of the string,
> instead of a local function. Also tweak the position of a debug() statement.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Split this series apart from the Rockchip series
>
> Changes in v2: None
>
>   drivers/power/pmic/pmic-uclass.c | 23 +++++------------------
>   1 file changed, 5 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
> index dbab3e3..d99cb9a 100644
> --- a/drivers/power/pmic/pmic-uclass.c
> +++ b/drivers/power/pmic/pmic-uclass.c
> @@ -9,6 +9,7 @@
>   #include <fdtdec.h>
>   #include <errno.h>
>   #include <dm.h>
> +#include <vsprintf.h>
>   #include <dm/lists.h>
>   #include <dm/device-internal.h>
>   #include <dm/uclass-internal.h>
> @@ -17,16 +18,6 @@
>
>   DECLARE_GLOBAL_DATA_PTR;
>
> -static ulong str_get_num(const char *ptr, const char *maxptr)
> -{
> -	if (!ptr || !maxptr)
> -		return 0;
> -
> -	while (!isdigit(*ptr) && ptr++ < maxptr);
> -
> -	return simple_strtoul(ptr, NULL, 0);
> -}
> -
>   int pmic_bind_children(struct udevice *pmic, int offset,
>   		       const struct pmic_child_info *child_info)
>   {
> @@ -35,7 +26,6 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>   	struct driver *drv;
>   	struct udevice *child;
>   	const char *node_name;
> -	int node_name_len;
>   	int bind_count = 0;
>   	int node;
>   	int prefix_len;
> @@ -47,19 +37,19 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>   	for (node = fdt_first_subnode(blob, offset);
>   	     node > 0;
>   	     node = fdt_next_subnode(blob, node)) {
> -		node_name = fdt_get_name(blob, node, &node_name_len);
> +		node_name = fdt_get_name(blob, node, NULL);
>
>   		debug("* Found child node: '%s' at offset:%d\n", node_name,
>   								 node);
>
>   		child = NULL;
>   		for (info = child_info; info->prefix && info->driver; info++) {
> +			debug("  - compatible prefix: '%s'\n", info->prefix);
> +
>   			prefix_len = strlen(info->prefix);
>   			if (strncmp(info->prefix, node_name, prefix_len))
>   				continue;
>
> -			debug("  - compatible prefix: '%s'\n", info->prefix);
> -
>   			drv = lists_driver_lookup_name(info->driver);
>   			if (!drv) {
>   				debug("  - driver: '%s' not found!\n",
> @@ -78,10 +68,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>
>   			debug("  - bound child device: '%s'\n", child->name);
>
> -			child->driver_data = str_get_num(node_name +
> -							 prefix_len,
> -							 node_name +
> -							 node_name_len);
> +			child->driver_data = trailing_strtol(node_name);
>
>   			debug("  - set 'child->driver_data': %lu\n",
>   			      child->driver_data);
>

Tested on:
- Odroid U3 (odroid_defconfig)
- Sandbox - ut pmic/regulator

Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-30 21:08             ` Simon Glass
@ 2015-07-02  7:03               ` Jagan Teki
  2015-07-09 20:31                 ` Jagan Teki
  0 siblings, 1 reply; 133+ messages in thread
From: Jagan Teki @ 2015-07-02  7:03 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 02:38, Simon Glass <sjg@chromium.org> wrote:
> Hi Tom,
>
> On 30 June 2015 at 14:31, Tom Rini <trini@konsulko.com> wrote:
>> On Tue, Jun 30, 2015 at 01:10:45PM -0700, York Sun wrote:
>>>
>>>
>>> On 06/30/2015 12:01 PM, Tom Rini wrote:
>>> > On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
>>> >>
>>> >>
>>> >> On 06/30/2015 11:33 AM, Simon Glass wrote:
>>> >>> Hi York,
>>> >>>
>>> >>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>>> >>>> Simon,
>>> >>>>
>>> >>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>>> >>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>> >>>>
>>> >>>> My understanding of the driver model is both device tree and platform data are
>>> >>>> allowed, like Linux. Is that still true?
>>> >>>
>>> >>> For buses you need device tree. I was rather hoping that we could
>>> >>> avoid platform data on platforms that have device tree. What is the
>>> >>> point?
>>> >>>
>>> >>
>>> >> Simon,
>>> >>
>>> >> It happens on a platform not using device tree, but DM will be used.
>>> >>
>>> >> I prefer DM to have both, rather than being forced to use device tree, unless we
>>> >> are going to enforce using device tree on all new platforms. Since device tree
>>> >> is still an option, I feel it is best to support platform data, like Linux
>>> >> drivers do.
>>> >
>>> > Well, to what end?  My recollection is that in short, the kernel has
>>> > both since platform data predates device tree (and converting platform
>>> > data to device tree is still a thing that happens).  But we're trying to
>>> > skip that intermediate step.  Are there platforms where you do not plan
>>> > to use a device tree, ever?

My observations with this approach (dm-spi)

1. We're planning to move spi driver with dm support but many of the
boards which
    used spi drivers don't have dts support yet.
2. I think dm will progress only when dts support progresses.

The only solution for this - if we need to move any driver to dm then check for
dts on particular board this driver uses and move that board to have
dts support.

Any comments?

>>> >
>>>
>>> Tom,
>>>
>>> I am not against using device tree at all. It is more dynamic and flexible. But
>>> I don't see any indication that we favor device tree over pdata (except in the
>>> code). If we are skipping pdata for new drivers, a clear message will be
>>> helpful. That's what I am trying to get clarification.
>>
>> OK.  I think we'd agreed to that at ELC-E last year and it might have
>> been in a few here-and-there emails but it's worth spelling out
>> somewhere.
>>
>> Hey Simon?  doc/driver-model/README.txt has a pdata example, so maybe
>> the answer here is it's time to update README.txt in a few ways :)
>
> I'll prepare a patch.

thanks!
-- 
Jagan | openedev.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
                   ` (54 preceding siblings ...)
  2015-06-30 16:08 ` [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses York Sun
@ 2015-07-03  3:28 ` Simon Glass
  55 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-03  3:28 UTC (permalink / raw)
  To: u-boot

Hi,

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
>
> This series adds several new uclasses. Some of these have been discussed
> for a while. All are fairly simple and just provide enough functionality for
> existing use cases. The following are included in this series:
>
> - Clocks - setting and getting PLL and peripheral clocks
> - Pinctrl - adjusting pin multiplexing settings
> - Reset - reseting the board or SoC
> - RAM - setting up RAM controllers and detecting the available RAM
> - MMC - MMC controllers (using the existing block device framework)
> - LEDs - turning LEDs on and off, with only a GPIO driver so far
>
> Trivial support is also added for regmap and syscon controllers, modelled
> on how the kernel does this.
>
> This builds on the SPL device tree support which was recently added.

I've started up a u-boot-dm/next tree again for the next release. I'm
planning start applying patches from this soon, or at least the ones
that don't need a respin. Please let me know if there are any more
comments. I can still fix things after they are applied (basically
drop patches and start again) but it is easier to get things right
first time.

[snip]

Regards,
Simon

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info()
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info() Simon Glass
@ 2015-07-08 14:10   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-08 14:10 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> This is checking the wrong method. Fix it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/cpu/cpu-uclass.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
> index ab18ee2..ffe250d 100644
> --- a/drivers/cpu/cpu-uclass.c
> +++ b/drivers/cpu/cpu-uclass.c
> @@ -25,7 +25,7 @@ int cpu_get_info(struct udevice *dev, struct cpu_info *info)
>  {
>         struct cpu_ops *ops = cpu_get_ops(dev);
>
> -       if (!ops->get_desc)
> +       if (!ops->get_info)
>                 return -ENOSYS;
>
>         return ops->get_info(dev, info);
> --
> 2.4.3.573.g4eafbef
>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-07-02  7:03               ` Jagan Teki
@ 2015-07-09 20:31                 ` Jagan Teki
  2015-07-09 21:10                   ` Simon Glass
  0 siblings, 1 reply; 133+ messages in thread
From: Jagan Teki @ 2015-07-09 20:31 UTC (permalink / raw)
  To: u-boot

On 2 July 2015 at 12:33, Jagan Teki <jteki@openedev.com> wrote:
> On 1 July 2015 at 02:38, Simon Glass <sjg@chromium.org> wrote:
>> Hi Tom,
>>
>> On 30 June 2015 at 14:31, Tom Rini <trini@konsulko.com> wrote:
>>> On Tue, Jun 30, 2015 at 01:10:45PM -0700, York Sun wrote:
>>>>
>>>>
>>>> On 06/30/2015 12:01 PM, Tom Rini wrote:
>>>> > On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
>>>> >>
>>>> >>
>>>> >> On 06/30/2015 11:33 AM, Simon Glass wrote:
>>>> >>> Hi York,
>>>> >>>
>>>> >>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>>>> >>>> Simon,
>>>> >>>>
>>>> >>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>>>> >>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>>> >>>>
>>>> >>>> My understanding of the driver model is both device tree and platform data are
>>>> >>>> allowed, like Linux. Is that still true?
>>>> >>>
>>>> >>> For buses you need device tree. I was rather hoping that we could
>>>> >>> avoid platform data on platforms that have device tree. What is the
>>>> >>> point?
>>>> >>>
>>>> >>
>>>> >> Simon,
>>>> >>
>>>> >> It happens on a platform not using device tree, but DM will be used.
>>>> >>
>>>> >> I prefer DM to have both, rather than being forced to use device tree, unless we
>>>> >> are going to enforce using device tree on all new platforms. Since device tree
>>>> >> is still an option, I feel it is best to support platform data, like Linux
>>>> >> drivers do.
>>>> >
>>>> > Well, to what end?  My recollection is that in short, the kernel has
>>>> > both since platform data predates device tree (and converting platform
>>>> > data to device tree is still a thing that happens).  But we're trying to
>>>> > skip that intermediate step.  Are there platforms where you do not plan
>>>> > to use a device tree, ever?
>
> My observations with this approach (dm-spi)
>
> 1. We're planning to move spi driver with dm support but many of the
> boards which
>     used spi drivers don't have dts support yet.
> 2. I think dm will progress only when dts support progresses.
>
> The only solution for this - if we need to move any driver to dm then check for
> dts on particular board this driver uses and move that board to have
> dts support.
>
> Any comments?

Any suggestions?

>
>>>> >
>>>>
>>>> Tom,
>>>>
>>>> I am not against using device tree at all. It is more dynamic and flexible. But
>>>> I don't see any indication that we favor device tree over pdata (except in the
>>>> code). If we are skipping pdata for new drivers, a clear message will be
>>>> helpful. That's what I am trying to get clarification.
>>>
>>> OK.  I think we'd agreed to that at ELC-E last year and it might have
>>> been in a few here-and-there emails but it's worth spelling out
>>> somewhere.
>>>
>>> Hey Simon?  doc/driver-model/README.txt has a pdata example, so maybe
>>> the answer here is it's time to update README.txt in a few ways :)
>>
>> I'll prepare a patch.

thanks!
-- 
Jagan | openedev.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses
  2015-07-09 20:31                 ` Jagan Teki
@ 2015-07-09 21:10                   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-09 21:10 UTC (permalink / raw)
  To: u-boot

Hi Jagan,

On 9 July 2015 at 14:31, Jagan Teki <jteki@openedev.com> wrote:
> On 2 July 2015 at 12:33, Jagan Teki <jteki@openedev.com> wrote:
>> On 1 July 2015 at 02:38, Simon Glass <sjg@chromium.org> wrote:
>>> Hi Tom,
>>>
>>> On 30 June 2015 at 14:31, Tom Rini <trini@konsulko.com> wrote:
>>>> On Tue, Jun 30, 2015 at 01:10:45PM -0700, York Sun wrote:
>>>>>
>>>>>
>>>>> On 06/30/2015 12:01 PM, Tom Rini wrote:
>>>>> > On Tue, Jun 30, 2015 at 11:42:41AM -0700, York Sun wrote:
>>>>> >>
>>>>> >>
>>>>> >> On 06/30/2015 11:33 AM, Simon Glass wrote:
>>>>> >>> Hi York,
>>>>> >>>
>>>>> >>> On 30 June 2015 at 10:08, York Sun <yorksun@freescale.com> wrote:
>>>>> >>>> Simon,
>>>>> >>>>
>>>>> >>>> Does the dm force using device tree? I was reviewing a patch set regarding SPI
>>>>> >>>> and found OF_CONTROL has to be selected in order to get the driver model happy.
>>>>> >>>>
>>>>> >>>> My understanding of the driver model is both device tree and platform data are
>>>>> >>>> allowed, like Linux. Is that still true?
>>>>> >>>
>>>>> >>> For buses you need device tree. I was rather hoping that we could
>>>>> >>> avoid platform data on platforms that have device tree. What is the
>>>>> >>> point?
>>>>> >>>
>>>>> >>
>>>>> >> Simon,
>>>>> >>
>>>>> >> It happens on a platform not using device tree, but DM will be used.
>>>>> >>
>>>>> >> I prefer DM to have both, rather than being forced to use device tree, unless we
>>>>> >> are going to enforce using device tree on all new platforms. Since device tree
>>>>> >> is still an option, I feel it is best to support platform data, like Linux
>>>>> >> drivers do.
>>>>> >
>>>>> > Well, to what end?  My recollection is that in short, the kernel has
>>>>> > both since platform data predates device tree (and converting platform
>>>>> > data to device tree is still a thing that happens).  But we're trying to
>>>>> > skip that intermediate step.  Are there platforms where you do not plan
>>>>> > to use a device tree, ever?
>>
>> My observations with this approach (dm-spi)
>>
>> 1. We're planning to move spi driver with dm support but many of the
>> boards which
>>     used spi drivers don't have dts support yet.
>> 2. I think dm will progress only when dts support progresses.
>>
>> The only solution for this - if we need to move any driver to dm then check for
>> dts on particular board this driver uses and move that board to have
>> dts support.
>>
>> Any comments?
>
> Any suggestions?
>

Yes, or maybe enable DTS for the board? It's not that hard. E.g. see
this for Raspberry Pi:

http://patchwork.ozlabs.org/patch/492694/
http://patchwork.ozlabs.org/patch/492698/
http://patchwork.ozlabs.org/patch/492700/

>>
>>>>> >
>>>>>
>>>>> Tom,
>>>>>
>>>>> I am not against using device tree at all. It is more dynamic and flexible. But
>>>>> I don't see any indication that we favor device tree over pdata (except in the
>>>>> code). If we are skipping pdata for new drivers, a clear message will be
>>>>> helpful. That's what I am trying to get clarification.
>>>>
>>>> OK.  I think we'd agreed to that at ELC-E last year and it might have
>>>> been in a few here-and-there emails but it's worth spelling out
>>>> somewhere.
>>>>
>>>> Hey Simon?  doc/driver-model/README.txt has a pdata example, so maybe
>>>> the answer here is it's time to update README.txt in a few ways :)
>>>
>>> I'll prepare a patch.
>
> thanks!
> --
> Jagan | openedev.

Regards,
Simon

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
>
> Drystone provides a convenient sanity check that the CPU is running at full
> speed. Add this as a command which can be enabled as needed.
>
> Note: I investigated using Coremark for this but there was a license
> agreement and I could not work out if it was GPL-compatible.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  lib/Kconfig         |   2 +
>  lib/Makefile        |   2 +
>  lib/dhry/Kconfig    |   7 +
>  lib/dhry/Makefile   |   7 +
>  lib/dhry/cmd_dhry.c |  34 ++++
>  lib/dhry/dhry.h     | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/dhry/dhry_1.c   | 421 +++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/dhry/dhry_2.c   | 217 ++++++++++++++++++++++++++
>  8 files changed, 1132 insertions(+)
>  create mode 100644 lib/dhry/Kconfig
>  create mode 100644 lib/dhry/Makefile
>  create mode 100644 lib/dhry/cmd_dhry.c
>  create mode 100644 lib/dhry/dhry.h
>  create mode 100644 lib/dhry/dhry_1.c
>  create mode 100644 lib/dhry/dhry_2.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Provide access to the dhrystone benchmark command.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  configs/sandbox_defconfig | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Offer to display the available image types in help. Also, rather than
> hacking the genimg_get_type_id() function to display a list of types,
> do this in the tool. Also, sort the list.
>
> The list of image types is quite long, and hard to discover. Print it out
> when we show help information.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Use case-insensitve compare for image params (fixes build break with m53evk)
>
> Changes in v2: None
>
>  common/image.c  | 58 +++++++++++++++++++++++++++++++-------------------------
>  include/image.h | 11 +++++++++++
>  tools/mkimage.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
>  3 files changed, 95 insertions(+), 33 deletions(-)

Applied to u-boot-dm.

(If people have time to test this out it would be great!)

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Property names are stored in a string table. When a node property is
> removed, the string table is not updated since other nodes may have a
> property with the same name.
>
> Thus it is possible for the string table to build up a number of unused
> strings. Add a function to remove these. This works by building a new device
> tree from the old one, adding strings one by one as needed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Fix indentation in function comment
>
> Changes in v2:
> - Add new patch to remove unused strings from a device tree
>
>  include/libfdt.h    | 17 +++++++++++++++++
>  lib/libfdt/fdt_rw.c | 32 ++++++++++++++++++++++++++++++++
>  2 files changed, 49 insertions(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> These have been sent upstream but not accepted to libfdt. For now, bring
> these into U-Boot to enable fdtgrep to operate. We will use fdtgrep to
> cut device tree files down for SPL.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add new patch with fdt_first/next_region() functions
> - Tidy up commit message a little
>
>  include/libfdt.h        | 239 ++++++++++++++++++++++-
>  lib/libfdt/Makefile     |   2 +-
>  lib/libfdt/fdt_region.c | 492 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 731 insertions(+), 2 deletions(-)
>  create mode 100644 lib/libfdt/fdt_region.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> This tool allows us to extract subsets of a device tree file. It is used by
> the SPL vuild, which needs to cut down the device tree size for use in
> limited memory.
>
> This tool was originally written for libfdt but it has not been accepted
> upstream, so for now, include it in U-Boot. Several utilfdt library
> functions been included inline here.
>
> If fdtgrep is eventually accepted in libfdt then we can bring that version
> of libfdt in here, and drop fdtgrep (requiring that fdtgrep is provided by
> the user).
>
> If it is not accepted then another approach would be to write a special
> tool for chopping down device tree files for SPL. While it would use the
> same libfdt support, it would be less code than fdtgrep.c because it would
> not have general-purpose functions.
>
> Another approach (which was used with v1 of this series) is to sprinkler all
> the device tree files with #ifdef. I don't like that idea.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add new patch with fdtgrep tool
>
>  tools/Makefile  |    6 +-
>  tools/fdtgrep.c | 1234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 1239 insertions(+), 1 deletion(-)
>  create mode 100644 tools/fdtgrep.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> The SPL device tree size must be minimised to save memory. Only include
> properties that are needed by SPL - this is determined by the presence
> of the "u-boot,dm-pre-reloc" property. Also remove a predefined list of
> unused properties from the nodes that remain.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Convert hex number to upper case to keep bc happy
>
> Changes in v2:
> - Add new patch to reduce SPL device tree size with fdtgrep
>
>  Makefile                    |  2 +-
>  arch/arm/cpu/u-boot-spl.lds |  2 +-
>  dts/Kconfig                 | 12 ++++++++++++
>  scripts/Makefile.spl        | 28 ++++++++++++++++++++++++++++
>  4 files changed, 42 insertions(+), 2 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Driver-model I2C drivers can be picked up by the linker script rule for
> legacy drivers. Change the order to avoid this.
>
> We could make the legacy code depend on !CONFIG_DM_I2C but that is not
> necessary and it is good to keep conditions to a minimum.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/cpu/u-boot-spl.lds | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> U-Boot uses structures for hardware access so it is important that these
> structures are correct. Add a way of asserting that a structure member is
> at a particular offset. This can be created using the datasheet for the
> hardware.
>
> This implementation uses Static_assert() since BUILD_BUG_ON() only works
> within functions.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  include/common.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> This does not actually help any current arch. For x86 it makes it harder
> to call (requires stack) and for ARM it has no effect. Drop it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  include/debug_uart.h | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> When there is no console ready, allow the debug UART to be used for output.
> This makes debugging of early code considerably easier.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/console.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> At present printf() skips output if it can see there is no console. This
> is really just an optimisation, and is not necessary. Also it is currently
> incorrect in some cases. Rather than update the logic, just remove it so
> that we don't need to keep it in sync.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/console.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> In SPL it is sometimes useful to be able to obtain a dump of the current
> driver model state. Since commands are not available, provide a way to
> directly call the functions to output this information.
>
> Adjust the existing commands to use these functions.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/Makefile |  1 +
>  drivers/core/dump.c   | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/util.h     |  6 ++++
>  test/dm/cmd_dm.c      | 82 ++-----------------------------------------
>  4 files changed, 106 insertions(+), 79 deletions(-)
>  create mode 100644 drivers/core/dump.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> To avoid bloating SPL code, use debug() where possible in the driver model
> core code. The error code is already returned, and can be investigated as
> needed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/lists.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> In some rare cases it is useful to be able to locate a device given a device
> tree node offset. An example is when you have an alias that points to a node
> and you want to find the associated device. The device may be SPI, MMC or
> something else, but you don't need to know the uclass to find it.
>
> Add a function to do a global search for a device, given its device tree
> offset.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/device.c | 25 +++++++++++++++++++++++++
>  include/dm/device.h   | 14 ++++++++++++++
>  2 files changed, 39 insertions(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> This parameter is named 'seq' but should be named 'of_offset'.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/device.c | 4 ++--
>  include/dm/device.h   | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Provide a driver-model function to look up a GPIO name. Make the standard
> function use it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/gpio/gpio-uclass.c | 34 ++++++++++++++++++++++++++--------
>  include/asm-generic/gpio.h | 13 +++++++++++++
>  2 files changed, 39 insertions(+), 8 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Now that we support driver model in SPL, allow GPIO drivers to be used there
> also.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/gpio/Makefile | 4 ----
>  1 file changed, 4 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> This function can be used for testing to manually request a GPIO for use,
> without resorting to the legacy GPIO API.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/gpio/gpio-uclass.c |  2 +-
>  include/asm-generic/gpio.h | 12 ++++++++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap) Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Add a simple implementaton of register maps, supporting only direct I/O
> for now. This can be enhanced later to support buses which have registers,
> such as I2C, SPI and PCI.
>
> It allows drivers which can operate with multiple buses to avoid dealing
> with the particulars of register access on that bus.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/Makefile |  1 +
>  drivers/core/regmap.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/regmap.h      | 72 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 159 insertions(+)
>  create mode 100644 drivers/core/regmap.c
>  create mode 100644 include/regmap.h

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon)
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon) Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Many SoCs have a number of system controllers which are dealt with as a
> group by a single driver. It is a pain to have to add lots of compatible
> strings and/or separate drivers for each. Instead we can identify the
> controllers by a number and request the address of the one we want.
>
> Add a simple implementation of this which can be used by SoC driver code.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/Makefile        |  1 +
>  drivers/core/syscon-uclass.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h       |  1 +
>  include/syscon.h             | 56 +++++++++++++++++++++++++++++++++
>  4 files changed, 131 insertions(+)
>  create mode 100644 drivers/core/syscon-uclass.c
>  create mode 100644 include/syscon.h

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs Simon Glass
@ 2015-07-17 23:56   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:56 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Add a simple uclass for LEDs, so that these can be controlled by the device
> tree and activated when needed. LEDs are referred to by their label.
>
> This implementation requires a driver for each type of LED (e.g GPIO, I2C).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  doc/device-tree-bindings/leds/common.txt | 23 ++++++++++++++
>  drivers/Kconfig                          |  2 ++
>  drivers/Makefile                         |  1 +
>  drivers/led/Kconfig                      | 17 +++++++++++
>  drivers/led/Makefile                     |  8 +++++
>  drivers/led/led-uclass.c                 | 48 ++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h                   |  1 +
>  include/led.h                            | 51 ++++++++++++++++++++++++++++++++
>  scripts/Makefile.spl                     |  1 +
>  9 files changed, 152 insertions(+)
>  create mode 100644 doc/device-tree-bindings/leds/common.txt
>  create mode 100644 drivers/led/Kconfig
>  create mode 100644 drivers/led/Makefile
>  create mode 100644 drivers/led/led-uclass.c
>  create mode 100644 include/led.h

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Add a simple driver which allows use of LEDs attached to GPIOs. The linux
> device tree binding is used.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  doc/device-tree-bindings/leds/leds-gpio.txt |  52 ++++++++++++++
>  drivers/led/Kconfig                         |   9 +++
>  drivers/led/Makefile                        |   1 +
>  drivers/led/led_gpio.c                      | 101 ++++++++++++++++++++++++++++
>  4 files changed, 163 insertions(+)
>  create mode 100644 doc/device-tree-bindings/leds/leds-gpio.txt
>  create mode 100644 drivers/led/led_gpio.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Add a few messages to indicate progress and failure.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/spl/spl_mmc.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Add basic support for MMC, providing a uclass which can set up an MMC
> device. This allows MMC drivers to move to using driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/Kconfig      | 10 ++++++++++
>  drivers/mmc/Makefile     |  2 ++
>  drivers/mmc/mmc-uclass.c | 34 ++++++++++++++++++++++++++++++++++
>  drivers/mmc/mmc.c        |  2 ++
>  include/dm/uclass-id.h   |  1 +
>  include/mmc.h            | 22 ++++++++++++++++++++++
>  6 files changed, 71 insertions(+)
>  create mode 100644 drivers/mmc/mmc-uclass.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Enable MMC using driver model in SPL for consistency with U-Boot proper.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/spl/spl_mmc.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> Allow read errors to be diagnosed more easily.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/mmc.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc
  2015-06-23 21:38 ` [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:38, Simon Glass <sjg@chromium.org> wrote:
> It took a little while to figure this out, so this patch adds documentation
> to help the next person who needs to do this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  include/dwmmc.h | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello,
>
> On 06/23/2015 11:38 PM, Simon Glass wrote:
>>
>> This is not user input (i.e. from the command line). It should be possible
>> to get the case correct and avoid the case-insensitive match. This will
>> help avoid sloppy device tree setups.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/pmic/pmic-uclass.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/power/pmic/pmic-uclass.c
>> b/drivers/power/pmic/pmic-uclass.c
>> index 812ac13..40b5135 100644
>> --- a/drivers/power/pmic/pmic-uclass.c
>> +++ b/drivers/power/pmic/pmic-uclass.c
>> @@ -55,7 +55,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>>                 child = NULL;
>>                 for (info = child_info; info->prefix && info->driver;
>> info++) {
>>                         prefix_len = strlen(info->prefix);
>> -                       if (strncasecmp(info->prefix, node_name,
>> prefix_len))
>> +                       if (strncmp(info->prefix, node_name, prefix_len))
>>                                 continue;
>>
>>                         debug("  - compatible prefix: '%s'\n",
>> info->prefix);
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>

Thanks for all the testing and review!

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:38 PM, Simon Glass wrote:
>>
>> Decide when the regulator is set up whether we want to auto-set the
>> voltage
>> or current. This avoids the complex logic spilling into the processing
>> code.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/regulator/regulator-uclass.c | 12 ++++++++++++
>>   include/power/regulator.h                  |  8 ++++++++
>>   2 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/power/regulator/regulator-uclass.c
>> b/drivers/power/regulator/regulator-uclass.c
>> index 31ffd44..0f1ca77 100644
>> --- a/drivers/power/regulator/regulator-uclass.c
>> +++ b/drivers/power/regulator/regulator-uclass.c
>> @@ -319,6 +319,18 @@ static int regulator_pre_probe(struct udevice *dev)
>>         uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
>>                                             "regulator-boot-on");
>>
>> +       /* Those values are optional (-ENODATA if unset) */
>> +       if ((uc_pdata->min_uV != -ENODATA) &&
>> +           (uc_pdata->max_uV != -ENODATA) &&
>> +           (uc_pdata->min_uV == uc_pdata->max_uV))
>> +               uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
>> +
>> +       /* Those values are optional (-ENODATA if unset) */
>> +       if ((uc_pdata->min_uA != -ENODATA) &&
>> +           (uc_pdata->max_uA != -ENODATA) &&
>> +           (uc_pdata->min_uA == uc_pdata->max_uA))
>> +               uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
>> +
>>         return 0;
>>   }
>>
>> diff --git a/include/power/regulator.h b/include/power/regulator.h
>> index 03a2cef..79ce0a4 100644
>> --- a/include/power/regulator.h
>> +++ b/include/power/regulator.h
>> @@ -128,6 +128,11 @@ struct dm_regulator_mode {
>>         const char *name;
>>   };
>>
>> +enum regulator_flag {
>> +       REGULATOR_FLAG_AUTOSET_UV       = 1 << 0,
>> +       REGULATOR_FLAG_AUTOSET_UA       = 1 << 1,
>> +};
>> +
>>   /**
>>    * struct dm_regulator_uclass_platdata - pointed by
>> dev->uclass_platdata, and
>>    * allocated on each regulator bind. This structure holds an information
>> @@ -143,6 +148,8 @@ struct dm_regulator_mode {
>>    * @max_uA*    - maximum amperage (micro Amps)
>>    * @always_on* - bool type, true or false
>>    * @boot_on*   - bool type, true or false
>> + * TODO(sjg at chromium.org): Consider putting the above two into @flags
>> + * @flags:     - flags value (see REGULATOR_FLAG_...)
>>    * @name**     - fdt regulator name - should be taken from the device
>> tree
>>    *
>>    * Note:
>> @@ -162,6 +169,7 @@ struct dm_regulator_uclass_platdata {
>>         bool always_on;
>>         bool boot_on;
>>         const char *name;
>> +       int flags;
>>   };
>>
>>   /* Regulator device operations */
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:38 PM, Simon Glass wrote:
>>
>> The regulator_autoset() function mixes printf() output and PMIC adjustment
>> code. It provides a boolean to control the output. It is better to avoid
>> missing logic and output, and this permits a smaller SPL code size. So
>> split the output into a separate function.
>>
>> Also rename the function to have a by_name() suffix, since we would like
>> to be able to pass a device when we know it, and thus avoid the name
>> search.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/regulator/regulator-uclass.c | 98
>> +++++++++++-------------------
>>   include/power/regulator.h                  | 34 ++++++++---
>>   include/power/sandbox_pmic.h               |  4 +-
>>   test/dm/regulator.c                        |  2 +-
>>   4 files changed, 63 insertions(+), 75 deletions(-)
>>
>> diff --git a/drivers/power/regulator/regulator-uclass.c
>> b/drivers/power/regulator/regulator-uclass.c
>> index 0f1ca77..687d3b1 100644
>> --- a/drivers/power/regulator/regulator-uclass.c
>> +++ b/drivers/power/regulator/regulator-uclass.c
>> @@ -138,87 +138,57 @@ int regulator_get_by_devname(const char *devname,
>> struct udevice **devp)
>>         return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
>>   }
>>
>> -static int failed(int ret, bool verbose, const char *fmt, ...)
>> +int regulator_autoset(struct udevice *dev)
>>   {
>> -       va_list args;
>> -       char buf[64];
>> -
>> -       if (verbose == false)
>> -               return ret;
>> +       struct dm_regulator_uclass_platdata *uc_pdata;
>> +       int ret = 0;
>>
>> -       va_start(args, fmt);
>> -       vscnprintf(buf, sizeof(buf), fmt, args);
>> -       va_end(args);
>> +       uc_pdata = dev_get_uclass_platdata(dev);
>> +       if (!uc_pdata->always_on && !uc_pdata->boot_on)
>> +               return -EMEDIUMTYPE;
>>
>> -       printf(buf);
>> +       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
>> +               ret = regulator_set_value(dev, uc_pdata->min_uV);
>> +       if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
>> +               ret = regulator_set_current(dev, uc_pdata->min_uA);
>>
>>         if (!ret)
>> -               return 0;
>> -
>> -       printf(" (ret: %d)", ret);
>> +               ret = regulator_set_enable(dev, true);
>>
>>         return ret;
>>   }
>>
>> -int regulator_autoset(const char *platname,
>> -                     struct udevice **devp,
>> -                     bool verbose)
>> +static void regulator_show(struct udevice *dev, int ret)
>>   {
>>         struct dm_regulator_uclass_platdata *uc_pdata;
>> -       struct udevice *dev;
>> -       int ret;
>> -
>> -       if (devp)
>> -               *devp = NULL;
>> -
>> -       ret = regulator_get_by_platname(platname, &dev);
>> -       if (ret) {
>> -               error("Can get the regulator: %s!", platname);
>> -               return ret;
>> -       }
>>
>>         uc_pdata = dev_get_uclass_platdata(dev);
>> -       if (!uc_pdata) {
>> -               error("Can get the regulator %s uclass platdata!",
>> platname);
>> -               return -ENXIO;
>> -       }
>> -
>> -       if (!uc_pdata->always_on && !uc_pdata->boot_on)
>> -               goto retdev;
>>
>> -       if (verbose)
>> -               printf("%s@%s: ", dev->name, uc_pdata->name);
>> -
>> -       /* Those values are optional (-ENODATA if unset) */
>> -       if ((uc_pdata->min_uV != -ENODATA) &&
>> -           (uc_pdata->max_uV != -ENODATA) &&
>> -           (uc_pdata->min_uV == uc_pdata->max_uV)) {
>> -               ret = regulator_set_value(dev, uc_pdata->min_uV);
>> -               if (failed(ret, verbose, "set %d uV", uc_pdata->min_uV))
>> -                       goto exit;
>> -       }
>> -
>> -       /* Those values are optional (-ENODATA if unset) */
>> -       if ((uc_pdata->min_uA != -ENODATA) &&
>> -           (uc_pdata->max_uA != -ENODATA) &&
>> -           (uc_pdata->min_uA == uc_pdata->max_uA)) {
>> -               ret = regulator_set_current(dev, uc_pdata->min_uA);
>> -               if (failed(ret, verbose, "; set %d uA", uc_pdata->min_uA))
>> -                       goto exit;
>> -       }
>> +       printf("%s@%s: ", dev->name, uc_pdata->name);
>> +       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
>> +               printf("set %d uV", uc_pdata->min_uV);
>> +       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
>> +               printf("; set %d uA", uc_pdata->min_uA);
>> +       printf("; enabling");
>> +       if (ret)
>> +               printf(" (ret: %d)\n", ret);
>> +       printf("\n");
>> +}
>>
>> -       ret = regulator_set_enable(dev, true);
>> -       if (failed(ret, verbose, "; enabling", uc_pdata->min_uA))
>> -               goto exit;
>> +int regulator_autoset_by_name(const char *platname, struct udevice
>> **devp)
>> +{
>> +       struct udevice *dev;
>> +       int ret;
>>
>> -retdev:
>> +       ret = regulator_get_by_platname(platname, &dev);
>>         if (devp)
>>                 *devp = dev;
>> -exit:
>> -       if (verbose)
>> -               printf("\n");
>> +       if (ret) {
>> +               debug("Can get the regulator: %s!", platname);
>> +               return ret;
>> +       }
>>
>> -       return ret;
>> +       return regulator_autoset(dev);
>>   }
>>
>>   int regulator_list_autoset(const char *list_platname[],
>> @@ -229,7 +199,9 @@ int regulator_list_autoset(const char
>> *list_platname[],
>>         int error = 0, i = 0, ret;
>>
>>         while (list_platname[i]) {
>> -               ret = regulator_autoset(list_platname[i], &dev, verbose);
>> +               ret = regulator_autoset_by_name(list_platname[i], &dev);
>> +               if (ret != -EMEDIUMTYPE && verbose)
>> +                       regulator_show(dev, ret);
>>                 if (ret & !error)
>>                         error = ret;
>>
>> diff --git a/include/power/regulator.h b/include/power/regulator.h
>> index 79ce0a4..86e9c3b 100644
>> --- a/include/power/regulator.h
>> +++ b/include/power/regulator.h
>> @@ -316,9 +316,28 @@ int regulator_get_mode(struct udevice *dev);
>>   int regulator_set_mode(struct udevice *dev, int mode_id);
>>
>>   /**
>> - * regulator_autoset: setup the regulator given by its uclass's platform
>> data
>> - * name field. The setup depends on constraints found in device's
>> uclass's
>> - * platform data (struct dm_regulator_uclass_platdata):
>> + * regulator_autoset: setup the the voltage/current on a regulator
>
>
> duplicated "the"
>
>
>> + *
>> + * The setup depends on constraints found in device's uclass's platform
>> data
>> + * (struct dm_regulator_uclass_platdata):
>> + *
>> + * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to
>> true,
>> + *   or if both are unset, then the function returns
>> + * - Voltage value - will set - if '.min_uV' and '.max_uV' values are
>> equal
>> + * - Current limit - will set - if '.min_uA' and '.max_uA' values are
>> equal
>> + *
>> + * The function returns on the first-encountered error.
>> + *
>> + * @platname - expected string for dm_regulator_uclass_platdata .name
>> field
>> + * @devp     - returned pointer to the regulator device - if non-NULL
>> passed
>> + * @return: 0 on success or negative value of errno.
>> + */
>> +int regulator_autoset(struct udevice *dev);
>> +
>> +/**
>> + * regulator_autoset_by_name: setup the regulator given by its uclass's
>> + * platform data name field. The setup depends on constraints found in
>> device's
>> + * uclass's platform data (struct dm_regulator_uclass_platdata):
>>    * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to
>> true,
>>    *   or if both are unset, then the function returns
>>    * - Voltage value - will set - if '.min_uV' and '.max_uV' values are
>> equal
>> @@ -328,21 +347,18 @@ int regulator_set_mode(struct udevice *dev, int
>> mode_id);
>>    *
>>    * @platname - expected string for dm_regulator_uclass_platdata .name
>> field
>>    * @devp     - returned pointer to the regulator device - if non-NULL
>> passed
>> - * @verbose  - (true/false) print regulator setup info, or be quiet
>>    * @return: 0 on success or negative value of errno.
>>    *
>>    * The returned 'regulator' device can be used with:
>>    * - regulator_get/set_*
>>    */
>> -int regulator_autoset(const char *platname,
>> -                     struct udevice **devp,
>> -                     bool verbose);
>> +int regulator_autoset_by_name(const char *platname, struct udevice
>> **devp);
>>
>>   /**
>>    * regulator_list_autoset: setup the regulators given by list of their
>> uclass's
>>    * platform data name field. The setup depends on constraints found in
>> device's
>>    * uclass's platform data. The function loops with calls to:
>> - * regulator_autoset() for each name from the list.
>> + * regulator_autoset_by_name() for each name from the list.
>>    *
>>    * @list_platname - an array of expected strings for .name field of each
>>    *                  regulator's uclass platdata
>> @@ -383,7 +399,7 @@ int regulator_get_by_devname(const char *devname,
>> struct udevice **devp);
>>    * Search by name, found in regulator uclass platdata.
>>    *
>>    * @platname - expected string for uc_pdata->name of regulator uclass
>> platdata
>> - * @devp     - returned pointer to the regulator device
>> + * @devp     - returns pointer to the regulator device or NULL on error
>>    * @return 0 on success or negative value of errno.
>>    *
>>    * The returned 'regulator' device is probed and can be used with:
>> diff --git a/include/power/sandbox_pmic.h b/include/power/sandbox_pmic.h
>> index ae14292..8547674 100644
>> --- a/include/power/sandbox_pmic.h
>> +++ b/include/power/sandbox_pmic.h
>> @@ -117,11 +117,11 @@ enum {
>>
>>   /*
>>    * Expected regulators setup after call of:
>> - * - regulator_autoset()
>> + * - regulator_autoset_by_name()
>>    * - regulator_list_autoset()
>>    */
>>
>> -/* BUCK1: for testing regulator_autoset() */
>> +/* BUCK1: for testing regulator_autoset_by_name() */
>>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UV     1200000
>>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UA     200000
>>   #define SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE true
>> diff --git a/test/dm/regulator.c b/test/dm/regulator.c
>> index d279c04..3d0056f 100644
>> --- a/test/dm/regulator.c
>> +++ b/test/dm/regulator.c
>> @@ -210,7 +210,7 @@ static int dm_test_power_regulator_autoset(struct
>> unit_test_state *uts)
>>          * Expected output state: uV=1200000; uA=200000; output enabled
>>          */
>>         platname = regulator_names[BUCK1][PLATNAME];
>> -       ut_assertok(regulator_autoset(platname, &dev_autoset, false));
>> +       ut_assertok(regulator_autoset_by_name(platname, &dev_autoset));
>>
>>         /* Check, that the returned device is proper */
>>         ut_assertok(regulator_get_by_platname(platname, &dev));
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:38 PM, Simon Glass wrote:
>>
>> The device tree provides information about which regulators should be
>> on at boot, or always on. Use this to set them up automatically.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/regulator/regulator-uclass.c | 22 ++++++++++++++++++++++
>>   include/power/regulator.h                  | 11 +++++++++++
>>   2 files changed, 33 insertions(+)
>>
>> diff --git a/drivers/power/regulator/regulator-uclass.c
>> b/drivers/power/regulator/regulator-uclass.c
>> index 687d3b1..a2d0b9f 100644
>> --- a/drivers/power/regulator/regulator-uclass.c
>> +++ b/drivers/power/regulator/regulator-uclass.c
>> @@ -306,6 +306,28 @@ static int regulator_pre_probe(struct udevice *dev)
>>         return 0;
>>   }
>>
>> +int regulators_enable_boot_on(bool verbose)
>> +{
>> +       struct udevice *dev;
>> +       struct uclass *uc;
>> +       int ret;
>> +
>> +       ret = uclass_get(UCLASS_REGULATOR, &uc);
>> +       if (ret)
>> +               return ret;
>> +       for (uclass_first_device(UCLASS_REGULATOR, &dev);
>> +            dev && !ret;
>> +            uclass_next_device(&dev)) {
>> +               ret = regulator_autoset(dev);
>> +               if (ret == -EMEDIUMTYPE)
>> +                       continue;
>> +               if (verbose)
>> +                       regulator_show(dev, ret);
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>>   UCLASS_DRIVER(regulator) = {
>>         .id             = UCLASS_REGULATOR,
>>         .name           = "regulator",
>> diff --git a/include/power/regulator.h b/include/power/regulator.h
>> index 86e9c3b..0bdb496 100644
>> --- a/include/power/regulator.h
>> +++ b/include/power/regulator.h
>> @@ -316,6 +316,17 @@ int regulator_get_mode(struct udevice *dev);
>>   int regulator_set_mode(struct udevice *dev, int mode_id);
>>
>>   /**
>> + * regulators_enable_boot_on() - enable regulators needed for boot
>> + *
>> + * This enables all regulators which are marked to be on at boot time.
>> This
>> + * only works for regulators which don't have a range for
>> voltage/current,
>> + * since in that case it is not possible to know which value to use.
>> + *
>> + * This effectively caslls regulator_autoset() for every regulator.
>
>
> "calls"
>
>> + */
>> +int regulators_enable_boot_on(bool verbose);
>> +
>> +/**
>>    * regulator_autoset: setup the the voltage/current on a regulator
>>    *
>>    * The setup depends on constraints found in device's uclass's platform
>> data
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:39 PM, Simon Glass wrote:
>>
>> To reduce unnecessary code size in an uncommon code path, use debug()
>> where possible(). The driver returns an error which indicates failure.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/regulator/regulator-uclass.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/power/regulator/regulator-uclass.c
>> b/drivers/power/regulator/regulator-uclass.c
>> index a2d0b9f..12e141b 100644
>> --- a/drivers/power/regulator/regulator-uclass.c
>> +++ b/drivers/power/regulator/regulator-uclass.c
>> @@ -262,7 +262,7 @@ static int regulator_post_bind(struct udevice *dev)
>>         if (regulator_name_is_unique(dev, uc_pdata->name))
>>                 return 0;
>>
>> -       error("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
>> +       debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
>>               property, dev->name, uc_pdata->name);
>>
>>         return -EINVAL;
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:57     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:39 PM, Simon Glass wrote:
>>
>> It is a common requirement to update some PMIC registers. Provide some
>> simple convenience functions to do this.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   drivers/power/pmic/pmic-uclass.c | 32 ++++++++++++++++++++++++++++++++
>>   include/power/pmic.h             | 34 ++++++++++++++++++++++++++++++++++
>>   2 files changed, 66 insertions(+)
>>
>> diff --git a/drivers/power/pmic/pmic-uclass.c
>> b/drivers/power/pmic/pmic-uclass.c
>> index 40b5135..dbab3e3 100644
>> --- a/drivers/power/pmic/pmic-uclass.c
>> +++ b/drivers/power/pmic/pmic-uclass.c
>> @@ -139,6 +139,38 @@ int pmic_write(struct udevice *dev, uint reg, const
>> uint8_t *buffer, int len)
>>         return ops->write(dev, reg, buffer, len);
>>   }
>>
>> +int pmic_reg_read(struct udevice *dev, uint reg)
>> +{
>> +       u8 byte;
>> +       int ret;
>> +
>> +       ret = pmic_read(dev, reg, &byte, 1);
>> +       debug("%s: reg=%x, value=%x\n", __func__, reg, byte);
>> +
>> +       return ret ? ret : byte;
>> +}
>> +
>> +int pmic_reg_write(struct udevice *dev, uint reg, uint value)
>> +{
>> +       u8 byte = value;
>> +
>> +       debug("%s: reg=%x, value=%x\n", __func__, reg, value);
>> +       return pmic_read(dev, reg, &byte, 1);
>> +}
>> +
>> +int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
>> +{
>> +       u8 byte;
>> +       int ret;
>> +
>> +       ret = pmic_reg_read(dev, reg);
>> +       if (ret < 0)
>> +               return ret;
>> +       byte = (ret & ~clr) | set;
>> +
>> +       return pmic_reg_write(dev, reg, byte);
>> +}
>> +
>>   UCLASS_DRIVER(pmic) = {
>>         .id             = UCLASS_PMIC,
>>         .name           = "pmic",
>> diff --git a/include/power/pmic.h b/include/power/pmic.h
>> index eb152ef..6ba4b6e 100644
>> --- a/include/power/pmic.h
>> +++ b/include/power/pmic.h
>> @@ -264,6 +264,40 @@ int pmic_reg_count(struct udevice *dev);
>>    */
>>   int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len);
>>   int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int
>> len);
>> +
>> +/**
>> + * pmic_reg_read() - read a PMIC register value
>> + *
>> + * @dev:       PMIC device to read
>> + * @reg:       Register to read
>> + * @return value read on success or negative value of errno.
>> + */
>> +int pmic_reg_read(struct udevice *dev, uint reg);
>> +
>> +/**
>> + * pmic_reg_write() - write a PMIC register value
>> + *
>> + * @dev:       PMIC device to write
>> + * @reg:       Register to write
>> + * @value:     Value to write
>> + * @return 0 on success or negative value of errno.
>> + */
>> +int pmic_reg_write(struct udevice *dev, uint reg, uint value);
>> +
>> +/**
>> + * pmic_clrsetbits() - clear and set bits in a PMIC register
>> + *
>> + * This reads a register, optionally clears some bits, optionally sets
>> some
>> + * bits, then writes the register.
>> + *
>> + * @dev:       PMIC device to update
>> + * @reg:       Register to update
>> + * @clr:       Bit mask to clear (set those bits that you want cleared)
>> + * @set:       Bit mask to set (set those bits that you want set)
>> + * @return 0 on success or negative value of errno.
>> + */
>> +int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set);
>> +
>>   #endif /* CONFIG_DM_PMIC */
>>
>>   #ifdef CONFIG_POWER
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> his functionality may be useful for setting up regulators early during
> boot.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  scripts/Makefile.spl | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> This bloats the code size quite a bit and is less useful in SPL where there
> is no command line.
>
> Avoid including this code in SPL.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  lib/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Add support for a driver which sets up DRAM and can return information about
> the amount of RAM available. This is a first step towards moving RAM init
> to driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/Kconfig          |  2 ++
>  drivers/Makefile         |  1 +
>  drivers/ram/Kconfig      | 18 ++++++++++++++++++
>  drivers/ram/Makefile     |  7 +++++++
>  drivers/ram/ram-uclass.c | 28 ++++++++++++++++++++++++++++
>  include/dm/uclass-id.h   |  1 +
>  include/ram.h            | 38 ++++++++++++++++++++++++++++++++++++++
>  scripts/Makefile.spl     |  1 +
>  8 files changed, 96 insertions(+)
>  create mode 100644 drivers/ram/Kconfig
>  create mode 100644 drivers/ram/Makefile
>  create mode 100644 drivers/ram/ram-uclass.c
>  create mode 100644 include/ram.h

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Several functions in this file should be marked as static. Update them.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/spi/spi-uclass.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Since Rockchip requires 32-bit serial access, add this to the driver.
> Refactor a little to make this easier.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/serial/ns16550.c | 36 +++++++++++++++++++++---------------
>  1 file changed, 21 insertions(+), 15 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation Simon Glass
@ 2015-07-17 23:57   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:57 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Add an implementation of RC4. This will be used by Rockchip booting but may
> be useful in other situations.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  include/rc4.h | 21 +++++++++++++++++++++
>  lib/Makefile  |  1 +
>  lib/rc4.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 71 insertions(+)
>  create mode 100644 include/rc4.h
>  create mode 100644 lib/rc4.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Split out the code in fdtdec which finds a number at the end of a string. It
> can be useful in other situations.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  include/vsprintf.h | 26 ++++++++++++++++++++++++++
>  lib/fdtdec.c       | 14 ++++++--------
>  lib/vsprintf.c     | 19 +++++++++++++++++++
>  3 files changed, 51 insertions(+), 8 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> It can be quite confusing with a new platform to figure out why the device
> tree cannot be located. Add some debug information for this case.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  lib/fdtdec.c | 7 +++++++
>  1 file changed, 7 insertions(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f()
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f() Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Add an spl_init() function that does basic init such that board_init_f() can
> use simple malloc(), device tree and driver model. Each one is set up only
> if enabled for SPL.
>
> Note: We really should refactor SPL such that there is a single
> board_init_f() and rename the existing weak board_init_f() functions
> provided by boards, calling them from the single board_init_f().
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/spl/spl.c                  | 35 ++++++++++++++++++++++++-----------
>  include/asm-generic/global_data.h |  1 +
>  include/spl.h                     | 12 ++++++++++++
>  3 files changed, 37 insertions(+), 11 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> As a debug option, add positive confirmation that SPL has completed
> execution. This can help with diagnosing the location of unexpected hangs.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/spl/spl.c | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated
  2015-06-25 22:51   ` Joe Hershberger
@ 2015-07-17 23:58     ` Simon Glass
  2015-08-10 23:43       ` Marek Vasut
  0 siblings, 1 reply; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 25 June 2015 at 16:51, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Tue, Jun 23, 2015 at 4:39 PM, Simon Glass <sjg@chromium.org> wrote:
>> Some functions called by mkimage would like to know the output file size.
>> Initially this is the same as the input file size, but it may be affected by
>> adding headers, etc.
>>
>> Add this information to the image parameters.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>
> Acked-by: Joe Hershberger <joe.hershberger@ni.com>

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> It is common for system reset to be available at multiple levels in modern
> hardware. For example, an SoC may provide a reset option, and a board may
> provide its own reset for reasons of security or thoroughness. It is useful
> to be able to model this hardware without hard-coding the behaviour in the
> SoC or board. Also there is a distinction sometimes between resetting just
> the CPU (leaving GPIO state alone) and resetting all the PMICs, just cutting
> power.
>
> To achieve this, add a simple system reset uclass. It allows multiple devices
> to provide reset functionality and provides a way to walk through them,
> requesting a particular reset type until is it provided.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/misc/Kconfig        |  9 +++++++
>  drivers/misc/Makefile       |  1 +
>  drivers/misc/reset-uclass.c | 62 +++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h      |  1 +
>  include/reset.h             | 62 +++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 135 insertions(+)
>  create mode 100644 drivers/misc/reset-uclass.c
>  create mode 100644 include/reset.h

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Since we want clk_ops to be used in U-Boot as a whole, rename the Zynq
> version until it can be converted to driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/mach-zynq/clk.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass
  2015-06-23 21:39 ` [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass Simon Glass
@ 2015-07-17 23:58   ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 23 June 2015 at 15:39, Simon Glass <sjg@chromium.org> wrote:
> Clocks are an important feature of platforms and have become increasing
> complex with time. Most modern SoCs have multiple PLLs and dozens of clock
> dividers which distribute clocks to on-chip peripherals.
>
> Some SoC implementations have a clock API which is private to that SoC family,
> e.g. Tegra and Exynos. This is useful but it would be better to have a
> common API that can be understood and used throughout U-Boot.
>
> Add a simple clock API as a starting point. It supports querying and setting
> the rate of a clock. Each clock is a device. To reduce memory and processing
> overhead the concept of peripheral clocks is provided. These do not need to
> be explicit devices - it is possible to write a driver that can adjust the
> I2C clock (for example) without an explicit I2C clock device. This can
> dramatically reduce the number of devices (and associated overhead) in a
> complex SoC.
>
> Clocks are referenced by a number, and it is expected that SoCs will define
> that numbering themselves via an enum.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/Kconfig          |  2 ++
>  drivers/Makefile         |  1 +
>  drivers/clk/Kconfig      | 19 ++++++++++++
>  drivers/clk/Makefile     |  8 +++++
>  drivers/clk/clk-uclass.c | 58 +++++++++++++++++++++++++++++++++++
>  include/clk.h            | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h   |  1 +
>  scripts/Makefile.spl     |  1 +
>  8 files changed, 170 insertions(+)
>  create mode 100644 drivers/clk/Kconfig
>  create mode 100644 drivers/clk/Makefile
>  create mode 100644 drivers/clk/clk-uclass.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function
  2015-07-01  9:44   ` Przemyslaw Marczak
@ 2015-07-17 23:58     ` Simon Glass
  0 siblings, 0 replies; 133+ messages in thread
From: Simon Glass @ 2015-07-17 23:58 UTC (permalink / raw)
  To: u-boot

On 1 July 2015 at 03:44, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
> Hello Simon,
>
> On 06/23/2015 11:39 PM, Simon Glass wrote:
>>
>> Use the common function to obtain the number from the end of the string,
>> instead of a local function. Also tweak the position of a debug()
>> statement.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> ---
>>
>> Changes in v3:
>> - Split this series apart from the Rockchip series
>>
>> Changes in v2: None
>>
>>   drivers/power/pmic/pmic-uclass.c | 23 +++++------------------
>>   1 file changed, 5 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/power/pmic/pmic-uclass.c
>> b/drivers/power/pmic/pmic-uclass.c
>> index dbab3e3..d99cb9a 100644
>> --- a/drivers/power/pmic/pmic-uclass.c
>> +++ b/drivers/power/pmic/pmic-uclass.c
>> @@ -9,6 +9,7 @@
>>   #include <fdtdec.h>
>>   #include <errno.h>
>>   #include <dm.h>
>> +#include <vsprintf.h>
>>   #include <dm/lists.h>
>>   #include <dm/device-internal.h>
>>   #include <dm/uclass-internal.h>
>> @@ -17,16 +18,6 @@
>>
>>   DECLARE_GLOBAL_DATA_PTR;
>>
>> -static ulong str_get_num(const char *ptr, const char *maxptr)
>> -{
>> -       if (!ptr || !maxptr)
>> -               return 0;
>> -
>> -       while (!isdigit(*ptr) && ptr++ < maxptr);
>> -
>> -       return simple_strtoul(ptr, NULL, 0);
>> -}
>> -
>>   int pmic_bind_children(struct udevice *pmic, int offset,
>>                        const struct pmic_child_info *child_info)
>>   {
>> @@ -35,7 +26,6 @@ int pmic_bind_children(struct udevice *pmic, int offset,
>>         struct driver *drv;
>>         struct udevice *child;
>>         const char *node_name;
>> -       int node_name_len;
>>         int bind_count = 0;
>>         int node;
>>         int prefix_len;
>> @@ -47,19 +37,19 @@ int pmic_bind_children(struct udevice *pmic, int
>> offset,
>>         for (node = fdt_first_subnode(blob, offset);
>>              node > 0;
>>              node = fdt_next_subnode(blob, node)) {
>> -               node_name = fdt_get_name(blob, node, &node_name_len);
>> +               node_name = fdt_get_name(blob, node, NULL);
>>
>>                 debug("* Found child node: '%s' at offset:%d\n",
>> node_name,
>>                                                                  node);
>>
>>                 child = NULL;
>>                 for (info = child_info; info->prefix && info->driver;
>> info++) {
>> +                       debug("  - compatible prefix: '%s'\n",
>> info->prefix);
>> +
>>                         prefix_len = strlen(info->prefix);
>>                         if (strncmp(info->prefix, node_name, prefix_len))
>>                                 continue;
>>
>> -                       debug("  - compatible prefix: '%s'\n",
>> info->prefix);
>> -
>>                         drv = lists_driver_lookup_name(info->driver);
>>                         if (!drv) {
>>                                 debug("  - driver: '%s' not found!\n",
>> @@ -78,10 +68,7 @@ int pmic_bind_children(struct udevice *pmic, int
>> offset,
>>
>>                         debug("  - bound child device: '%s'\n",
>> child->name);
>>
>> -                       child->driver_data = str_get_num(node_name +
>> -                                                        prefix_len,
>> -                                                        node_name +
>> -                                                        node_name_len);
>> +                       child->driver_data = trailing_strtol(node_name);
>>
>>                         debug("  - set 'child->driver_data': %lu\n",
>>                               child->driver_data);
>>
>
> Tested on:
> - Odroid U3 (odroid_defconfig)
> - Sandbox - ut pmic/regulator
>
> Tested-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
>
> Best regards,
> --
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak at samsung.com

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated
  2015-07-17 23:58     ` Simon Glass
@ 2015-08-10 23:43       ` Marek Vasut
  2015-08-11  1:10         ` Marek Vasut
  0 siblings, 1 reply; 133+ messages in thread
From: Marek Vasut @ 2015-08-10 23:43 UTC (permalink / raw)
  To: u-boot

On Saturday, July 18, 2015 at 01:58:09 AM, Simon Glass wrote:
> On 25 June 2015 at 16:51, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> > Hi Simon,
> > 
> > On Tue, Jun 23, 2015 at 4:39 PM, Simon Glass <sjg@chromium.org> wrote:
> >> Some functions called by mkimage would like to know the output file
> >> size. Initially this is the same as the input file size, but it may be
> >> affected by adding headers, etc.
> >> 
> >> Add this information to the image parameters.
> >> 
> >> Signed-off-by: Simon Glass <sjg@chromium.org>
> >> ---
> > 
> > Acked-by: Joe Hershberger <joe.hershberger@ni.com>
> 
> Applied to u-boot-dm.

Hi,

This breaks all i.MX23 and i.MX28 boards, try building for example the
mx28evk board, u-boot.sb target:

$ make mx28evk_defconfig
$ make u-boot.sb
[...]
  LD      spl/lib/built-in.o
  LDS     spl/u-boot-spl.lds
  LD      spl/u-boot-spl
  OBJCOPY spl/u-boot-spl.bin
  CFG     spl/u-boot-spl.cfg
  MKIMAGE u-boot.sb
./tools/mkimage: Can't open (null): Bad address
arch/arm/cpu/arm926ejs/mxs/Makefile:82: recipe for target 'u-boot.sb' failed
make[1]: *** [u-boot.sb] Error 1
Makefile:989: recipe for target 'u-boot.sb' failed
make: *** [u-boot.sb] Error 2

Shall I look into it or do you already have a patch ? :)

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated
  2015-08-10 23:43       ` Marek Vasut
@ 2015-08-11  1:10         ` Marek Vasut
  0 siblings, 0 replies; 133+ messages in thread
From: Marek Vasut @ 2015-08-11  1:10 UTC (permalink / raw)
  To: u-boot

On Tuesday, August 11, 2015 at 01:43:05 AM, Marek Vasut wrote:
> On Saturday, July 18, 2015 at 01:58:09 AM, Simon Glass wrote:
> > On 25 June 2015 at 16:51, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> > > Hi Simon,
> > > 
> > > On Tue, Jun 23, 2015 at 4:39 PM, Simon Glass <sjg@chromium.org> wrote:
> > >> Some functions called by mkimage would like to know the output file
> > >> size. Initially this is the same as the input file size, but it may be
> > >> affected by adding headers, etc.
> > >> 
> > >> Add this information to the image parameters.
> > >> 
> > >> Signed-off-by: Simon Glass <sjg@chromium.org>
> > >> ---
> > > 
> > > Acked-by: Joe Hershberger <joe.hershberger@ni.com>
> > 
> > Applied to u-boot-dm.
> 
> Hi,
> 
> This breaks all i.MX23 and i.MX28 boards, try building for example the
> mx28evk board, u-boot.sb target:
> 
> $ make mx28evk_defconfig
> $ make u-boot.sb
> [...]
>   LD      spl/lib/built-in.o
>   LDS     spl/u-boot-spl.lds
>   LD      spl/u-boot-spl
>   OBJCOPY spl/u-boot-spl.bin
>   CFG     spl/u-boot-spl.cfg
>   MKIMAGE u-boot.sb
> ./tools/mkimage: Can't open (null): Bad address
> arch/arm/cpu/arm926ejs/mxs/Makefile:82: recipe for target 'u-boot.sb'
> failed make[1]: *** [u-boot.sb] Error 1
> Makefile:989: recipe for target 'u-boot.sb' failed
> make: *** [u-boot.sb] Error 2
> 
> Shall I look into it or do you already have a patch ? :)

Patch is out and the patch is most certainly correct.

On the other hand, is my understanding correct that this patch makes passing
the -d option to mkimage mandatory ? It was optional before this patch I 
believe.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 133+ messages in thread

end of thread, other threads:[~2015-08-11  1:10 UTC | newest]

Thread overview: 133+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-23 21:38 [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 01/54] Add a dhrystone benchmark command Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 02/54] sandbox: Enable dhry command Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 03/54] mkimage: Display a better list of available image types Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 04/54] fdt: Add a function to remove unused strings from a device tree Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 05/54] fdt: Add fdt_first/next_region() functions Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 06/54] fdt: Add fdtgrep tool Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 07/54] dm: Reduce SPL device tree size Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 08/54] dm: arm: Put driver model I2C drivers before legacy ones Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 09/54] Add a way of checking the position of a structure member Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 10/54] debug_uart: Remove use of asmlinkage Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 11/54] dm: Allow debug UART to support an early console Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 12/54] sandbox: Drop special-case sandbox console code Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 13/54] dm: Move the tree/uclass dump code into its own file Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 14/54] dm: core: Use debug() instead of printf() for failures Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 15/54] dm: core: Add a function to find any device from device tree Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 16/54] dm: core: Correct device_get_child_by_of_offset() parameter Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 17/54] dm: gpio: Allow GPIO uclass to be used in SPL Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 18/54] dm: gpio: Add dm_gpio_lookup_name() to look up a GPIO name Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 19/54] dm: gpio: Add dm_gpio_request() to manually request a GPIO Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 20/54] dm: Add support for register maps (regmap) Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 21/54] dm: Add support for generic system controllers (syscon) Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 22/54] dm: Correct the missing method check in cpu_get_info() Simon Glass
2015-07-08 14:10   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 23/54] dm: Add support for LEDs Simon Glass
2015-07-17 23:56   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 24/54] dm: led: Add a driver for GPIO-controlled LEDs Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 25/54] spl: Add debugging info for spl_mmc boot Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 26/54] dm: mmc: Add an MMC uclass Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 27/54] mmc: Avoid using printf() for errors Simon Glass
2015-06-24  1:56   ` Chen-Yu Tsai
2015-06-23 21:38 ` [U-Boot] [PATCH v3 28/54] mmc: Add debug() output on read errors Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 29/54] dm: mmc: Allow driver model to be used for MMC in SPL Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 30/54] mmc: Add structure comments for dwmmc Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 31/54] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
2015-06-24  1:50   ` Chen-Yu Tsai
2015-06-25  1:58   ` Jaehoon Chung
2015-06-23 21:38 ` [U-Boot] [PATCH v3 32/54] mmc: Calculate dwmmc FIFO threshold size if not provided Simon Glass
2015-06-25  1:58   ` Jaehoon Chung
2015-06-25 19:26     ` Simon Glass
2015-06-26  4:49       ` Jaehoon Chung
2015-06-23 21:38 ` [U-Boot] [PATCH v3 33/54] dm: Add basic support for pin multiplexing (pinctrl) Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 34/54] dm: power: Avoid case-insensitve match for child names Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 35/54] dm: power: Add regulator flags to centralise auto-set logic Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 36/54] dm: pmic: Split output from function Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:38 ` [U-Boot] [PATCH v3 37/54] dm: power: Add a function to set up all regulators Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 38/54] dm: power: Use debug() for errors in regulator uclass Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 39/54] dm: pmic: Add functions to adjust PMIC registers Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:57     ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 40/54] dm: power: Allow use of regulators in SPL Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 41/54] Drop CONFIG_ERRNO_STR from SPL Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 42/54] dm: Add support for RAM drivers Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 43/54] dm: spi: Make local functions static Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 44/54] ns16550: Improve debug UART so it can work with 32-bit access Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 45/54] Add rivest cipher 4 (rc4) implementation Simon Glass
2015-07-17 23:57   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 46/54] lib: Add function to extract a number from the end of a string Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 47/54] fdt: Provide debug info when a device tree cannot be found Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 48/54] dm: spl: Allow device tree/driver model in board_init_f() Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 49/54] spl: Add a debug string before the jump to U-Boot Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 50/54] mkimage: Set up a file size parameter and keep it updated Simon Glass
2015-06-25 22:51   ` Joe Hershberger
2015-07-17 23:58     ` Simon Glass
2015-08-10 23:43       ` Marek Vasut
2015-08-11  1:10         ` Marek Vasut
2015-06-23 21:39 ` [U-Boot] [PATCH v3 51/54] dm: Add a system reset uclass Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 52/54] zynq: Rename struct clk_ops to zynq_clk_ops Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 53/54] dm: Add a clock uclass Simon Glass
2015-07-17 23:58   ` Simon Glass
2015-06-23 21:39 ` [U-Boot] [PATCH v3 54/54] power: pmic: Use trailing_strtol() instead of a local function Simon Glass
2015-07-01  9:44   ` Przemyslaw Marczak
2015-07-17 23:58     ` Simon Glass
2015-06-30 16:08 ` [U-Boot] [PATCH v3 00/54] dm: Introduce new driver model uclasses York Sun
2015-06-30 18:33   ` Simon Glass
2015-06-30 18:42     ` York Sun
2015-06-30 19:01       ` Tom Rini
2015-06-30 20:10         ` York Sun
2015-06-30 20:31           ` Tom Rini
2015-06-30 21:08             ` Simon Glass
2015-07-02  7:03               ` Jagan Teki
2015-07-09 20:31                 ` Jagan Teki
2015-07-09 21:10                   ` Simon Glass
2015-06-30 19:01       ` Jagan Teki
2015-07-03  3:28 ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.