[PATCH] spi: omap3_spi: Fix speed and mode selection

2020-11-28 Thread Vignesh Raghavendra
McSPI IP provides per CS specific speed and mode selection. Therefore it
is possible to apply these settings only after CS is known. But
set_speed and set_mode can be called without bus being claimed, this
would lead driver to set up wrong CS (or previously used CS).

Fix this by apply set_speed and set_mode only if bus is already claimed.

Signed-off-by: Vignesh Raghavendra 
---
 drivers/spi/omap3_spi.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 56cb217486..fe73362945 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -37,6 +37,8 @@ struct omap3_spi_priv {
unsigned int mode;
unsigned int wordlen;
unsigned int pin_dir:1;
+
+   bool bus_claimed;
 };
 
 static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val)
@@ -372,6 +374,8 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv 
*priv)
conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
 
writel(conf, >regs->modulctrl);
+
+   priv->bus_claimed = true;
 }
 
 static int omap3_spi_claim_bus(struct udevice *dev)
@@ -381,9 +385,12 @@ static int omap3_spi_claim_bus(struct udevice *dev)
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 
priv->cs = slave_plat->cs;
-   priv->freq = slave_plat->max_hz;
+   if (!priv->freq)
+   priv->freq = slave_plat->max_hz;
 
_omap3_spi_claim_bus(priv);
+   _omap3_spi_set_speed(priv);
+   _omap3_spi_set_mode(priv);
 
return 0;
 }
@@ -395,6 +402,8 @@ static int omap3_spi_release_bus(struct udevice *dev)
 
writel(OMAP3_MCSPI_MODULCTRL_MS, >regs->modulctrl);
 
+   priv->bus_claimed = false;
+
return 0;
 }
 
@@ -440,7 +449,8 @@ static int omap3_spi_set_speed(struct udevice *dev, 
unsigned int speed)
struct omap3_spi_priv *priv = dev_get_priv(dev);
 
priv->freq = speed;
-   _omap3_spi_set_speed(priv);
+   if (priv->bus_claimed)
+   _omap3_spi_set_speed(priv);
 
return 0;
 }
@@ -451,7 +461,8 @@ static int omap3_spi_set_mode(struct udevice *dev, uint 
mode)
 
priv->mode = mode;
 
-   _omap3_spi_set_mode(priv);
+   if (priv->bus_claimed)
+   _omap3_spi_set_mode(priv);
 
return 0;
 }
-- 
2.29.2



Re: [PATCH 2/3] efi_loader: Introduce eventlog support for TCG2_PROTOCOL

2020-11-28 Thread Heinrich Schuchardt

On 11/27/20 5:29 PM, Ilias Apalodimas wrote:

In the previous patches we only introduced a minimal subset of the
EFI_TCG2_PROTOCOL protocol implementing GetCapability().
So let's continue adding features to it, introducing the
GetEventLog() and HashLogExtendEvent() functions.

In order to do that we first need to construct the eventlog in memory,
specifically in EFI_BOOT_SERVICES_DATA memory and a configuration table
from EFI_ACPI_MEMORY_NVS.
U-Boot won't currently add any events to the log or measure any
components, but will expose the necessary EFI APIs for applications
to do so.

Signed-off-by: Ilias Apalodimas 
---
  include/efi_api.h  |   4 +
  include/efi_tcg2.h |  48 +++-
  lib/efi_loader/efi_setup.c |  12 +-
  lib/efi_loader/efi_tcg2.c  | 554 +++--
  4 files changed, 594 insertions(+), 24 deletions(-)

diff --git a/include/efi_api.h b/include/efi_api.h
index 5744f6aed86d..364c578a3b1b 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -356,6 +356,10 @@ struct efi_runtime_services {
EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, \
 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)

+#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID \
+   EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, \
+0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
+
  struct efi_configuration_table {
efi_guid_t guid;
void *table;
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 86b8fe4c01af..6de86156ac4d 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -17,6 +17,8 @@

  /* TPMV2 only */
  #define TCG2_EVENT_LOG_FORMAT_TCG_2 0x0002
+#define EFI_TCG2_EXTEND_ONLY 0x0001
+#define PE_COFF_IMAGE 0x0010

  /* Algorithm Registry */
  #define EFI_TCG2_BOOT_HASH_ALG_SHA10x0001
@@ -25,6 +27,15 @@
  #define EFI_TCG2_BOOT_HASH_ALG_SHA512  0x0008
  #define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x0010

+#define TPM2_SHA1_DIGEST_SIZE 20
+#define TPM2_SHA256_DIGEST_SIZE 32
+#define TPM2_SHA384_DIGEST_SIZE 48
+#define TPM2_SHA512_DIGEST_SIZE 64


lib/efi_loader/efi_tcg2.c already includes tpm-v2.h.

Why should we define the same constant twice?

Best regards

Heinrich


+
+#define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
+
+#define TPM2_EVENT_LOG_SIZE 4096


What does this size derive from? A comment describing the constant could
help.


+
  typedef u32 efi_tcg_event_log_bitmap;
  typedef u32 efi_tcg_event_log_format;
  typedef u32 efi_tcg_event_algorithm_bitmap;
@@ -65,6 +76,40 @@ struct efi_tcg2_boot_service_capability {
sizeof(struct efi_tcg2_boot_service_capability) - \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)

+#define tcg_efi_spec_id_event_signature_03 "Spec ID Event03"
+
+#define tcg_efi_spec_id_event_spec_version_major_tpm2 2
+#define tcg_efi_spec_id_event_spec_version_minor_tpm2 0
+#define tcg_efi_spec_id_event_spec_version_errata_tpm2 0


Constants should be capitalized.


+


Please, provide Sphinx style comments for structures. Cf.
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#structure-union-and-enumeration-documentation


+struct tcg_efi_spec_id_event_algorithm_size {
+   u16  algorithm_id;
+   u16  digest_size;
+} __packed;
+
+struct tcg_efi_spec_id_event {
+   u8 signature[16];
+   u32 platform_class;
+   u8 spec_version_minor;
+   u8 spec_version_major;
+   u8 spec_errata;
+   u8 uintn_size;
+   u32 number_of_algorithms;
+   struct tcg_efi_spec_id_event_algorithm_size 
digest_sizes[TPM2_NUM_PCR_BANKS];
+   u8 vendor_info_size;
+   /*
+* filled in with vendor_info_size
+* currently vendor_info_size = 0


%s/vendor_info_size = 0/U-Boot does not provide any vendor info/


+*/
+   u8 vendor_info[];
+} __packed;
+
+struct efi_tcg2_final_events_table {
+   u64 version;
+   u64 number_of_events;
+   struct tcg_pcr_event2 event[];
+};
+
  struct efi_tcg2_protocol {
efi_status_t (EFIAPI * get_capability)(struct efi_tcg2_protocol *this,
   struct 
efi_tcg2_boot_service_capability *capability);
@@ -73,7 +118,8 @@ struct efi_tcg2_protocol {
 u64 *event_log_location, u64 
*event_log_last_entry,
 bool *event_log_truncated);
efi_status_t (EFIAPI * hash_log_extend_event)(struct efi_tcg2_protocol 
*this,
- u64 flags, u64 
data_to_hash,
+ u64 flags,
+ efi_physical_addr_t 
data_to_hash,
  u64 data_to_hash_len,
  struct efi_tcg2_event 
*efi_tcg_event);
efi_status_t (EFIAPI * submit_command)(struct efi_tcg2_protocol *this,
diff --git 

Re: [PATCH 1/3] tpm: Add tpm2 headers for TCG2 eventlog support

2020-11-28 Thread Heinrich Schuchardt

On 11/27/20 5:29 PM, Ilias Apalodimas wrote:

A following patch introduces support for the EFI_TCG2_PROTOCOL
evenlog management.


%s/evenlog/eventlog/


Introduce the necessary tpm related headers

Signed-off-by: Ilias Apalodimas 
---
  include/tpm-v2.h | 59 
  1 file changed, 59 insertions(+)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index d8c9feda28dc..9637f9be998e 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -18,6 +18,12 @@

  #define TPM2_DIGEST_LEN   32


Shouldn't TPM2_DIGEST_LEN be renamed to TPM2_SHA256_DIGEST_SIZE in all
of our code?



+#define TPM2_SHA1_DIGEST_SIZE 20
+#define TPM2_SHA256_DIGEST_SIZE32
+#define TPM2_SHA384_DIGEST_SIZE48
+#define TPM2_SHA512_DIGEST_SIZE64
+#define TPM2_SM3_256_DIGEST_SIZE 32
+
  #define TPM2_MAX_PCRS 32
  #define TPM2_PCR_SELECT_MAX ((TPM2_MAX_PCRS + 7) / 8)
  #define TPM2_MAX_CAP_BUFFER 1024
@@ -45,6 +51,15 @@
  #define TPM2_PT_MAX_COMMAND_SIZE  (u32)(TPM2_PT_FIXED + 30)
  #define TPM2_PT_MAX_RESPONSE_SIZE (u32)(TPM2_PT_FIXED + 31)

+/* event types */
+#define EV_POST_CODE   ((u32)0x0001)
+#define EV_NO_ACTION   ((u32)0x0003)
+#define EV_SEPARATOR   ((u32)0x0004)
+#define EV_S_CRTM_CONTENTS ((u32)0x0007)
+#define EV_S_CRTM_VERSION  ((u32)0x0008)
+#define EV_CPU_MICROCODE   ((u32)0x0009)
+#define EV_TABLE_OF_DEVICES((u32)0x000B)
+
  /* TPMS_TAGGED_PROPERTY Structure */
  struct tpms_tagged_property {
u32 property;
@@ -86,6 +101,50 @@ struct tpms_capability_data {
union tpmu_capabilities data;
  } __packed;

+/* defined as TPM_SHA1_160_HASH_LEN in spec */
+struct tpm_digest {
+   u8 digest[TPM2_SHA1_DIGEST_SIZE];
+} __packed;
+
+/* SHA1 Event Log Entry Format */


Please, use Sphinx style comments for structures. This allows us to add
them to the HTML documentation. See

https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#structure-union-and-enumeration-documentation

I would appreciate member descriptions, too.


+struct tcg_pcr_event {
+   u32 pcr_index;
+   u32 event_type;
+   struct tpm_digest digest;


struct tpm_digest is only used here in your patch series.

The standard has

typedef UINT8 TCG_DIGEST[TPM2_SHA1_DIGEST_SIZE];

Can't we simply write

u8 digest[20];

here and get rid of struct tpm_digest?

Otherwise looks ok to me.

Best regards

Heinrich


+   u32 event_size;
+   u8 event[];
+} __packed;
+
+/* Definition of TPMU_HA Union */
+union tmpu_ha {
+   u8 sha1[TPM2_SHA1_DIGEST_SIZE];
+   u8 sha256[TPM2_SHA256_DIGEST_SIZE];
+   u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
+   u8 sha384[TPM2_SHA384_DIGEST_SIZE];
+   u8 sha512[TPM2_SHA512_DIGEST_SIZE];
+} __packed;
+
+/* Definition of TPMT_HA Structure */
+struct tpmt_ha {
+   u16 hash_alg;
+   union tmpu_ha digest;
+} __packed;
+
+/* Definition of TPML_DIGEST_VALUES Structure */
+struct tpml_digest_values {
+   u32 count;
+   struct tpmt_ha digests[TPM2_NUM_PCR_BANKS];
+} __packed;
+
+/* Crypto Agile Log Entry Format */
+struct tcg_pcr_event2 {
+   u32 pcr_index;
+   u32 event_type;
+   struct tpml_digest_values digests;
+   u32 event_size;
+   u8 event[];
+} __packed;
+
  /**
   * TPM2 Structure Tags for command/response buffers.
   *





Re: [PATCH v9 08/11] tools: add mkeficapsule command for UEFI capsule update

2020-11-28 Thread Heinrich Schuchardt

On 11/27/20 3:22 PM, Heinrich Schuchardt wrote:

Am 25. November 2020 08:32:08 MEZ schrieb AKASHI Takahiro 
:

Heinrich,

On Wed, Nov 25, 2020 at 07:42:31AM +0100, Heinrich Schuchardt wrote:

Am 25. November 2020 02:05:06 MEZ schrieb AKASHI Takahiro

:

Heinrich,

On Tue, Nov 24, 2020 at 09:23:50PM +0100, Heinrich Schuchardt wrote:

On 11/17/20 1:28 AM, AKASHI Takahiro wrote:

This is a utility mainly for test purpose.
mkeficapsule -f: create a test capsule file for FIT image

firmware


Having said that, you will be able to customize the code to fit
your specific requirements for your platform.

Signed-off-by: AKASHI Takahiro 
---
   tools/Makefile   |   2 +
   tools/mkeficapsule.c | 238

+++

   2 files changed, 240 insertions(+)
   create mode 100644 tools/mkeficapsule.c

diff --git a/tools/Makefile b/tools/Makefile
index 51123fd92983..66d9376803e3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -218,6 +218,8 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs
   hostprogs-$(CONFIG_ASN1_COMPILER)+= asn1_compiler
   HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include

+hostprogs-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += mkeficapsule
+
   # 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/mkeficapsule.c b/tools/mkeficapsule.c
new file mode 100644
index ..db95426457cc
--- /dev/null
+++ b/tools/mkeficapsule.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 Linaro Limited
+ * Author: AKASHI Takahiro
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+typedef __u8 u8;
+typedef __u16 u16;
+typedef __u32 u32;
+typedef __u64 u64;
+typedef __s16 s16;
+typedef __s32 s32;
+
+#define aligned_u64 __aligned_u64
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+#include 
+#include 
+
+static const char *tool_name = "mkeficapsule";
+
+efi_guid_t efi_guid_fm_capsule =

EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;

+efi_guid_t efi_guid_image_type_uboot_fit =
+   EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID;
+efi_guid_t efi_guid_image_type_uboot_raw =
+   EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID;
+
+static struct option options[] = {
+   {"fit", required_argument, NULL, 'f'},
+   {"raw", required_argument, NULL, 'r'},
+   {"index", required_argument, NULL, 'i'},
+   {"instance", required_argument, NULL, 'I'},
+   {"version", required_argument, NULL, 'v'},
+   {"help", no_argument, NULL, 'h'},
+   {NULL, 0, NULL, 0},
+};
+
+static void print_usage(void)
+{
+   printf("Usage: %s [options] \n"
+  "Options:\n"
+  "\t--fit   new FIT image file\n"
+  "\t--raw   new raw image file\n"
+  "\t--index update image index\n"
+  "\t--instance   update hardware instance\n"
+  "\t--version firmware version\n"
+  "\t--help print a help message\n",
+  tool_name);
+}
+
+static int create_fwbin(char *path, char *bin, efi_guid_t

*guid,

+   unsigned long version, unsigned long index,
+   unsigned long instance)
+{
+   struct efi_capsule_header header;
+   struct efi_firmware_management_capsule_header capsule;
+   struct efi_firmware_management_capsule_image_header image;
+   FILE *f, *g;
+   struct stat bin_stat;
+   u8 *data;
+   size_t size;
+
+#ifdef DEBUG
+   printf("For output: %s\n", path);
+   printf("\tbin: %s\n\ttype: %pUl\n" bin, guid);
+   printf("\tversion: %ld\n\tindex: %ld\n\tinstance: %ld\n",
+  version, index, instance);
+#endif
+
+   g = fopen(bin, "r");
+   if (!g) {
+   printf("cannot open %s\n", bin);
+   return -1;
+   }
+   if (stat(bin, _stat) < 0) {
+   printf("cannot determine the size of %s\n", bin);
+   goto err_1;
+   }
+   data = malloc(bin_stat.st_size);
+   if (!data) {
+   printf("cannot allocate memory: %lx\n", bin_stat.st_size);
+   goto err_1;
+   }
+   f = fopen(path, "w");
+   if (!f) {
+   printf("cannot open %s\n", path);
+   goto err_2;
+   }
+   header.capsule_guid = efi_guid_fm_capsule;
+   header.header_size = sizeof(header);
+   header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */
+   header.capsule_image_size = sizeof(header)
+   + sizeof(capsule) + sizeof(u64)
+   + sizeof(image)
+   + bin_stat.st_size;
+
+   size = fwrite(, 1, sizeof(header), f);
+   if (size < sizeof(header)) {
+   

[PATCH 16/18] fs: fat: use constant DELETED_FLAG

2020-11-28 Thread Heinrich Schuchardt
When deleting a directory entry 0xe5 is written to name[0].

We have a constant for this value and should use it consistently.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 56ea28553b..c403d7d5c6 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1464,7 +1464,7 @@ static int delete_dentry(fat_itr *itr)
 *  - find and mark the "new" first invalid entry as name[0]=0x00
 */
memset(dentptr, 0, sizeof(*dentptr));
-   dentptr->name[0] = 0xe5;
+   dentptr->name[0] = DELETED_FLAG;

if (flush_dir(itr)) {
printf("error: writing directory entry\n");
--
2.29.2



[PATCH 18/18] fs: fat: deletion of long file names

2020-11-28 Thread Heinrich Schuchardt
Long file names are stored in multiple directory entries. When deleting a
file we must delete all of them.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 88 +++---
 1 file changed, 76 insertions(+), 12 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index c403d7d5c6..20a54a2418 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1445,27 +1445,91 @@ exit:
return count;
 }

-static int delete_dentry(fat_itr *itr)
+/**
+ * delete_single_dentry() - delete a single directory entry
+ *
+ * @itr:   directory iterator
+ * Return: 0 for success
+ */
+static int delete_single_dentry(fat_itr *itr)
+{
+   struct dir_entry *dent = itr->dent;
+
+   memset(dent, 0, sizeof(*dent));
+   dent->name[0] = DELETED_FLAG;
+
+   if (!itr->remaining) {
+   if (flush_dir(itr)) {
+   printf("error: writing directory entry\n");
+   return -EIO;
+   }
+   }
+   return 0;
+}
+
+/**
+ * delete_long_name() - delete long name directory entries
+ *
+ * @itr:   directory iterator
+ * Return: 0 for success
+ */
+static int delete_long_name(fat_itr *itr)
+{
+   struct dir_entry *dent = itr->dent;
+   int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
+
+   while (seqn--) {
+   int ret;
+
+   ret = delete_single_dentry(itr);
+   if (ret)
+   return ret;
+   dent = next_dent(itr);
+   if (!dent)
+   return -EIO;
+   }
+   return 0;
+}
+
+/**
+ * delete_dentry_long() - remove directory entry
+ *
+ * @itr:   directory iterator
+ * Return: 0 for success
+ */
+static int delete_dentry_long(fat_itr *itr)
 {
fsdata *mydata = itr->fsdata;
-   dir_entry *dentptr = itr->dent;
+   dir_entry *dent = itr->dent;

/* free cluster blocks */
-   clear_fatent(mydata, START(dentptr));
+   clear_fatent(mydata, START(dent));
if (flush_dirty_fat_buffer(mydata) < 0) {
printf("Error: flush fat buffer\n");
return -EIO;
}
+   /* Position to first directory entry for long name */
+   if (itr->clust != itr->dent_clust) {
+   int ret;

-   /*
-* update a directory entry
-* TODO:
-*  - long file name support
-*  - find and mark the "new" first invalid entry as name[0]=0x00
-*/
-   memset(dentptr, 0, sizeof(*dentptr));
-   dentptr->name[0] = DELETED_FLAG;
+   ret = fat_move_to_cluster(itr, itr->dent_clust);
+   if (ret)
+   return ret;
+   }
+   itr->dent = itr->dent_start;
+   itr->remaining = itr->dent_rem;
+   dent = itr->dent_start;
+   /* Delete long name */
+   if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
+   (dent->name[0] & LAST_LONG_ENTRY_MASK)) {
+   int ret;

+   ret = delete_long_name(itr);
+   if (ret)
+   return ret;
+   }
+   /* Delete short name */
+   delete_single_dentry(itr);
if (flush_dir(itr)) {
printf("error: writing directory entry\n");
return -EIO;
@@ -1535,7 +1599,7 @@ int fat_unlink(const char *filename)
}
}

-   ret = delete_dentry(itr);
+   ret = delete_dentry_long(itr);

 exit:
free(fsdata.fatbuf);
--
2.29.2



[PATCH 17/18] fs: fat: first dentry of long name in FAT iterator

2020-11-28 Thread Heinrich Schuchardt
A long name is split over multiple directory entries. When deleting a file
with a long name we need the first directory entry to be able to delete the
whole chain.

Add the necessary fields to the FAT iterator:

* cluster of first directory entry
* address of first directory entry
* remaining entries in cluster

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 5a418cfbb7..47344bb57e 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -700,6 +700,18 @@ struct fat_itr {
 * @dent:   current directory entry
 */
dir_entry *dent;
+   /**
+* @dent_rem:   remaining entries after long name start
+*/
+   int dent_rem;
+   /**
+* @dent_clust: cluster of long name start
+*/
+   unsigned int dent_clust;
+   /**
+* @dent_start: first directory entry for long name
+*/
+   dir_entry *dent_start;
/**
 * @l_name: long name of current directory entry
 */
@@ -966,9 +978,13 @@ static int fat_itr_next(fat_itr *itr)

while (1) {
dent = next_dent(itr);
-   if (!dent)
+   if (!dent) {
+   itr->dent_start = NULL;
return 0;
-
+   }
+   itr->dent_rem = itr->remaining;
+   itr->dent_start = itr->dent;
+   itr->dent_clust = itr->clust;
if (dent->name[0] == DELETED_FLAG)
continue;

--
2.29.2



[PATCH 15/18] fs: fat: search file should not allocate cluster

2020-11-28 Thread Heinrich Schuchardt
Searching for a file is not a write operation. So it should not lead to the
allocation of a new cluster to the directory.

If we reuse deleted entries, we might not even use the new cluster and due
to not flushing it the directory could be corrupted.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index a029ef8ed6..56ea28553b 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1154,10 +1154,12 @@ static void fill_dentry(fsdata *mydata, dir_entry 
*dentptr,
memcpy(dentptr->name, shortname, SHORT_NAME_SIZE);
 }

-/*
- * Find a directory entry based on filename or start cluster number
- * If the directory entry is not found,
- * the new position for writing a directory entry will be returned
+/**
+ * find_directory_entry() - find a directory entry by filename
+ *
+ * @itr:   directory iterator
+ * @filename:  name of file to find
+ * Return: directory entry or NULL
  */
 static dir_entry *find_directory_entry(fat_itr *itr, char *filename)
 {
@@ -1180,13 +1182,6 @@ static dir_entry *find_directory_entry(fat_itr *itr, 
char *filename)
return itr->dent;
}

-   /* allocate a cluster for more entries */
-   if (!itr->dent &&
-   (!itr->is_root || itr->fsdata->fatsize == 32) &&
-   new_dir_table(itr))
-   /* indicate that allocating dent failed */
-   itr->dent = NULL;
-
return NULL;
 }

@@ -1348,12 +1343,6 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
}
}

-   if (!itr->dent) {
-   printf("Error: allocating new dir entry\n");
-   ret = -EIO;
-   goto exit;
-   }
-
if (pos) {
/* No hole allowed */
ret = -EINVAL;
@@ -1622,12 +1611,6 @@ int fat_mkdir(const char *new_dirname)
}
}

-   if (!itr->dent) {
-   printf("Error: allocating new dir entry\n");
-   ret = -EIO;
-   goto exit;
-   }
-
/* Check if long name is needed */
ndent = set_name(itr, dirname, shortname);
if (ndent < 0) {
--
2.29.2



[PATCH 08/18] fs: fat: call set_name() only once

2020-11-28 Thread Heinrich Schuchardt
In set_name() we select the short name. Once this is correctly implemented
this will be a performance intensive operation because we need to check
that the name does not exist yet. So set_name should only be called once.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 87 --
 1 file changed, 54 insertions(+), 33 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 7e8886791c..716b6a6627 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -23,6 +23,9 @@
 /* Characters that may only be used in long file names */
 static const char LONG_ONLY_CHARS[] = "+,;=[]";

+/* Combined size of the name and ext fields in the directory entry */
+#define SHORT_NAME_SIZE 11
+
 /**
  * str2fat() - convert string to valid FAT name characters
  *
@@ -68,24 +71,28 @@ static int str2fat(char *dest, char *src, int length)
  *
  * If a long name is needed, a short name is constructed.
  *
- * @dirent:directory entry
  * @filename:  long file name
+ * @shortname: buffer of 11 bytes to receive chosen short name and extension
  * Return: number of directory entries needed, negative on error
  */
-static int set_name(dir_entry *dirent, const char *filename)
+static int set_name(const char *filename, char *shortname)
 {
char *period;
char *pos;
int period_location;
char buf[13];
int i;
+   int ret;
+   struct {
+   char name[8];
+   char ext[3];
+   } dirent;

if (!filename)
return -EIO;

-   /* Initialize buffers */
-   memset(dirent->name, ' ', sizeof(dirent->name));
-   memset(dirent->ext, ' ', sizeof(dirent->ext));
+   /* Initialize buffer */
+   memset(, ' ', sizeof(dirent));

/* Convert filename to upper case short name */
period = strrchr(filename, '.');
@@ -95,20 +102,22 @@ static int set_name(dir_entry *dirent, const char 
*filename)
period = 0;
}
if (period)
-   str2fat(dirent->ext, period + 1, sizeof(dirent->ext));
-   period_location = str2fat(dirent->name, pos, sizeof(dirent->name));
+   str2fat(dirent.ext, period + 1, sizeof(dirent.ext));
+   period_location = str2fat(dirent.name, pos, sizeof(dirent.name));
if (period_location < 0)
return period_location;
-   if (*dirent->name == ' ')
-   *dirent->name = '_';
+   if (*dirent.name == ' ')
+   *dirent.name = '_';
/* 0xe5 signals a deleted directory entry. Replace it by 0x05. */
-   if (*dirent->name == 0xe5)
-   *dirent->name = 0x05;
+   if (*dirent.name == 0xe5)
+   *dirent.name = 0x05;

/* If filename and short name are the same, quit. */
-   sprintf(buf, "%.*s.%.3s", period_location, dirent->name, dirent->ext);
-   if (!strcmp(buf, filename))
-   return 1;
+   sprintf(buf, "%.*s.%.3s", period_location, dirent.name, dirent.ext);
+   if (!strcmp(buf, filename)) {
+   ret = 1;
+   goto out;
+   }

/* Construct an indexed short name */
for (i = 1; i < 0x20; ++i) {
@@ -128,20 +137,24 @@ static int set_name(dir_entry *dirent, const char 
*filename)
suffix_start = 8 - suffix_len;
if (suffix_start > period_location)
suffix_start = period_location;
-   memcpy(dirent->name + suffix_start, buf, suffix_len);
-   if (*dirent->ext != ' ')
+   memcpy(dirent.name + suffix_start, buf, suffix_len);
+   if (*dirent.ext != ' ')
sprintf(buf, "%.*s.%.3s", suffix_start + suffix_len,
-   dirent->name, dirent->ext);
+   dirent.name, dirent.ext);
else
sprintf(buf, "%.*s", suffix_start + suffix_len,
-   dirent->name);
+   dirent.name);
debug("short name: %s\n", buf);
/* TODO: Check that the short name does not exist yet. */

/* Each long name directory entry takes 13 characters. */
-   return (strlen(filename) + 25) / 13;
+   ret = (strlen(filename) + 25) / 13;
+   goto out;
}
return -EIO;
+out:
+   memcpy(shortname, dirent.name, SHORT_NAME_SIZE);
+   return ret;
 }

 static int total_sector;
@@ -1019,18 +1032,27 @@ getit:
return 0;
 }

-/*
- * Fill dir_entry
+/**
+ * fill_dentry() - fill directory entry with shortname
+ *
+ * @mydata:private filesystem parameters
+ * @dentptr:   directory entry
+ * @shortname: chosen short name
+ * @start_cluster: first cluster of file
+ * @size:  file size
+ * @attr:  file attributes
  */
 static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
-

[PATCH 13/18] fs: fat: fat_find_empty_dentries()

2020-11-28 Thread Heinrich Schuchardt
Provide a function to find a series of empty directory entries.

The current directory is scanned for deleted entries.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 62 +-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 941f8789ab..d560b94b60 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -21,6 +21,7 @@
 #include "fat.c"

 static dir_entry *find_directory_entry(fat_itr *itr, char *filename);
+static int new_dir_table(fat_itr *itr);

 /* Characters that may only be used in long file names */
 static const char LONG_ONLY_CHARS[] = "+,;=[]";
@@ -250,6 +251,66 @@ static int flush_dirty_fat_buffer(fsdata *mydata)
return 0;
 }

+/**
+ * fat_find_empty_dentries() - find a sequence of available directory entries
+ *
+ * @itr:   directory iterator
+ * @count: number of directory entries to find
+ * Return: 0 on success or negative error number
+ */
+static int __maybe_unused fat_find_empty_dentries(fat_itr *itr, int count)
+{
+   unsigned int cluster;
+   dir_entry *dent;
+   int remaining;
+   unsigned int n = 0;
+   int ret;
+
+   ret = fat_move_to_cluster(itr, itr->start_clust);
+   if (ret)
+   return ret;
+
+   for (;;) {
+   if (!itr->dent) {
+   log_debug("Not enough directory entries available\n");
+   return -ENOSPC;
+   }
+   switch (itr->dent->name[0]) {
+   case 0x00:
+   case DELETED_FLAG:
+   if (!n) {
+   /* Remember first deleted directory entry */
+   cluster = itr->clust;
+   dent = itr->dent;
+   remaining = itr->remaining;
+   }
+   ++n;
+   if (n == count)
+   goto out;
+   break;
+   default:
+   n = 0;
+   break;
+   }
+
+   next_dent(itr);
+   if (!itr->dent &&
+   (!itr->is_root || itr->fsdata->fatsize == 32) &&
+   new_dir_table(itr))
+   return -ENOSPC;
+   }
+out:
+   /* Position back to first directory entry */
+   if (itr->clust != cluster) {
+   ret = fat_move_to_cluster(itr, cluster);
+   if (ret)
+   return ret;
+   }
+   itr->dent = dent;
+   itr->remaining = remaining;
+   return 0;
+}
+
 /*
  * Set the file name information from 'name' into 'slotptr',
  */
@@ -319,7 +380,6 @@ name11_12:
return 1;
 }

-static int new_dir_table(fat_itr *itr);
 static int flush_dir(fat_itr *itr);

 /**
--
2.29.2



[PATCH 09/18] fs: fat: generate unique short names

2020-11-28 Thread Heinrich Schuchardt
File names must be unique within their directory. So before assigning a
short name we must check that it is unique.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 41 -
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 716b6a6627..59cffef34e 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -20,6 +20,8 @@
 #include 
 #include "fat.c"

+static dir_entry *find_directory_entry(fat_itr *itr, char *filename);
+
 /* Characters that may only be used in long file names */
 static const char LONG_ONLY_CHARS[] = "+,;=[]";

@@ -63,6 +65,27 @@ static int str2fat(char *dest, char *src, int length)
return i;
 }

+/**
+ * fat_move_to_cluster() - position to first directory entry in cluster
+ *
+ * @itr:   directory iterator
+ * @clustercluster
+ * Return: 0 for success, -EIO on error
+ */
+static int fat_move_to_cluster(fat_itr *itr, unsigned int cluster)
+{
+   unsigned int nbytes;
+
+   /* position to the start of the directory */
+   itr->next_clust = cluster;
+   itr->last_cluster = 0;
+   if (!fat_next_cluster(itr, ))
+   return -EIO;
+   itr->dent = (dir_entry *)itr->block;
+   itr->remaining = nbytes / sizeof(dir_entry) - 1;
+   return 0;
+}
+
 /**
  * set_name() - set short name in directory entry
  *
@@ -71,11 +94,12 @@ static int str2fat(char *dest, char *src, int length)
  *
  * If a long name is needed, a short name is constructed.
  *
+ * @itr:   directory iterator
  * @filename:  long file name
  * @shortname: buffer of 11 bytes to receive chosen short name and extension
  * Return: number of directory entries needed, negative on error
  */
-static int set_name(const char *filename, char *shortname)
+static int set_name(fat_itr *itr, const char *filename, char *shortname)
 {
char *period;
char *pos;
@@ -144,9 +168,16 @@ static int set_name(const char *filename, char *shortname)
else
sprintf(buf, "%.*s", suffix_start + suffix_len,
dirent.name);
-   debug("short name: %s\n", buf);
-   /* TODO: Check that the short name does not exist yet. */
+   debug("generated short name: %s\n", buf);
+
+   /* Check that the short name does not exist yet. */
+   ret = fat_move_to_cluster(itr, itr->start_clust);
+   if (ret)
+   return ret;
+   if (find_directory_entry(itr, buf))
+   continue;

+   debug("chosen short name: %s\n", buf);
/* Each long name directory entry takes 13 characters. */
ret = (strlen(filename) + 25) / 13;
goto out;
@@ -1261,7 +1292,7 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
}

/* Check if long name is needed */
-   ret = set_name(filename, shortname);
+   ret = set_name(itr, filename, shortname);
if (ret < 0)
goto exit;
if (ret > 1) {
@@ -1523,7 +1554,7 @@ int fat_mkdir(const char *new_dirname)
}

/* Check if long name is needed */
-   ret = set_name(dirname, shortname);
+   ret = set_name(itr, dirname, shortname);
if (ret < 0)
goto exit;
if (ret > 1) {
--
2.29.2



[PATCH 02/18] fs: fat: directory entries starting with 0x05

2020-11-28 Thread Heinrich Schuchardt
0x05 is used as replacement letter for 0xe5 at the first position of short
file names. We must not skip over directory entries starting with 0x05.

Cf. Microsoft FAT Specification, August 30 2005

Fixes: 39606d462c97 ("fs: fat: handle deleted directory entries correctly")
Signed-off-by: Heinrich Schuchardt 
Reviewed-by: Christian Gmeiner 
Reviewed-by: Simon Glass 
---
 fs/fat/fat.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 28aa5aaa9f..fb6ba89466 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -926,8 +926,7 @@ static int fat_itr_next(fat_itr *itr)
if (!dent)
return 0;

-   if (dent->name[0] == DELETED_FLAG ||
-   dent->name[0] == aRING)
+   if (dent->name[0] == DELETED_FLAG)
continue;

if (dent->attr & ATTR_VOLUME) {
--
2.29.2



[PATCH 11/18] fs: fat: set start cluster for root directory

2020-11-28 Thread Heinrich Schuchardt
When iterating over a child directory we set itr->start_clust.
Do the same when over the root directory.

When looking for deleted directory entries or existing short names we will
have to iterate over directories a second and third time. With this patch
we do not need any special logic for the root directory.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 674236d68a..5a418cfbb7 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -734,7 +734,7 @@ static int fat_itr_root(fat_itr *itr, fsdata *fsdata)
return -ENXIO;

itr->fsdata = fsdata;
-   itr->start_clust = 0;
+   itr->start_clust = fsdata->root_cluster;
itr->clust = fsdata->root_cluster;
itr->next_clust = fsdata->root_cluster;
itr->dent = NULL;
@@ -778,6 +778,7 @@ static void fat_itr_child(fat_itr *itr, fat_itr *parent)
} else {
itr->clust = parent->fsdata->root_cluster;
itr->next_clust = parent->fsdata->root_cluster;
+   itr->start_clust = parent->fsdata->root_cluster;
itr->is_root = 1;
}
itr->dent = NULL;
@@ -1067,6 +1068,7 @@ static int fat_itr_resolve(fat_itr *itr, const char 
*path, unsigned type)
/* point back to itself */
itr->clust = itr->fsdata->root_cluster;
itr->next_clust = itr->fsdata->root_cluster;
+   itr->start_clust = itr->fsdata->root_cluster;
itr->dent = NULL;
itr->remaining = 0;
itr->last_cluster = 0;
--
2.29.2



[PATCH 14/18] fs: fat: reuse deleted directory entries

2020-11-28 Thread Heinrich Schuchardt
When creating new directory entries try to reuse entries marked as deleted.

In fill_dir_slot() do not allocate new clusters as this has already been
done in fat_find_empty_dentries().

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 34 ++
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index d560b94b60..a029ef8ed6 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -258,7 +258,7 @@ static int flush_dirty_fat_buffer(fsdata *mydata)
  * @count: number of directory entries to find
  * Return: 0 on success or negative error number
  */
-static int __maybe_unused fat_find_empty_dentries(fat_itr *itr, int count)
+static int fat_find_empty_dentries(fat_itr *itr, int count)
 {
unsigned int cluster;
dir_entry *dent;
@@ -421,11 +421,9 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char 
*shortname)
if (itr->remaining == 0)
flush_dir(itr);

-   /* allocate a cluster for more entries */
-   if (!next_dent(itr) && !itr->dent)
-   if ((itr->is_root && itr->fsdata->fatsize != 32) ||
-   new_dir_table(itr))
-   return -EIO;
+   next_dent(itr);
+   if (!itr->dent)
+   return -EIO;
}

return 0;
@@ -1339,6 +1337,7 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
} else {
/* Create a new file */
char shortname[SHORT_NAME_SIZE];
+   int ndent;

if (itr->is_root) {
/* root dir cannot have "." or ".." */
@@ -1362,10 +1361,15 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
}

/* Check if long name is needed */
-   ret = set_name(itr, filename, shortname);
-   if (ret < 0)
+   ndent = set_name(itr, filename, shortname);
+   if (ndent < 0) {
+   ret = ndent;
+   goto exit;
+   }
+   ret = fat_find_empty_dentries(itr, ndent);
+   if (ret)
goto exit;
-   if (ret > 1) {
+   if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, filename, shortname);
if (ret)
@@ -1607,6 +1611,7 @@ int fat_mkdir(const char *new_dirname)
goto exit;
} else {
char shortname[SHORT_NAME_SIZE];
+   int ndent;

if (itr->is_root) {
/* root dir cannot have "." or ".." */
@@ -1624,10 +1629,15 @@ int fat_mkdir(const char *new_dirname)
}

/* Check if long name is needed */
-   ret = set_name(itr, dirname, shortname);
-   if (ret < 0)
+   ndent = set_name(itr, dirname, shortname);
+   if (ndent < 0) {
+   ret = ndent;
+   goto exit;
+   }
+   ret = fat_find_empty_dentries(itr, ndent);
+   if (ret)
goto exit;
-   if (ret > 1) {
+   if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, dirname, shortname);
if (ret)
--
2.29.2



[PATCH 12/18] fs: fat: flush new directory cluster

2020-11-28 Thread Heinrich Schuchardt
When handling long file names directory entries may be split over multiple
clusters. We must make sure that new clusters are zero filled on disk.

When allocating a new cluster for a directory flush it.

The flushing should be executed before updating the FAT. This way if
flushing fails, we still have a valid directory structure.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 0746d73f8d..941f8789ab 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -738,17 +738,32 @@ static int find_empty_cluster(fsdata *mydata)
return entry;
 }

-/*
- * Allocate a cluster for additional directory entries
+/**
+ * new_dir_table() - allocate a cluster for additional directory entries
+ *
+ * @itr:   directory iterator
+ * Return: 0 on success, -EIO otherwise
  */
 static int new_dir_table(fat_itr *itr)
 {
fsdata *mydata = itr->fsdata;
int dir_newclust = 0;
+   int dir_oldclust = itr->clust;
unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;

dir_newclust = find_empty_cluster(mydata);
-   set_fatent_value(mydata, itr->clust, dir_newclust);
+
+   /*
+* Flush before updating FAT to ensure valid directory structure
+* in case of failure.
+*/
+   itr->clust = dir_newclust;
+   itr->next_clust = dir_newclust;
+   memset(itr->block, 0x00, bytesperclust);
+   if (flush_dir(itr))
+   return -EIO;
+
+   set_fatent_value(mydata, dir_oldclust, dir_newclust);
if (mydata->fatsize == 32)
set_fatent_value(mydata, dir_newclust, 0xff8);
else if (mydata->fatsize == 16)
@@ -756,13 +771,8 @@ static int new_dir_table(fat_itr *itr)
else if (mydata->fatsize == 12)
set_fatent_value(mydata, dir_newclust, 0xff8);

-   itr->clust = dir_newclust;
-   itr->next_clust = dir_newclust;
-
if (flush_dirty_fat_buffer(mydata) < 0)
-   return -1;
-
-   memset(itr->block, 0x00, bytesperclust);
+   return -EIO;

itr->dent = (dir_entry *)itr->block;
itr->last_cluster = 1;
--
2.29.2



[PATCH 10/18] fs: fat: dentry iterator for fill_dir_slot()

2020-11-28 Thread Heinrich Schuchardt
For reusing deleted directory entries we have to adjust the function called
to step to the next directory entry.

This patch alone is not enough to actually reuse deleted directory entries
as the fill_dir_slot() is still called with first never used directory
entry.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 59cffef34e..0746d73f8d 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -362,7 +362,7 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char 
*shortname)
flush_dir(itr);

/* allocate a cluster for more entries */
-   if (!fat_itr_next(itr) && !itr->dent)
+   if (!next_dent(itr) && !itr->dent)
if ((itr->is_root && itr->fsdata->fatsize != 32) ||
new_dir_table(itr))
return -EIO;
--
2.29.2



[PATCH 01/18] fs: fat: avoid NULL dereference when root dir is full

2020-11-28 Thread Heinrich Schuchardt
When trying to create a file in the full root directory of a FAT32
filesystem a NULL dereference can be observed.

When the root directory of a FAT16 filesystem is full fill_dir_slot() must
return -1 to signal that a new directory entry could not be allocated.

Fixes: cd2d727fff7e ("fs: fat: allocate a new cluster for root directory of 
fat32")
Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index a2682b5f46..fc932df953 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -260,9 +260,8 @@ fill_dir_slot(fat_itr *itr, const char *l_name)
flush_dir(itr);

/* allocate a cluster for more entries */
-   if (!fat_itr_next(itr))
-   if (!itr->dent &&
-   (!itr->is_root || itr->fsdata->fatsize == 32) &&
+   if (!fat_itr_next(itr) && !itr->dent)
+   if ((itr->is_root && itr->fsdata->fatsize != 32) ||
new_dir_table(itr))
return -1;
}
--
2.29.2



[PATCH 00/18] fs: fat: fix long name support

2020-11-28 Thread Heinrich Schuchardt
Since long name support was added to U-Boot's implementation of the
FAT file system corruption of the directories was observed when running
the UEFI Self Certifification Test.

The following problems are addressed by this series.

* short names were not unique
* long names directory entries were not deleted when a file was deleted
* directory entries released by file deletion were not reused

The first four patches are just resent to indicate the import sequence.

The following problems need to be addressed in further patches:

* When extending a file only available FAT entries after the last cluster
  of the file are considered. Available FAT entries before are ignored.
* The case of no FAT entry found is not treated correctly.
* The free FAT count is not updated on FAT32.
* Some FAT related tests are not run on Gitlab CI.
* Add tests to detect directory corruption.

Heinrich Schuchardt (18):
  fs: fat: avoid NULL dereference when root dir is full
  fs: fat: directory entries starting with 0x05
  fs: fat: use ATTR_ARCH instead of anonymous 0x20
  fs: fat: correct first cluster for '..'
  fs: fat: export fat_next_cluster()
  fs: fat: create correct short names
  fs: fat: pass shortname to fill_dir_slot
  fs: fat: call set_name() only once
  fs: fat: generate unique short names
  fs: fat: dentry iterator for fill_dir_slot()
  fs: fat: set start cluster for root directory
  fs: fat: flush new directory cluster
  fs: fat: fat_find_empty_dentries()
  fs: fat: reuse deleted directory entries
  fs: fat: search file should not allocate cluster
  fs: fat: use constant DELETED_FLAG
  fs: fat: first dentry of long name in FAT iterator
  fs: fat: deletion of long file names

 fs/fat/fat.c   | 133 
 fs/fat/fat_write.c | 532 +
 include/fat.h  |   7 +-
 lib/Kconfig|   2 +-
 4 files changed, 494 insertions(+), 180 deletions(-)

--
2.29.2



[PATCH 05/18] fs: fat: export fat_next_cluster()

2020-11-28 Thread Heinrich Schuchardt
Rename function next_cluster() to fat_next_cluster() and export it.

When creating a new directory entries we should reuse deleted entries.
This requires re-scanning the directory.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat.c  | 106 +++---
 include/fat.h |   7 +++-
 2 files changed, 80 insertions(+), 33 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index fb6ba89466..674236d68a 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -621,7 +621,7 @@ static int get_fs_info(fsdata *mydata)
/*
 * The root directory is not cluster-aligned and may be on a
 * "negative" cluster, this will be handled specially in
-* next_cluster().
+* fat_next_cluster().
 */
mydata->root_cluster = 0;
}
@@ -647,44 +647,76 @@ static int get_fs_info(fsdata *mydata)
return 0;
 }

-
-/*
- * Directory iterator, to simplify filesystem traversal
+/**
+ * struct fat_itr - directory iterator, to simplify filesystem traversal
  *
  * Implements an iterator pattern to traverse directory tables,
  * transparently handling directory tables split across multiple
  * clusters, and the difference between FAT12/FAT16 root directory
  * (contiguous) and subdirectories + FAT32 root (chained).
  *
- * Rough usage:
+ * Rough usage
  *
- *   for (fat_itr_root(, fsdata); fat_itr_next(); ) {
- *  // to traverse down to a subdirectory pointed to by
- *  // current iterator position:
- *  fat_itr_child(, );
- *   }
+ * .. code-block:: c
  *
- * For more complete example, see fat_itr_resolve()
+ * for (fat_itr_root(, fsdata); fat_itr_next(); ) {
+ * // to traverse down to a subdirectory pointed to by
+ * // current iterator position:
+ * fat_itr_child(, );
+ * }
+ *
+ * For a more complete example, see fat_itr_resolve().
  */
-
-typedef struct {
-   fsdata*fsdata;/* filesystem parameters */
-   unsigned   start_clust;   /* first cluster */
-   unsigned   clust; /* current cluster */
-   unsigned   next_clust;/* next cluster if remaining == 0 */
-   intlast_cluster;  /* set once we've read last cluster */
-   intis_root;   /* is iterator at root directory */
-   intremaining; /* remaining dent's in current cluster */
-
-   /* current iterator position values: */
-   dir_entry *dent;  /* current directory entry */
-   char   l_name[VFAT_MAXLEN_BYTES];/* long (vfat) name */
-   char   s_name[14];/* short 8.3 name */
-   char  *name;  /* l_name if there is one, else s_name */
-
-   /* storage for current cluster in memory: */
-   u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN);
-} fat_itr;
+struct fat_itr {
+   /**
+* @fsdata: filesystem parameters
+*/
+   fsdata *fsdata;
+   /**
+* @start_clust:first cluster
+*/
+   unsigned int start_clust;
+   /**
+* @clust:  current cluster
+*/
+   unsigned int clust;
+   /**
+* @next_clust: next cluster if remaining == 0
+*/
+   unsigned int next_clust;
+   /**
+* @last_cluster:   set if last cluster of directory reached
+*/
+   int last_cluster;
+   /**
+* @is_root:is iterator at root directory
+*/
+   int is_root;
+   /**
+* @remaining:  remaining directory entries in current cluster
+*/
+   int remaining;
+   /**
+* @dent:   current directory entry
+*/
+   dir_entry *dent;
+   /**
+* @l_name: long name of current directory entry
+*/
+   char l_name[VFAT_MAXLEN_BYTES];
+   /**
+* @s_name: short 8.3 name of current directory entry
+*/
+   char s_name[14];
+   /**
+* @name:   l_name if there is one, else s_name
+*/
+   char *name;
+   /**
+* @block:  buffer for current cluster
+*/
+   u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN);
+};

 static int fat_itr_isdir(fat_itr *itr);

@@ -753,7 +785,17 @@ static void fat_itr_child(fat_itr *itr, fat_itr *parent)
itr->last_cluster = 0;
 }

-static void *next_cluster(fat_itr *itr, unsigned *nbytes)
+/**
+ * fat_next_cluster() - load next FAT cluster
+ *
+ * The function is used when iterating through directories. It loads the
+ * next cluster with directory entries
+ *
+ * @itr:   directory iterator
+ * @nbytes:number of bytes read, 0 on error
+ * Return: first directory entry, NULL on error
+ */
+void *fat_next_cluster(fat_itr *itr, unsigned int *nbytes)
 {
fsdata *mydata = itr->fsdata;  /* for silly macros */
int ret;
@@ -825,7 +867,7 @@ static dir_entry 

[PATCH 07/18] fs: fat: pass shortname to fill_dir_slot

2020-11-28 Thread Heinrich Schuchardt
Currently we pass the short name via the directory iterator.
Pass it explicitly as a parameter.

This removes the requirement to set the short name in the iterator before
writing the long name.

Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 058b566629..7e8886791c 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -278,12 +278,16 @@ name11_12:
 static int new_dir_table(fat_itr *itr);
 static int flush_dir(fat_itr *itr);

-/*
- * Fill dir_slot entries with appropriate name, id, and attr
- * 'itr' will point to a next entry
+/**
+ * fill_dir_slot() - fill directory entries for long name
+ *
+ * @itr:   directory iterator
+ * @l_name:long name
+ * @shortname: short name
+ * Return: 0 for success, -errno otherwise
  */
 static int
-fill_dir_slot(fat_itr *itr, const char *l_name)
+fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
 {
__u8 temp_dir_slot_buffer[MAX_LFN_SLOT * sizeof(dir_slot)];
dir_slot *slotptr = (dir_slot *)temp_dir_slot_buffer;
@@ -291,7 +295,7 @@ fill_dir_slot(fat_itr *itr, const char *l_name)
int idx = 0, ret;

/* Get short file name checksum value */
-   checksum = mkcksum(itr->dent->name, itr->dent->ext);
+   checksum = mkcksum(shortname, shortname + 8);

do {
memset(slotptr, 0x00, sizeof(dir_slot));
@@ -317,7 +321,7 @@ fill_dir_slot(fat_itr *itr, const char *l_name)
if (!fat_itr_next(itr) && !itr->dent)
if ((itr->is_root && itr->fsdata->fatsize != 32) ||
new_dir_table(itr))
-   return -1;
+   return -EIO;
}

return 0;
@@ -1241,7 +1245,7 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
goto exit;
if (ret > 1) {
/* Set long name entries */
-   ret = fill_dir_slot(itr, filename);
+   ret = fill_dir_slot(itr, filename, itr->dent->name);
if (ret)
goto exit;
}
@@ -1503,7 +1507,7 @@ int fat_mkdir(const char *new_dirname)
goto exit;
if (ret > 1) {
/* Set long name entries */
-   ret = fill_dir_slot(itr, dirname);
+   ret = fill_dir_slot(itr, dirname, itr->dent->name);
if (ret)
goto exit;
}
--
2.29.2



[PATCH 04/18] fs: fat: correct first cluster for '..'

2020-11-28 Thread Heinrich Schuchardt
The FAT specification [1] requires that for a '..' directory entry pointing
to the root directory the fields DIR_FstClusHi and DIR_FstClusLo are 0.

[1] Microsoft FAT Specification, Microsoft Corporation, August 30 2005

Fixes: 31a18d570d96 ("fs: fat: support mkdir")
Signed-off-by: Heinrich Schuchardt 
Acked-by: Marek Szyprowski 
---
 fs/fat/fat_write.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 7afc8388b2..4da342f9c9 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1468,7 +1468,11 @@ int fat_mkdir(const char *new_dirname)
memcpy(dotdent[1].name, "..  ", 8);
memcpy(dotdent[1].ext, "   ", 3);
dotdent[1].attr = ATTR_DIR | ATTR_ARCH;
-   set_start_cluster(mydata, [1], itr->start_clust);
+
+   if (itr->is_root)
+   set_start_cluster(mydata, [1], 0);
+   else
+   set_start_cluster(mydata, [1], itr->start_clust);

ret = set_contents(mydata, retdent, 0, (__u8 *)dotdent,
   bytesperclust, );
--
2.29.2



[PATCH 06/18] fs: fat: create correct short names

2020-11-28 Thread Heinrich Schuchardt
The current function set_name() used to create short names has the
following deficiencies resolved by this patch:

* Long names (e.g. FOO.TXT) are stored even if a short name is enough.
* Short names with spaces are created, e.g. "A ~1.TXT".
* Short names with illegal characters are created, e.g. "FOO++BAR".
* Debug output does not not consider that the short file name has no
  concluding '\0'.

The solution for the following bug is split of into a separate patch:

* Short file names must be unique.

This patch only provides the loop over possible short file names.

Fixes: c30a15e590c ("FAT: Add FAT write feature")
Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 215 +
 lib/Kconfig|   2 +-
 2 files changed, 140 insertions(+), 77 deletions(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 4da342f9c9..058b566629 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -8,25 +8,140 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
 #include 
-#include 
 #include 
 #include "fat.c"

-static void uppercase(char *str, int len)
+/* Characters that may only be used in long file names */
+static const char LONG_ONLY_CHARS[] = "+,;=[]";
+
+/**
+ * str2fat() - convert string to valid FAT name characters
+ *
+ * Stop when reaching end of @src or a period.
+ * Ignore spaces.
+ * Replace characters that may only be used in long names by underscores.
+ * Convert lower case characters to upper case.
+ *
+ * To avoid assumptions about the code page we do not use characters
+ * above 0x7f for the short name.
+ *
+ * @dest:  destination buffer
+ * @src:   source buffer
+ * @length:size of destination buffer
+ * Return: number of bytes in destination buffer
+ */
+static int str2fat(char *dest, char *src, int length)
+{
+   int i;
+
+   for (i = 0; i < length; ++src) {
+   char c = *src;
+
+   if (!c || c == '.')
+   break;
+   if (c == ' ')
+   continue;
+   if (strchr(LONG_ONLY_CHARS, c) || c > 0x7f)
+   c = '_';
+   else if (c >= 'a' && c <= 'z')
+   c &= 0xdf;
+   dest[i] = c;
+   ++i;
+   }
+   return i;
+}
+
+/**
+ * set_name() - set short name in directory entry
+ *
+ * The function determines if the @filename is a valid short name.
+ * In this case no long name is needed.
+ *
+ * If a long name is needed, a short name is constructed.
+ *
+ * @dirent:directory entry
+ * @filename:  long file name
+ * Return: number of directory entries needed, negative on error
+ */
+static int set_name(dir_entry *dirent, const char *filename)
 {
+   char *period;
+   char *pos;
+   int period_location;
+   char buf[13];
int i;

-   for (i = 0; i < len; i++) {
-   *str = toupper(*str);
-   str++;
+   if (!filename)
+   return -EIO;
+
+   /* Initialize buffers */
+   memset(dirent->name, ' ', sizeof(dirent->name));
+   memset(dirent->ext, ' ', sizeof(dirent->ext));
+
+   /* Convert filename to upper case short name */
+   period = strrchr(filename, '.');
+   pos = (char *)filename;
+   if (*pos == '.') {
+   pos = period + 1;
+   period = 0;
+   }
+   if (period)
+   str2fat(dirent->ext, period + 1, sizeof(dirent->ext));
+   period_location = str2fat(dirent->name, pos, sizeof(dirent->name));
+   if (period_location < 0)
+   return period_location;
+   if (*dirent->name == ' ')
+   *dirent->name = '_';
+   /* 0xe5 signals a deleted directory entry. Replace it by 0x05. */
+   if (*dirent->name == 0xe5)
+   *dirent->name = 0x05;
+
+   /* If filename and short name are the same, quit. */
+   sprintf(buf, "%.*s.%.3s", period_location, dirent->name, dirent->ext);
+   if (!strcmp(buf, filename))
+   return 1;
+
+   /* Construct an indexed short name */
+   for (i = 1; i < 0x20; ++i) {
+   int suffix_len;
+   int suffix_start;
+   int j;
+
+   /* To speed up the search use random numbers */
+   if (i < 10) {
+   j = i;
+   } else {
+   j = 30 - fls(i);
+   j = 10 + (rand() >> j);
+   }
+   sprintf(buf, "~%d", j);
+   suffix_len = strlen(buf);
+   suffix_start = 8 - suffix_len;
+   if (suffix_start > period_location)
+   suffix_start = period_location;
+   memcpy(dirent->name + suffix_start, buf, suffix_len);
+   if (*dirent->ext != ' ')
+   sprintf(buf, "%.*s.%.3s", suffix_start + suffix_len,
+  

[PATCH 03/18] fs: fat: use ATTR_ARCH instead of anonymous 0x20

2020-11-28 Thread Heinrich Schuchardt
Using constants instead of anonymous numbers increases code readability.

Fixes: 704df6aa0a28 ("fs: fat: refactor write interface for a file offset")
Signed-off-by: Heinrich Schuchardt 
---
 fs/fat/fat_write.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index fc932df953..7afc8388b2 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1191,7 +1191,8 @@ int file_fat_write_at(const char *filename, loff_t pos, 
void *buffer,
}

/* Set short name entry */
-   fill_dentry(itr->fsdata, itr->dent, filename, 0, size, 0x20);
+   fill_dentry(itr->fsdata, itr->dent, filename, 0, size,
+   ATTR_ARCH);

retdent = itr->dent;
}
--
2.29.2



[PATCH 09/11] dm: core: Combine the flattree and livetree binding code

2020-11-28 Thread Simon Glass
At present there are two copies of this code. With ofnode we can combine
them to reduce duplication. Update the dm_scan_fdt_node() function and
adjust its callers.

Signed-off-by: Simon Glass 
---

 drivers/core/root.c | 74 ++---
 1 file changed, 16 insertions(+), 58 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 9ee65504e6e..62efa0fedcf 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -199,33 +199,6 @@ int dm_scan_platdata(bool pre_reloc_only)
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
-static int dm_scan_fdt_live(struct udevice *parent,
-   const struct device_node *node_parent,
-   bool pre_reloc_only)
-{
-   struct device_node *np;
-   int ret = 0, err;
-
-   for (np = node_parent->child; np; np = np->sibling) {
-
-   if (!of_device_is_available(np)) {
-   pr_debug("   - ignoring disabled device\n");
-   continue;
-   }
-   err = lists_bind_fdt(parent, np_to_ofnode(np), NULL,
-pre_reloc_only);
-   if (err && !ret) {
-   ret = err;
-   debug("%s: ret=%d\n", np->name, ret);
-   }
-   }
-
-   if (ret)
-   dm_warn("Some drivers failed to bind\n");
-
-   return ret;
-}
-
 /**
  * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node
  *
@@ -233,28 +206,30 @@ static int dm_scan_fdt_live(struct udevice *parent,
  * for each one.
  *
  * @parent: Parent device for the devices that will be created
- * @blob: Pointer to device tree blob
- * @offset: Offset of node to scan
+ * @node: Node to scan
  * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
  * flag. If false bind all drivers.
  * @return 0 if OK, -ve on error
  */
-static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
-   int offset, bool pre_reloc_only)
+static int dm_scan_fdt_node(struct udevice *parent, ofnode parent_node,
+   bool pre_reloc_only)
 {
int ret = 0, err;
+   ofnode node;
+
+   if (!ofnode_valid(parent_node))
+   return 0;
 
-   for (offset = fdt_first_subnode(blob, offset);
-offset > 0;
-offset = fdt_next_subnode(blob, offset)) {
-   const char *node_name = fdt_get_name(blob, offset, NULL);
+   for (node = ofnode_first_subnode(parent_node);
+ofnode_valid(node);
+node = ofnode_next_subnode(node)) {
+   const char *node_name = ofnode_get_name(node);
 
-   if (!fdtdec_get_is_enabled(blob, offset)) {
+   if (!ofnode_is_enabled(node)) {
pr_debug("   - ignoring disabled device\n");
continue;
}
-   err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL,
-pre_reloc_only);
+   err = lists_bind_fdt(parent, node, NULL, pre_reloc_only);
if (err && !ret) {
ret = err;
debug("%s: ret=%d\n", node_name, ret);
@@ -269,24 +244,13 @@ static int dm_scan_fdt_node(struct udevice *parent, const 
void *blob,
 
 int dm_scan_fdt_dev(struct udevice *dev)
 {
-   if (!dev_of_valid(dev))
-   return 0;
-
-   if (of_live_active())
-   return dm_scan_fdt_live(dev, dev_np(dev),
-   gd->flags & GD_FLG_RELOC ? false : true);
-
-   return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
+   return dm_scan_fdt_node(dev, dev_ofnode(dev),
gd->flags & GD_FLG_RELOC ? false : true);
 }
 
 int dm_scan_fdt(const void *blob, bool pre_reloc_only)
 {
-   if (of_live_active())
-   return dm_scan_fdt_live(gd->dm_root, gd_of_root(),
-   pre_reloc_only);
-
-   return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
+   return dm_scan_fdt_node(gd->dm_root, ofnode_root(), pre_reloc_only);
 }
 
 static int dm_scan_fdt_ofnode_path(const void *blob, const char *path,
@@ -295,14 +259,8 @@ static int dm_scan_fdt_ofnode_path(const void *blob, const 
char *path,
ofnode node;
 
node = ofnode_path(path);
-   if (!ofnode_valid(node))
-   return 0;
-
-   if (of_live_active())
-   return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
 
-   return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset,
-   pre_reloc_only);
+   return dm_scan_fdt_node(gd->dm_root, node, pre_reloc_only);
 }
 
 int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 11/11] dm: core: Drop unused parameter from dm_extended_scan_fdt()

2020-11-28 Thread Simon Glass
This doesn't need to be passed the devicetree anymore. Drop it.
Also rename the function to drop the _fdt suffix.

Signed-off-by: Simon Glass 
---

 drivers/core/root.c | 6 +++---
 include/dm/root.h   | 5 ++---
 test/dm/test-fdt.c  | 2 +-
 test/dm/test-main.c | 2 +-
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 54498b2df71..6f8168bb92d 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -262,7 +262,7 @@ static int dm_scan_fdt_ofnode_path(const char *path, bool 
pre_reloc_only)
return dm_scan_fdt_node(gd->dm_root, node, pre_reloc_only);
 }
 
-int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
+int dm_extended_scan(bool pre_reloc_only)
 {
int ret, i;
const char * const nodes[] = {
@@ -315,9 +315,9 @@ int dm_init_and_scan(bool pre_reloc_only)
}
 
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
-   ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only);
+   ret = dm_extended_scan(pre_reloc_only);
if (ret) {
-   debug("dm_extended_scan_dt() failed: %d\n", ret);
+   debug("dm_extended_scan() failed: %d\n", ret);
return ret;
}
}
diff --git a/include/dm/root.h b/include/dm/root.h
index e277ebb9523..830e31312df 100644
--- a/include/dm/root.h
+++ b/include/dm/root.h
@@ -54,18 +54,17 @@ int dm_scan_platdata(bool pre_reloc_only);
 int dm_scan_fdt(bool pre_reloc_only);
 
 /**
- * dm_extended_scan_fdt() - Scan the device tree and bind drivers
+ * dm_extended_scan() - Scan the device tree and bind drivers
  *
  * This calls dm_scna_dft() which scans the device tree and creates a driver
  * for each node. the top-level subnodes are examined and also all sub-nodes
  * of "clocks" node.
  *
- * @blob: Pointer to device tree blob
  * @pre_reloc_only: If true, bind only nodes with special devicetree 
properties,
  * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
  * @return 0 if OK, -ve on error
  */
-int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only);
+int dm_extended_scan(bool pre_reloc_only);
 
 /**
  * dm_scan_other() - Scan for other devices
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 9507636b630..673ffb4de94 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -257,7 +257,7 @@ static int dm_test_fdt(struct unit_test_state *uts)
int ret;
int i;
 
-   ret = dm_extended_scan_fdt(gd->fdt_blob, false);
+   ret = dm_extended_scan(false);
ut_assert(!ret);
 
ret = uclass_get(UCLASS_TEST_FDT, );
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 2ab73b647e6..4814e186cb7 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -94,7 +94,7 @@ static int dm_do_test(struct unit_test_state *uts, struct 
unit_test *test,
ut_assertok(do_autoprobe(uts));
if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
(test->flags & UT_TESTF_SCAN_FDT))
-   ut_assertok(dm_extended_scan_fdt(gd->fdt_blob, false));
+   ut_assertok(dm_extended_scan(false));
 
/*
 * Silence the console and rely on console recording to get
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 10/11] dm: core: Drop unused parameter from dm_scan_fdt()

2020-11-28 Thread Simon Glass
This doesn't need to be passed the devicetree anymore. Drop it.

Signed-off-by: Simon Glass 
---

 drivers/core/root.c | 9 -
 include/dm/root.h   | 3 +--
 test/dm/core.c  | 2 +-
 test/dm/test-fdt.c  | 2 +-
 test/dm/test-main.c | 2 +-
 5 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 62efa0fedcf..54498b2df71 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -248,13 +248,12 @@ int dm_scan_fdt_dev(struct udevice *dev)
gd->flags & GD_FLG_RELOC ? false : true);
 }
 
-int dm_scan_fdt(const void *blob, bool pre_reloc_only)
+int dm_scan_fdt(bool pre_reloc_only)
 {
return dm_scan_fdt_node(gd->dm_root, ofnode_root(), pre_reloc_only);
 }
 
-static int dm_scan_fdt_ofnode_path(const void *blob, const char *path,
-  bool pre_reloc_only)
+static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only)
 {
ofnode node;
 
@@ -272,7 +271,7 @@ int dm_extended_scan_fdt(const void *blob, bool 
pre_reloc_only)
"/firmware"
};
 
-   ret = dm_scan_fdt(blob, pre_reloc_only);
+   ret = dm_scan_fdt(pre_reloc_only);
if (ret) {
debug("dm_scan_fdt() failed: %d\n", ret);
return ret;
@@ -280,7 +279,7 @@ int dm_extended_scan_fdt(const void *blob, bool 
pre_reloc_only)
 
/* Some nodes aren't devices themselves but may contain some */
for (i = 0; i < ARRAY_SIZE(nodes); i++) {
-   ret = dm_scan_fdt_ofnode_path(blob, nodes[i], pre_reloc_only);
+   ret = dm_scan_fdt_ofnode_path(nodes[i], pre_reloc_only);
if (ret) {
debug("dm_scan_fdt() scan for %s failed: %d\n",
  nodes[i], ret);
diff --git a/include/dm/root.h b/include/dm/root.h
index c8d629ba9bf..e277ebb9523 100644
--- a/include/dm/root.h
+++ b/include/dm/root.h
@@ -47,12 +47,11 @@ int dm_scan_platdata(bool pre_reloc_only);
  * This scans the device tree and creates a driver for each node. Only
  * the top-level subnodes are examined.
  *
- * @blob: Pointer to device tree blob
  * @pre_reloc_only: If true, bind only nodes with special devicetree 
properties,
  * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
  * @return 0 if OK, -ve on error
  */
-int dm_scan_fdt(const void *blob, bool pre_reloc_only);
+int dm_scan_fdt(bool pre_reloc_only);
 
 /**
  * dm_extended_scan_fdt() - Scan the device tree and bind drivers
diff --git a/test/dm/core.c b/test/dm/core.c
index ba9e60d09cb..71ebb36d88b 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -486,7 +486,7 @@ static int dm_test_leak(struct unit_test_state *uts)
dm_leak_check_start(uts);
 
ut_assertok(dm_scan_platdata(false));
-   ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
+   ut_assertok(dm_scan_fdt(false));
 
/* Scanning the uclass is enough to probe all the devices */
for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) {
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index cc12419ea0f..9507636b630 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -308,7 +308,7 @@ static int dm_test_fdt_pre_reloc(struct unit_test_state 
*uts)
struct uclass *uc;
int ret;
 
-   ret = dm_scan_fdt(gd->fdt_blob, true);
+   ret = dm_scan_fdt(true);
ut_assert(!ret);
 
ret = uclass_get(UCLASS_TEST_FDT, );
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index fd24635006c..2ab73b647e6 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -213,7 +213,7 @@ int dm_test_main(const char *test_name)
ut_assertok(dm_init(CONFIG_IS_ENABLED(OF_LIVE)));
dm_scan_platdata(false);
if (!CONFIG_IS_ENABLED(OF_PLATDATA))
-   dm_scan_fdt(gd->fdt_blob, false);
+   dm_scan_fdt(false);
 
return uts->fail_count ? CMD_RET_FAILURE : 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 07/11] dm: core: Drop device_bind_offset()

2020-11-28 Thread Simon Glass
This function is not needed since the standard device_bind() can be used
instead. Drop it.

Signed-off-by: Simon Glass 
---

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

diff --git a/drivers/core/device.c b/drivers/core/device.c
index c8a219d77b3..79afaf06290 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -232,14 +232,6 @@ int device_bind_with_driver_data(struct udevice *parent,
  0, devp);
 }
 
-int device_bind_offset(struct udevice *parent, const struct driver *drv,
-  const char *name, void *platdata, int of_offset,
-  struct udevice **devp)
-{
-   return device_bind_common(parent, drv, name, platdata, 0,
- offset_to_ofnode(of_offset), 0, devp);
-}
-
 int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, ofnode node,
struct udevice **devp)
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 6f4f8510f7e..578a483497e 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -16,7 +16,7 @@ struct device_node;
 struct udevice;
 
 /**
- * device_bind_offset() - Create a device and bind it to a driver
+ * device_bind() - Create a device and bind it to a driver
  *
  * Called to set up a new device attached to a driver. The device will either
  * have platdata, or a device tree node which can be used to create the
@@ -31,15 +31,11 @@ struct udevice;
  * @platdata: Pointer to data for this device - the structure is device-
  * specific but may include the device's I/O address, etc.. This is NULL for
  * devices which use device tree.
- * @of_offset: Offset of device tree node for this device. This is -1 for
- * devices which don't use device tree.
+ * @ofnode: Devicetree node for this device. This is ofnode_null() for
+ * devices which don't use devicetree or don't have a node.
  * @devp: if non-NULL, returns a pointer to the bound device
  * @return 0 if OK, -ve on error
  */
-int device_bind_offset(struct udevice *parent, const struct driver *drv,
-   const char *name, void *platdata, int of_offset,
-   struct udevice **devp);
-
 int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, ofnode node,
struct udevice **devp);
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 08/11] dm: core: Add an ofnode function to get the devicetree root

2020-11-28 Thread Simon Glass
This is needed in at least one place. Avoid the conditional code in root.c
by adding this inline function.

Signed-off-by: Simon Glass 
---

 drivers/core/root.c |  8 ++--
 include/dm/ofnode.h | 12 
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 5f10d7a39c7..9ee65504e6e 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -147,12 +147,8 @@ int dm_init(bool of_live)
ret = device_bind_by_name(NULL, false, _info, _ROOT_NON_CONST);
if (ret)
return ret;
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-   if (CONFIG_IS_ENABLED(OF_LIVE) && of_live)
-   DM_ROOT_NON_CONST->node = np_to_ofnode(gd_of_root());
-   else
-   DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
-#endif
+   if (CONFIG_IS_ENABLED(OF_CONTROL))
+   DM_ROOT_NON_CONST->node = ofnode_root();
ret = device_probe(DM_ROOT_NON_CONST);
if (ret)
return ret;
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index ee8c44a71ec..53f04ac91d0 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -218,6 +218,18 @@ static inline ofnode ofnode_null(void)
return node;
 }
 
+static inline ofnode ofnode_root(void)
+{
+   ofnode node;
+
+   if (of_live_active())
+   node.np = gd_of_root();
+   else
+   node.of_offset = 0;
+
+   return node;
+}
+
 /**
  * ofnode_read_u32() - Read a 32-bit integer from a property
  *
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 05/11] dm: Drop uses of dev_set_of_offset()

2020-11-28 Thread Simon Glass
The need for this can be avoided by passing the correct node to the
device_bind() function.

Signed-off-by: Simon Glass 
---

 drivers/gpio/mt7621_gpio.c| 3 +--
 drivers/gpio/s5p_gpio.c   | 4 +---
 drivers/gpio/sunxi_gpio.c | 3 +--
 drivers/gpio/tegra186_gpio.c  | 3 +--
 drivers/gpio/tegra_gpio.c | 5 ++---
 drivers/pinctrl/meson/pinctrl-meson.c | 1 -
 6 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/mt7621_gpio.c b/drivers/gpio/mt7621_gpio.c
index 8b41e34844e..ea51291e237 100644
--- a/drivers/gpio/mt7621_gpio.c
+++ b/drivers/gpio/mt7621_gpio.c
@@ -158,11 +158,10 @@ static int gpio_mediatek_bind(struct udevice *parent)
plat->bank = bank;
 
ret = device_bind(parent, parent->driver, plat->bank_name, plat,
- ofnode_null(), );
+ node, );
if (ret)
return ret;
 
-   dev->node = node;
bank++;
}
 
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index d6054c4a6dd..ec8d54922d3 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -333,12 +333,10 @@ static int gpio_exynos_bind(struct udevice *parent)
 
plat->bank_name = fdt_get_name(blob, node, NULL);
ret = device_bind(parent, parent->driver, plat->bank_name, plat,
- ofnode_null(), );
+ offset_to_ofnode(node), );
if (ret)
return ret;
 
-   dev_set_of_offset(dev, node);
-
reg = dev_read_addr(dev);
if (reg != FDT_ADDR_T_NONE)
bank = (struct s5p_gpio_bank *)((ulong)base + reg);
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index b6b0e9acbdb..dea71a7f340 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -306,10 +306,9 @@ static int gpio_sunxi_bind(struct udevice *parent)
plat->gpio_count = SUNXI_GPIOS_PER_BANK;
 
ret = device_bind(parent, parent->driver, plat->bank_name, plat,
- ofnode_null(), );
+ dev_ofnode(parent), );
if (ret)
return ret;
-   dev_set_of_offset(dev, dev_of_offset(parent));
}
 
return 0;
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index bcc322c3b02..ad97e13a1cb 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -191,10 +191,9 @@ static int tegra186_gpio_bind(struct udevice *parent)
plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);
 
ret = device_bind(parent, parent->driver, plat->name, plat,
- ofnode_null(), );
+ dev_ofnode(parent), );
if (ret)
return ret;
-   dev_set_of_offset(dev, dev_of_offset(parent));
}
 
return 0;
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 3877ee659af..22d25313227 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -361,11 +361,10 @@ static int gpio_tegra_bind(struct udevice *parent)
plat->port_name = gpio_port_name(base_port);
 
ret = device_bind(parent, parent->driver,
- plat->port_name, plat, ofnode_null(),
- );
+ plat->port_name, plat,
+ dev_ofnode(parent), );
if (ret)
return ret;
-   dev_set_of_offset(dev, dev_of_offset(parent));
}
}
 
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c 
b/drivers/pinctrl/meson/pinctrl-meson.c
index c35e4c42a09..37bddb14e08 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -422,7 +422,6 @@ int meson_pinctrl_probe(struct udevice *dev)
/* Create child device UCLASS_GPIO and bind it */
device_bind(dev, priv->data->gpio_driver, name, NULL,
offset_to_ofnode(gpio), _dev);
-   dev_set_of_offset(gpio_dev, gpio);
 
return 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 04/11] dm: Remove uses of device_bind_offset()

2020-11-28 Thread Simon Glass
This function is not needed since the standard device_bind() can be used
instead.

Signed-off-by: Simon Glass 
---

 arch/x86/cpu/apollolake/spl.c   |  2 +-
 drivers/clk/at91/compat.c   | 20 
 drivers/clk/clk.c   |  2 +-
 drivers/gpio/mt7621_gpio.c  |  4 ++--
 drivers/gpio/s5p_gpio.c |  4 ++--
 drivers/gpio/sunxi_gpio.c   |  4 ++--
 drivers/gpio/tegra186_gpio.c|  4 ++--
 drivers/gpio/tegra_gpio.c   |  6 +++---
 drivers/net/mvpp2.c |  4 ++--
 drivers/pinctrl/broadcom/pinctrl-bcm283x.c  |  5 ++---
 drivers/pinctrl/meson/pinctrl-meson.c   |  4 +++-
 drivers/pinctrl/mscc/pinctrl-jr2.c  |  4 ++--
 drivers/pinctrl/mscc/pinctrl-luton.c|  4 ++--
 drivers/pinctrl/mscc/pinctrl-ocelot.c   |  4 ++--
 drivers/pinctrl/mscc/pinctrl-serval.c   |  4 ++--
 drivers/pinctrl/mscc/pinctrl-servalt.c  |  4 ++--
 drivers/pinctrl/mvebu/pinctrl-armada-37xx.c |  8 
 drivers/power/regulator/Kconfig |  2 +-
 include/dm/device-internal.h|  4 ++--
 include/power/regulator.h   |  2 +-
 20 files changed, 46 insertions(+), 49 deletions(-)

diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c
index 1f75e1894b7..089b37c59f8 100644
--- a/arch/x86/cpu/apollolake/spl.c
+++ b/arch/x86/cpu/apollolake/spl.c
@@ -86,7 +86,7 @@ static int apl_flash_probe(struct udevice *dev)
 /*
  * Manually set the parent of the SPI flash to SPI, since dtoc doesn't. We also
  * need to allocate the parent_platdata since by the time this function is
- * called device_bind_offset() has already gone past that step.
+ * called device_bind() has already gone past that step.
  */
 static int apl_flash_bind(struct udevice *dev)
 {
diff --git a/drivers/clk/at91/compat.c b/drivers/clk/at91/compat.c
index 9563285674b..afd67b290d8 100644
--- a/drivers/clk/at91/compat.c
+++ b/drivers/clk/at91/compat.c
@@ -62,34 +62,30 @@ static int at91_pmc_core_probe(struct udevice *dev)
  */
 int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
 {
-   const void *fdt = gd->fdt_blob;
-   int offset = dev_of_offset(dev);
+   ofnode parent = dev_ofnode(dev);
+   ofnode node;
bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
const char *name;
int ret;
 
-   for (offset = fdt_first_subnode(fdt, offset);
-offset > 0;
-offset = fdt_next_subnode(fdt, offset)) {
-   if (pre_reloc_only &&
-   !ofnode_pre_reloc(offset_to_ofnode(offset)))
+   ofnode_for_each_subnode(node, parent) {
+   if (pre_reloc_only && !ofnode_pre_reloc(node))
continue;
/*
 * If this node has "compatible" property, this is not
 * a clock sub-node, but a normal device. skip.
 */
-   fdt_get_property(fdt, offset, "compatible", );
-   if (ret >= 0)
+   if (ofnode_read_prop(node, "compatible", NULL))
continue;
 
if (ret != -FDT_ERR_NOTFOUND)
return ret;
 
-   name = fdt_get_name(fdt, offset, NULL);
+   name = ofnode_get_name(node);
if (!name)
return -EINVAL;
-   ret = device_bind_driver_to_node(dev, drv_name, name,
-   offset_to_ofnode(offset), NULL);
+   ret = device_bind_driver_to_node(dev, drv_name, name, node,
+NULL);
if (ret)
return ret;
}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1fa9bec6fea..928ad13641a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -36,7 +36,7 @@ int clk_register(struct clk *clk, const char *drv_name,
return -ENOENT;
}
 
-   ret = device_bind_offset(parent, drv, name, NULL, -1, >dev);
+   ret = device_bind(parent, drv, name, NULL, ofnode_null(), >dev);
if (ret) {
printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
   ret);
diff --git a/drivers/gpio/mt7621_gpio.c b/drivers/gpio/mt7621_gpio.c
index b64bc838a31..8b41e34844e 100644
--- a/drivers/gpio/mt7621_gpio.c
+++ b/drivers/gpio/mt7621_gpio.c
@@ -157,8 +157,8 @@ static int gpio_mediatek_bind(struct udevice *parent)
plat->gpio_count = MTK_BANK_WIDTH;
plat->bank = bank;
 
-   ret = device_bind_offset(parent, parent->driver,
-plat->bank_name, plat, -1, );
+   ret = device_bind(parent, parent->driver, plat->bank_name, plat,
+ ofnode_null(), );
if (ret)
return ret;
 
diff --git 

[PATCH 06/11] dm: core: Drop dev_set_of_offset()

2020-11-28 Thread Simon Glass
This pre-livetree function is not needed anymore. Drop it.

Signed-off-by: Simon Glass 
---

 include/dm/device.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/include/dm/device.h b/include/dm/device.h
index 5bef4842470..25a77d08b9d 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -177,11 +177,6 @@ static inline int dev_of_offset(const struct udevice *dev)
return ofnode_to_offset(dev->node);
 }
 
-static inline void dev_set_of_offset(struct udevice *dev, int of_offset)
-{
-   dev->node = offset_to_ofnode(of_offset);
-}
-
 static inline bool dev_has_of_node(struct udevice *dev)
 {
return ofnode_valid(dev->node);
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 03/11] dm: core: Add a livetree function to check node status

2020-11-28 Thread Simon Glass
Add a way to find out if a node is enabled or not, based on its 'status'
property.

Signed-off-by: Simon Glass 
---

 drivers/core/ofnode.c | 10 ++
 include/dm/ofnode.h   | 11 +++
 test/dm/ofnode.c  | 12 
 3 files changed, 33 insertions(+)

diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index a68076bf351..87072094f32 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -226,6 +226,16 @@ int ofnode_read_u32_array(ofnode node, const char 
*propname,
}
 }
 
+bool ofnode_is_enabled(ofnode node)
+{
+   if (ofnode_is_np(node)) {
+   return of_device_is_available(ofnode_to_np(node));
+   } else {
+   return fdtdec_get_is_enabled(gd->fdt_blob,
+ofnode_to_offset(node));
+   }
+}
+
 ofnode ofnode_first_subnode(ofnode node)
 {
assert(ofnode_valid(node));
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index ced7f6ffb25..ee8c44a71ec 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -345,6 +345,17 @@ const char *ofnode_read_string(ofnode node, const char 
*propname);
  */
 int ofnode_read_u32_array(ofnode node, const char *propname,
  u32 *out_values, size_t sz);
+/**
+ * ofnode_is_enabled() - Checks whether a node is enabled.
+ * This looks for a 'status' property. If this exists, then returns true if
+ * the status is 'okay' and false otherwise. If there is no status property,
+ * it returns true on the assumption that anything mentioned should be enabled
+ * by default.
+ *
+ * @node: node to examine
+ * @return false (not enabled) or true (enabled)
+ */
+bool ofnode_is_enabled(ofnode node);
 
 /**
  * ofnode_read_bool() - read a boolean value from a property
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index fb1ceb13180..c5391342962 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -249,3 +249,15 @@ static int dm_test_ofnode_get_child_count(struct 
unit_test_state *uts)
 }
 DM_TEST(dm_test_ofnode_get_child_count,
UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_ofnode_is_enabled(struct unit_test_state *uts)
+{
+   ofnode root_node = ofnode_path("/");
+   ofnode node = ofnode_path("/usb@0");
+
+   ut_assert(ofnode_is_enabled(root_node));
+   ut_assert(!ofnode_is_enabled(node));
+
+   return 0;
+}
+DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.29.2.454.gaff20da3a2-goog



[PATCH 02/11] dm: core: Rename device_bind_ofnode() to device_bind()

2020-11-28 Thread Simon Glass
This is the standard function to use when binding devices. Drop the
'_ofnode' suffix to make this clear.

Signed-off-by: Simon Glass 
---

 drivers/core/device.c | 6 +++---
 drivers/firmware/scmi/scmi_agent-uclass.c | 4 ++--
 drivers/gpio/dwapb_gpio.c | 4 ++--
 drivers/misc/i2c_eeprom.c | 4 ++--
 drivers/mtd/spi/sandbox.c | 2 +-
 drivers/pci/pci-uclass.c  | 4 ++--
 drivers/pci/pci_mvebu.c   | 4 ++--
 drivers/usb/host/usb-uclass.c | 4 ++--
 include/dm/device-internal.h  | 6 +++---
 test/dm/core.c| 4 ++--
 10 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 081dd1f7780..c8a219d77b3 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -240,9 +240,9 @@ int device_bind_offset(struct udevice *parent, const struct 
driver *drv,
  offset_to_ofnode(of_offset), 0, devp);
 }
 
-int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
-  const char *name, void *platdata, ofnode node,
-  struct udevice **devp)
+int device_bind(struct udevice *parent, const struct driver *drv,
+   const char *name, void *platdata, ofnode node,
+   struct udevice **devp)
 {
return device_bind_common(parent, drv, name, platdata, 0, node, 0,
  devp);
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index 7dc533149b6..b3d3f0a51b0 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -89,8 +89,8 @@ static int scmi_bind_protocols(struct udevice *dev)
continue;
}
 
-   ret = device_bind_ofnode(dev, drv, ofnode_get_name(node),
-NULL, node, NULL);
+   ret = device_bind(dev, drv, ofnode_get_name(node), NULL, node,
+ NULL);
if (ret)
break;
}
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 37916e77716..cf20a5024e0 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -202,8 +202,8 @@ static int gpio_dwapb_bind(struct udevice *dev)
}
}
 
-   ret = device_bind_ofnode(dev, dev->driver, plat->name,
-plat, node, );
+   ret = device_bind(dev, dev->driver, plat->name, plat, node,
+ );
if (ret)
return ret;
 
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index 3651ba4871e..92e18356254 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -131,8 +131,8 @@ static int i2c_eeprom_std_bind(struct udevice *dev)
if (!name)
continue;
 
-   device_bind_ofnode(dev, DM_GET_DRIVER(i2c_eeprom_partition),
-  name, NULL, partition, NULL);
+   device_bind(dev, DM_GET_DRIVER(i2c_eeprom_partition), name,
+   NULL, partition, NULL);
}
 
return 0;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 0b602dc9140..1d0c1cb3fa2 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -538,7 +538,7 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int 
busnum, int cs,
str = strdup(name);
if (!str)
return -ENOMEM;
-   ret = device_bind_ofnode(bus, drv, str, NULL, node, );
+   ret = device_bind(bus, drv, str, NULL, node, );
if (ret) {
free(str);
printf("Cannot create emul device for spec '%s' (err=%d)\n",
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index eb07d253011..9230cfe88b5 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -750,8 +750,8 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 * find another driver. For now this doesn't seem
 * necesssary, so just bind the first match.
 */
-   ret = device_bind_ofnode(parent, drv, drv->name, NULL,
-node, );
+   ret = device_bind(parent, drv, drv->name, NULL, node,
+ );
if (ret)
goto error;
debug("%s: Match found: %s\n", __func__, drv->name);
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index c9afe751501..ba1c139dbc5 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -501,8 +501,8 @@ static int 

[PATCH 01/11] dm: core: Rename device_bind() to device_bind_offset()

2020-11-28 Thread Simon Glass
This function is not necessary anymore, since device_bind_ofnode() does
the same thing and works with both flattree and livetree.

Rename it to indicate that it is special.

Signed-off-by: Simon Glass 
---

 arch/x86/cpu/apollolake/spl.c   | 2 +-
 drivers/clk/clk.c   | 2 +-
 drivers/core/device.c   | 6 +++---
 drivers/gpio/mt7621_gpio.c  | 4 ++--
 drivers/gpio/s5p_gpio.c | 4 ++--
 drivers/gpio/sunxi_gpio.c   | 4 ++--
 drivers/gpio/tegra186_gpio.c| 4 ++--
 drivers/gpio/tegra_gpio.c   | 5 +++--
 drivers/net/mvpp2.c | 2 +-
 drivers/pinctrl/broadcom/pinctrl-bcm283x.c  | 5 +++--
 drivers/pinctrl/meson/pinctrl-meson.c   | 2 +-
 drivers/pinctrl/mscc/pinctrl-jr2.c  | 4 ++--
 drivers/pinctrl/mscc/pinctrl-luton.c| 4 ++--
 drivers/pinctrl/mscc/pinctrl-ocelot.c   | 4 ++--
 drivers/pinctrl/mscc/pinctrl-serval.c   | 4 ++--
 drivers/pinctrl/mscc/pinctrl-servalt.c  | 4 ++--
 drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 4 ++--
 drivers/power/regulator/Kconfig | 2 +-
 include/dm/device-internal.h| 8 
 include/power/regulator.h   | 2 +-
 20 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c
index 089b37c59f8..1f75e1894b7 100644
--- a/arch/x86/cpu/apollolake/spl.c
+++ b/arch/x86/cpu/apollolake/spl.c
@@ -86,7 +86,7 @@ static int apl_flash_probe(struct udevice *dev)
 /*
  * Manually set the parent of the SPI flash to SPI, since dtoc doesn't. We also
  * need to allocate the parent_platdata since by the time this function is
- * called device_bind() has already gone past that step.
+ * called device_bind_offset() has already gone past that step.
  */
 static int apl_flash_bind(struct udevice *dev)
 {
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 319808d433f..1fa9bec6fea 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -36,7 +36,7 @@ int clk_register(struct clk *clk, const char *drv_name,
return -ENOENT;
}
 
-   ret = device_bind(parent, drv, name, NULL, -1, >dev);
+   ret = device_bind_offset(parent, drv, name, NULL, -1, >dev);
if (ret) {
printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
   ret);
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 4b3dcb3b379..081dd1f7780 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -232,9 +232,9 @@ int device_bind_with_driver_data(struct udevice *parent,
  0, devp);
 }
 
-int device_bind(struct udevice *parent, const struct driver *drv,
-   const char *name, void *platdata, int of_offset,
-   struct udevice **devp)
+int device_bind_offset(struct udevice *parent, const struct driver *drv,
+  const char *name, void *platdata, int of_offset,
+  struct udevice **devp)
 {
return device_bind_common(parent, drv, name, platdata, 0,
  offset_to_ofnode(of_offset), 0, devp);
diff --git a/drivers/gpio/mt7621_gpio.c b/drivers/gpio/mt7621_gpio.c
index 612413e17bc..b64bc838a31 100644
--- a/drivers/gpio/mt7621_gpio.c
+++ b/drivers/gpio/mt7621_gpio.c
@@ -157,8 +157,8 @@ static int gpio_mediatek_bind(struct udevice *parent)
plat->gpio_count = MTK_BANK_WIDTH;
plat->bank = bank;
 
-   ret = device_bind(parent, parent->driver,
- plat->bank_name, plat, -1, );
+   ret = device_bind_offset(parent, parent->driver,
+plat->bank_name, plat, -1, );
if (ret)
return ret;
 
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index c78227f4da3..4f9fedd6129 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -332,8 +332,8 @@ static int gpio_exynos_bind(struct udevice *parent)
return -ENOMEM;
 
plat->bank_name = fdt_get_name(blob, node, NULL);
-   ret = device_bind(parent, parent->driver,
- plat->bank_name, plat, -1, );
+   ret = device_bind_offset(parent, parent->driver,
+plat->bank_name, plat, -1, );
if (ret)
return ret;
 
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 02c3471b568..f18f0c8152c 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -305,8 +305,8 @@ static int gpio_sunxi_bind(struct udevice *parent)
plat->bank_name = gpio_bank_name(soc_data->start + bank);
plat->gpio_count = SUNXI_GPIOS_PER_BANK;
 
-   ret = device_bind(parent, parent->driver,
-   

[U-Boot] Please pull from u-boot-i2c

2020-11-28 Thread Heiko Schocher
Hello Tom,

The following changes since commit 7889951d0f56eab746a7c8fde350a022ba0361ca:

  Merge tag 'u-boot-stm32-20201125' of 
https://gitlab.denx.de/u-boot/custodians/u-boot-stm
(2020-11-25 11:00:52 -0500)

are available in the Git repository at:

  https://gitlab.denx.de/u-boot/custodians/u-boot-i2c.git master

for you to fetch changes up to f517e5fe98598d933e050b4005af6d745820bdb1:

  riscv: sifive/fu540: kconfig: Enable support for Opencores I2C controller 
(2020-11-28 08:30:41 +0100)


Baruch Siach (1):
  i2c: mvtwsi: disable i2c slave also on Armada 8k

Pragnesh Patel (2):
  i2c: ocores: add i2c driver for OpenCores I2C controller
  riscv: sifive/fu540: kconfig: Enable support for Opencores I2C controller

Simon Glass (1):
  i2c: designware_i2c: Don't warn if no reset controller

 arch/riscv/cpu/fu540/Kconfig |   2 +
 board/sifive/fu540/Kconfig   |   1 +
 drivers/i2c/Kconfig  |   7 ++
 drivers/i2c/Makefile |   1 +
 drivers/i2c/designware_i2c.c |   8 +-
 drivers/i2c/mvtwsi.c |   3 +-
 drivers/i2c/ocores_i2c.c | 637
+
 7 files changed, 655 insertions(+), 4 deletions(-)
 create mode 100644 drivers/i2c/ocores_i2c.c

Travis build:
https://travis-ci.org/github/hsdenx/u-boot-i2c/builds/746392479

Sorry for being late, but I am a little under stress ...

bye,
Heiko
-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: h...@denx.de


Re: [PATCH v3 0/2] Add OpenCores I2C controller driver

2020-11-28 Thread Heiko Schocher
Hello Pragnesh,

Am 14.11.20 um 10:12 schrieb Pragnesh Patel:
> This driver has been tested on HiFive Unleashed with a PMOD based
> RTCC sensor connected to I2C pins J1 header of the board.
> 
> This series is available here [1] for testing
> [1] https://github.com/pragnesh26992/u-boot/tree/i2c
> 
> Tested-by: Sagar Shrikant Kadam 
> 
> Changes in v3:
> - Rebase to master and add missing #include 
> 
> Changes in v2:
> - Remove TYPE_SIFIVE_REV0 flag
> - Update the Opencores I2C Controller Link
> 
> U-Boot Logs for reference:
> 
> Hit any key to stop autoboot:  0
> => i2c dev 0
> Setting bus to 0
> => i2c probe
> Valid chip addresses: 57 6F
> => i2c md 0x57 0x0 1
> : a5.
> => i2c mw 0x57 0x0 0x5a 1
> => i2c md 0x57 0x0 1
> : 5aZ
> => i2c md 0x57 0x2 1
> 0002: 99.
> => i2c mw 0x57 0x2 0xa9 1
> => i2c md 0x57 0x2 1
> 0002: a9.
> => i2c md 0x6f 0x20 1
> 0020: 5aZ
> => i2c md 0x6f 0x5f 1
> 005f: a5.
> => i2c mw 0x6f 0x20 0xa9 1
> => i2c mw 0x6f 0x5f 0xa9 1
> => i2c md 0x6f 0x20 1
> 0020: a9.
> => i2c md 0x6f 0x5f 1
> 005f: a9.
> =>
> 
> Pragnesh Patel (2):
>   i2c: ocores: add i2c driver for OpenCores I2C controller
>   riscv: sifive/fu540: kconfig: Enable support for Opencores I2C
> controller
> 
>  arch/riscv/cpu/fu540/Kconfig |   2 +
>  board/sifive/fu540/Kconfig   |   1 +
>  drivers/i2c/Kconfig  |   7 +
>  drivers/i2c/Makefile |   1 +
>  drivers/i2c/ocores_i2c.c | 637 +++
>  5 files changed, 648 insertions(+)
>  create mode 100644 drivers/i2c/ocores_i2c.c

Series applied to u-boot-i2c

Thanks!

bye,
Heiko

-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: h...@denx.de


Re: [PATCH] i2c: designware_i2c: Don't warn if no reset controller

2020-11-28 Thread Heiko Schocher
Hello Simon,

Am 09.11.20 um 15:12 schrieb Simon Glass:
> At present if CONFIG_RESET is not enabled, this code shows a warning:
> 
>   designware_i2c_ofdata_to_platdata() i2c_designware_pci i2c2@16,0:
>   Can't get reset: -524
> 
> Avoid this by checking if reset is supported, first.
> 
> Fixes: 622597dee4f ("i2c: designware: add reset ctrl to driver")
> Signed-off-by: Simon Glass 
> ---
> 
>  drivers/i2c/designware_i2c.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Applied to u-boot-i2c.git

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: h...@denx.de


Re: [PATCH] i2c: mvtwsi: disable i2c slave also on Armada 8k

2020-11-28 Thread Heiko Schocher
Hello Baruch,

Am 01.10.20 um 13:49 schrieb Baruch Siach:
> The hidden I2C slave is also present on the Armada 8k AP806. Testing
> shows that this I2C slave causes the same issues as Armada 38x.
> Disabling that I2C slave fixes all these issues.
> 
> I2C blocks on the Armada 8k CP110 are not affected.
> 
> Extend the I2C slave disable to Armada 8k as well.
> 
> Cc: Stefan Roese 
> Signed-off-by: Baruch Siach 
> ---
>  drivers/i2c/mvtwsi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Applied to u-boot-i2c.git

thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: h...@denx.de


[PATCH v4 1/2] pinctrl: renesas: Make sure the pin type is updated after setting the MUX

2020-11-28 Thread Lad Prabhakar
By default on startup all the pin types are configured to
PINMUX_TYPE_NONE (in sh_pfc_map_pins()), when pin is set as GPIO the
pin type is updated to PINMUX_TYPE_GPIO. But the type is not updated
when the pin is set as a function in sh_pfc_pinctrl_pin_set() or
sh_pfc_pinctrl_group_set() calls (these calls only set the MUX if
the pin type is PINMUX_TYPE_NONE ie unused).

So with the current implementation pin functionality could be overwritten
silently, for example if the same pin is added for SPI and serial.

This patch makes sure of updating pin type after every successful call to
sh_pfc_config_mux() and thus fixing from pin functionality to be
overwritten. Also a warning message is printed if the current pin is being
overwritten before abort.

This also avoids pin re-muxing to same type that is for example from
command line device is asked to re-probe/select (mmc dev x) we return
early with success in this case as the pin is already muxed.

Signed-off-by: Lad Prabhakar 
Reviewed-by: Biju Das 
---
 drivers/pinctrl/renesas/pfc.c | 52 +++
 1 file changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 6cccd33c40..1b1f583ee6 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -45,6 +45,7 @@ enum sh_pfc_model {
 
 struct sh_pfc_pin_config {
u32 type;
+   const char *name;
 };
 
 struct sh_pfc_pinctrl {
@@ -488,14 +489,21 @@ static int sh_pfc_gpio_request_enable(struct udevice *dev,
idx = sh_pfc_get_pin_index(pfc, pin->pin);
cfg = >configs[idx];
 
-   if (cfg->type != PINMUX_TYPE_NONE)
+   if (cfg->type != PINMUX_TYPE_NONE) {
+   if (!strcmp(cfg->name, pin->name))
+   return 0;
+
+   dev_err(pfc->dev, "Pin already used as %s\n",
+   cfg->name);
return -EBUSY;
+   }
 
ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
if (ret)
return ret;
 
cfg->type = PINMUX_TYPE_GPIO;
+   cfg->name = "gpio";
 
return 0;
 }
@@ -525,6 +533,7 @@ static int sh_pfc_gpio_disable_free(struct udevice *dev,
cfg = >configs[idx];
 
cfg->type = PINMUX_TYPE_NONE;
+   cfg->name = "none";
 
return 0;
 }
@@ -538,11 +547,25 @@ static int sh_pfc_pinctrl_pin_set(struct udevice *dev, 
unsigned pin_selector,
const struct sh_pfc_pin *pin = >pfc.info->pins[pin_selector];
int idx = sh_pfc_get_pin_index(pfc, pin->pin);
struct sh_pfc_pin_config *cfg = >configs[idx];
+   int ret;
 
-   if (cfg->type != PINMUX_TYPE_NONE)
+   if (cfg->type != PINMUX_TYPE_NONE) {
+   if (!strcmp(cfg->name, pin->name))
+   return 0;
+
+   dev_err(pfc->dev, "Pin already used as %s\n",
+   cfg->name);
return -EBUSY;
+   }
+
+   ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION);
+   if (ret)
+   return ret;
 
-   return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION);
+   cfg->type = PINMUX_TYPE_FUNCTION;
+   cfg->name = "function";
+
+   return 0;
 }
 
 static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned 
group_selector,
@@ -552,23 +575,41 @@ static int sh_pfc_pinctrl_group_set(struct udevice *dev, 
unsigned group_selector
struct sh_pfc_pinctrl *pmx = >pmx;
struct sh_pfc *pfc = >pfc;
const struct sh_pfc_pin_group *grp = 
>pfc.info->groups[group_selector];
+   bool grp_pins_configured = true;
+   struct sh_pfc_pin_config *cfg;
unsigned int i;
int ret = 0;
+   int idx;
 
for (i = 0; i < grp->nr_pins; ++i) {
-   int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
-   struct sh_pfc_pin_config *cfg = >configs[idx];
+   idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
+   cfg = >configs[idx];
 
if (cfg->type != PINMUX_TYPE_NONE) {
+   if (!strcmp(cfg->name, grp->name))
+   continue;
+
+   dev_err(pfc->dev, "Pin already used as %s\n",
+   cfg->name);
ret = -EBUSY;
goto done;
+   } else {
+   grp_pins_configured = false;
}
}
 
+   if (grp_pins_configured)
+   return 0;
+
for (i = 0; i < grp->nr_pins; ++i) {
ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION);
if (ret < 0)
break;
+
+   idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
+   cfg = >configs[idx];
+   cfg->type = PINMUX_TYPE_FUNCTION;
+   cfg->name = priv->pfc.info->groups[group_selector].name;
}
 
 done:
@@ -805,6 +846,7 @@ static int 

[PATCH v4 2/2] pinctrl: renesas: Implement get_pin_muxing() callback

2020-11-28 Thread Lad Prabhakar
Implement get_pin_muxing() callback so that pinmux status
command can be used on Renesas platforms.

Signed-off-by: Lad Prabhakar 
Reviewed-by: Biju Das 
---
 drivers/pinctrl/renesas/pfc.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 1b1f583ee6..c45fdca64d 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -450,6 +450,30 @@ static const char *sh_pfc_pinctrl_get_group_name(struct 
udevice *dev,
return priv->pfc.info->groups[selector].name;
 }
 
+static int sh_pfc_pinctrl_get_pin_muxing(struct udevice *dev,
+unsigned int selector,
+char *buf, int size)
+{
+   struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
+   struct sh_pfc_pinctrl *pmx = >pmx;
+   struct sh_pfc *pfc = >pfc;
+   struct sh_pfc_pin_config *cfg;
+   const struct sh_pfc_pin *pin;
+   int idx;
+
+   pin = >pfc.info->pins[selector];
+   if (!pin) {
+   snprintf(buf, size, "Unknown");
+   return -EINVAL;
+   }
+
+   idx = sh_pfc_get_pin_index(pfc, pin->pin);
+   cfg = >configs[idx];
+   snprintf(buf, size, "%s", cfg->name);
+
+   return 0;
+}
+
 static int sh_pfc_pinctrl_get_functions_count(struct udevice *dev)
 {
struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
@@ -816,6 +840,7 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = {
.get_pin_name   = sh_pfc_pinctrl_get_pin_name,
.get_groups_count   = sh_pfc_pinctrl_get_groups_count,
.get_group_name = sh_pfc_pinctrl_get_group_name,
+   .get_pin_muxing = sh_pfc_pinctrl_get_pin_muxing,
.get_functions_count= sh_pfc_pinctrl_get_functions_count,
.get_function_name  = sh_pfc_pinctrl_get_function_name,
 
-- 
2.17.1



[PATCH v4 0/2] pinctrl: renesas: trivial fixes and enhancements

2020-11-28 Thread Lad Prabhakar
Hi All,

This patch series includes trivial fixes and enhancements to
renesas pfc driver.

Cheers,
Prabhakar

v3->v4
* Avoided pin to be re-muxed for the same device.

v2->v3
* Patch 1/2 print a warning message if the current pin is being overwritten
  before abort as suggested by Marek.
* Patch 2/2 unchanged

v1->v2
* Patch 1/2 updated commit message
* Patch 2/2 unchanged

Lad Prabhakar (2):
  pinctrl: renesas: Make sure the pin type is updated after setting the
MUX
  pinctrl: renesas: Implement get_pin_muxing() callback

 drivers/pinctrl/renesas/pfc.c | 77 ---
 1 file changed, 72 insertions(+), 5 deletions(-)

-- 
2.17.1



Re: [PATCH] Nokia RX-51: Decrease i2c speed to 100000

2020-11-28 Thread Pali Rohár
On Saturday 28 November 2020 14:02:20 Michael Nazzareno Trimarchi wrote:
> Hi
> 
> On Sat, Nov 28, 2020 at 1:59 PM Pali Rohár  wrote:
> >
> > On Saturday 28 November 2020 13:48:37 Michael Nazzareno Trimarchi wrote:
> > > Hi
> > >
> > > On Sat, Nov 21, 2020 at 11:30 PM Pali Rohár  wrote:
> > > >
> > > > It looks like that i2c bus lot of times timeout on some units. Prior
> > > > migration to CONFIG_DM_I2C i2c speed was set to 
> > > > CONFIG_SYS_OMAP24_I2C_SPEED
> > > > value which was 10. Lower speed fixes timeout problems, so change 
> > > > speed
> > > > back to its previous value.
> > > >
> > > > Signed-off-by: Pali Rohár 
> > > > Fixes: 8d8c18170325 ("Nokia RX-51: Convert to CONFIG_DM_I2C")
> > > > ---
> > > > Please include this patch into U-Boot master branch for 2020.01 release
> > > > to have i2c bus working.
> > > > ---
> > > >  board/nokia/rx51/rx51.c | 4 ++--
> > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c
> > > > index 3d62b5d9ad..2dd41604c9 100644
> > > > --- a/board/nokia/rx51/rx51.c
> > > > +++ b/board/nokia/rx51/rx51.c
> > > > @@ -704,9 +704,9 @@ void board_mmc_power_init(void)
> > > >  }
> > > >
> > > >  static const struct omap_i2c_platdata rx51_i2c[] = {
> > > > -   { I2C_BASE1, 220, OMAP_I2C_REV_V1 },
> > > > +   { I2C_BASE1, 10, OMAP_I2C_REV_V1 },
> > >
> > > I can understand this one. I don't know what kind of speed was before
> >
> > Prior to mentioned commit which is doing conversion to DM, i2c speed was
> > set to 10.
> >
> 
> Does this impact the led?

Yes, it starts working again.

> > > > { I2C_BASE2, 10, OMAP_I2C_REV_V1 },
> > > > -   { I2C_BASE3, 40, OMAP_I2C_REV_V1 },
> > > > +   { I2C_BASE3, 10, OMAP_I2C_REV_V1 },
> > >
> > > Can you report the peripherals have this problem? I mean
> > > a lot of i2c devices can run to 400Khz.
> >
> > Problematic is i2c LED device.
> >
> > > And how are those buses configured in the kernel?
> >
> > It configures it to 220, 10, 40, like prior this patch.
> > In kernel they are working fine. I really do not know why U-Boot has
> > problems...
> >
> 
> Maybe the selected pull up is not the same for pinmux configuration.
> Anyway I suggest only to change the value that impact the device,
> reduce the commit as mimal and describe what is the peripheral was
> involved

Commit is already minimal. It revers back to configuration which was
stable and was working prior DM migration.

> Michael
> 
> > >
> > > Michael
> > >
> > > >  };
> > > >
> > > >  U_BOOT_DEVICES(rx51_i2c) = {
> > > > --
> > > > 2.20.1
> > > >
> > >
> > >
> > > --
> > > Michael Nazzareno Trimarchi
> > > Amarula Solutions BV
> > > COO Co-Founder
> > > Cruquiuskade 47 Amsterdam 1018 AM NL
> > > T. +31(0)851119172
> > > M. +39(0)3479132170
> > > [`as] https://www.amarulasolutions.com
> 
> 
> 
> -- 
> Michael Nazzareno Trimarchi
> Amarula Solutions BV
> COO Co-Founder
> Cruquiuskade 47 Amsterdam 1018 AM NL
> T. +31(0)851119172
> M. +39(0)3479132170
> [`as] https://www.amarulasolutions.com


Re: [PATCH] Nokia RX-51: Decrease i2c speed to 100000

2020-11-28 Thread Michael Nazzareno Trimarchi
Hi

On Sat, Nov 28, 2020 at 1:59 PM Pali Rohár  wrote:
>
> On Saturday 28 November 2020 13:48:37 Michael Nazzareno Trimarchi wrote:
> > Hi
> >
> > On Sat, Nov 21, 2020 at 11:30 PM Pali Rohár  wrote:
> > >
> > > It looks like that i2c bus lot of times timeout on some units. Prior
> > > migration to CONFIG_DM_I2C i2c speed was set to 
> > > CONFIG_SYS_OMAP24_I2C_SPEED
> > > value which was 10. Lower speed fixes timeout problems, so change 
> > > speed
> > > back to its previous value.
> > >
> > > Signed-off-by: Pali Rohár 
> > > Fixes: 8d8c18170325 ("Nokia RX-51: Convert to CONFIG_DM_I2C")
> > > ---
> > > Please include this patch into U-Boot master branch for 2020.01 release
> > > to have i2c bus working.
> > > ---
> > >  board/nokia/rx51/rx51.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c
> > > index 3d62b5d9ad..2dd41604c9 100644
> > > --- a/board/nokia/rx51/rx51.c
> > > +++ b/board/nokia/rx51/rx51.c
> > > @@ -704,9 +704,9 @@ void board_mmc_power_init(void)
> > >  }
> > >
> > >  static const struct omap_i2c_platdata rx51_i2c[] = {
> > > -   { I2C_BASE1, 220, OMAP_I2C_REV_V1 },
> > > +   { I2C_BASE1, 10, OMAP_I2C_REV_V1 },
> >
> > I can understand this one. I don't know what kind of speed was before
>
> Prior to mentioned commit which is doing conversion to DM, i2c speed was
> set to 10.
>

Does this impact the led?

> > > { I2C_BASE2, 10, OMAP_I2C_REV_V1 },
> > > -   { I2C_BASE3, 40, OMAP_I2C_REV_V1 },
> > > +   { I2C_BASE3, 10, OMAP_I2C_REV_V1 },
> >
> > Can you report the peripherals have this problem? I mean
> > a lot of i2c devices can run to 400Khz.
>
> Problematic is i2c LED device.
>
> > And how are those buses configured in the kernel?
>
> It configures it to 220, 10, 40, like prior this patch.
> In kernel they are working fine. I really do not know why U-Boot has
> problems...
>

Maybe the selected pull up is not the same for pinmux configuration.
Anyway I suggest only to change the value that impact the device,
reduce the commit as mimal and describe what is the peripheral was
involved

Michael

> >
> > Michael
> >
> > >  };
> > >
> > >  U_BOOT_DEVICES(rx51_i2c) = {
> > > --
> > > 2.20.1
> > >
> >
> >
> > --
> > Michael Nazzareno Trimarchi
> > Amarula Solutions BV
> > COO Co-Founder
> > Cruquiuskade 47 Amsterdam 1018 AM NL
> > T. +31(0)851119172
> > M. +39(0)3479132170
> > [`as] https://www.amarulasolutions.com



-- 
Michael Nazzareno Trimarchi
Amarula Solutions BV
COO Co-Founder
Cruquiuskade 47 Amsterdam 1018 AM NL
T. +31(0)851119172
M. +39(0)3479132170
[`as] https://www.amarulasolutions.com


Re: [PATCH] Nokia RX-51: Decrease i2c speed to 100000

2020-11-28 Thread Pali Rohár
On Saturday 28 November 2020 13:48:37 Michael Nazzareno Trimarchi wrote:
> Hi
> 
> On Sat, Nov 21, 2020 at 11:30 PM Pali Rohár  wrote:
> >
> > It looks like that i2c bus lot of times timeout on some units. Prior
> > migration to CONFIG_DM_I2C i2c speed was set to CONFIG_SYS_OMAP24_I2C_SPEED
> > value which was 10. Lower speed fixes timeout problems, so change speed
> > back to its previous value.
> >
> > Signed-off-by: Pali Rohár 
> > Fixes: 8d8c18170325 ("Nokia RX-51: Convert to CONFIG_DM_I2C")
> > ---
> > Please include this patch into U-Boot master branch for 2020.01 release
> > to have i2c bus working.
> > ---
> >  board/nokia/rx51/rx51.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c
> > index 3d62b5d9ad..2dd41604c9 100644
> > --- a/board/nokia/rx51/rx51.c
> > +++ b/board/nokia/rx51/rx51.c
> > @@ -704,9 +704,9 @@ void board_mmc_power_init(void)
> >  }
> >
> >  static const struct omap_i2c_platdata rx51_i2c[] = {
> > -   { I2C_BASE1, 220, OMAP_I2C_REV_V1 },
> > +   { I2C_BASE1, 10, OMAP_I2C_REV_V1 },
> 
> I can understand this one. I don't know what kind of speed was before

Prior to mentioned commit which is doing conversion to DM, i2c speed was
set to 10.

> > { I2C_BASE2, 10, OMAP_I2C_REV_V1 },
> > -   { I2C_BASE3, 40, OMAP_I2C_REV_V1 },
> > +   { I2C_BASE3, 10, OMAP_I2C_REV_V1 },
> 
> Can you report the peripherals have this problem? I mean
> a lot of i2c devices can run to 400Khz.

Problematic is i2c LED device.

> And how are those buses configured in the kernel?

It configures it to 220, 10, 40, like prior this patch.
In kernel they are working fine. I really do not know why U-Boot has
problems...

> 
> Michael
> 
> >  };
> >
> >  U_BOOT_DEVICES(rx51_i2c) = {
> > --
> > 2.20.1
> >
> 
> 
> -- 
> Michael Nazzareno Trimarchi
> Amarula Solutions BV
> COO Co-Founder
> Cruquiuskade 47 Amsterdam 1018 AM NL
> T. +31(0)851119172
> M. +39(0)3479132170
> [`as] https://www.amarulasolutions.com


Re: [PATCH] Nokia RX-51: Decrease i2c speed to 100000

2020-11-28 Thread Michael Nazzareno Trimarchi
Hi

On Sat, Nov 21, 2020 at 11:30 PM Pali Rohár  wrote:
>
> It looks like that i2c bus lot of times timeout on some units. Prior
> migration to CONFIG_DM_I2C i2c speed was set to CONFIG_SYS_OMAP24_I2C_SPEED
> value which was 10. Lower speed fixes timeout problems, so change speed
> back to its previous value.
>
> Signed-off-by: Pali Rohár 
> Fixes: 8d8c18170325 ("Nokia RX-51: Convert to CONFIG_DM_I2C")
> ---
> Please include this patch into U-Boot master branch for 2020.01 release
> to have i2c bus working.
> ---
>  board/nokia/rx51/rx51.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c
> index 3d62b5d9ad..2dd41604c9 100644
> --- a/board/nokia/rx51/rx51.c
> +++ b/board/nokia/rx51/rx51.c
> @@ -704,9 +704,9 @@ void board_mmc_power_init(void)
>  }
>
>  static const struct omap_i2c_platdata rx51_i2c[] = {
> -   { I2C_BASE1, 220, OMAP_I2C_REV_V1 },
> +   { I2C_BASE1, 10, OMAP_I2C_REV_V1 },

I can understand this one. I don't know what kind of speed was before

> { I2C_BASE2, 10, OMAP_I2C_REV_V1 },
> -   { I2C_BASE3, 40, OMAP_I2C_REV_V1 },
> +   { I2C_BASE3, 10, OMAP_I2C_REV_V1 },

Can you report the peripherals have this problem? I mean
a lot of i2c devices can run to 400Khz. And how are those buses
configured in the kernel?

Michael

>  };
>
>  U_BOOT_DEVICES(rx51_i2c) = {
> --
> 2.20.1
>


-- 
Michael Nazzareno Trimarchi
Amarula Solutions BV
COO Co-Founder
Cruquiuskade 47 Amsterdam 1018 AM NL
T. +31(0)851119172
M. +39(0)3479132170
[`as] https://www.amarulasolutions.com


Re: [PATCH] Nokia RX-51: Decrease i2c speed to 100000

2020-11-28 Thread Pali Rohár
On Saturday 21 November 2020 23:30:11 Pali Rohár wrote:
> It looks like that i2c bus lot of times timeout on some units. Prior
> migration to CONFIG_DM_I2C i2c speed was set to CONFIG_SYS_OMAP24_I2C_SPEED
> value which was 10. Lower speed fixes timeout problems, so change speed
> back to its previous value.
> 
> Signed-off-by: Pali Rohár 
> Fixes: 8d8c18170325 ("Nokia RX-51: Convert to CONFIG_DM_I2C")
> ---
> Please include this patch into U-Boot master branch for 2020.01 release
> to have i2c bus working.

Hello! Could you please review this patch?

> ---
>  board/nokia/rx51/rx51.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c
> index 3d62b5d9ad..2dd41604c9 100644
> --- a/board/nokia/rx51/rx51.c
> +++ b/board/nokia/rx51/rx51.c
> @@ -704,9 +704,9 @@ void board_mmc_power_init(void)
>  }
>  
>  static const struct omap_i2c_platdata rx51_i2c[] = {
> - { I2C_BASE1, 220, OMAP_I2C_REV_V1 },
> + { I2C_BASE1, 10, OMAP_I2C_REV_V1 },
>   { I2C_BASE2, 10, OMAP_I2C_REV_V1 },
> - { I2C_BASE3, 40, OMAP_I2C_REV_V1 },
> + { I2C_BASE3, 10, OMAP_I2C_REV_V1 },
>  };
>  
>  U_BOOT_DEVICES(rx51_i2c) = {
> -- 
> 2.20.1
> 


Re: [linux-sunxi] [PATCH] sunxi: Add arm64 FEL support

2020-11-28 Thread Icenowy Zheng
在 2020-11-19星期四的 10:54 +,Andre Przywara写道:
> So far we did not support the BootROM based FEL USB debug mode on the
> 64-bit builds for Allwinner SoCs: The BootROM is using AArch32, but
> the
> SPL runs in AArch64.
> Returning back to AArch32 was not working as expected, since the RMR
> reset into 32-bit mode always starts execution in the BootROM, but
> not
> in the FEL routine.
> 
> After some debug and research and with help via IRC, the CPU hotplug
> mechanism emerged as a solution: If a certain R_CPUCFG register
> contains
> some magic, the BootROM will immediately branch to an address stored
> in
> some other register. This works well for our purposes.
> 
> Enable the FEL feature by providing early AArch32 code to first save
> the
> FEL state, *before* initially entering AArch64.
> If we eventually determine that we should return to FEL, we reset
> back
> into AArch32, and use the CPU hotplug mechanism to run some small
> AArch32 code snippet that restores the initially saved FEL state.
> 
> That allows the normal AArch64 SPL build to be loaded via the sunxi-
> fel
> tool, with it returning into FEL mode, so that other payloads can be
> transferred via FEL as well.
> 
> Tested on A64, H5 and H6.
> 
> Signed-off-by: Andre Przywara 

Tested-by: Icenowy Zheng 

> ---
>  arch/arm/cpu/armv8/Makefile |  2 +
>  arch/arm/cpu/armv8/fel_utils.S  | 78
> +
>  arch/arm/include/asm/arch-sunxi/boot0.h | 14 +
>  include/configs/sunxi-common.h  |  2 -
>  4 files changed, 94 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/cpu/armv8/fel_utils.S
> 
> diff --git a/arch/arm/cpu/armv8/Makefile
> b/arch/arm/cpu/armv8/Makefile
> index 93d26f98568..f7b4a5ee46c 100644
> --- a/arch/arm/cpu/armv8/Makefile
> +++ b/arch/arm/cpu/armv8/Makefile
> @@ -27,6 +27,8 @@ obj-$(CONFIG_ARM_SMCCC) += smccc-call.o
>  
>  ifndef CONFIG_SPL_BUILD
>  obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
> +else
> +obj-$(CONFIG_ARCH_SUNXI) += fel_utils.o
>  endif
>  obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o
> sec_firmware_asm.o
>  
> diff --git a/arch/arm/cpu/armv8/fel_utils.S
> b/arch/arm/cpu/armv8/fel_utils.S
> new file mode 100644
> index 000..334fdef7fa0
> --- /dev/null
> +++ b/arch/arm/cpu/armv8/fel_utils.S
> @@ -0,0 +1,78 @@
> +/*
> + * Utility functions for FEL mode, when running SPL in AArch64.
> + *
> + * Copyright (c) 2017 Arm Ltd.
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/*
> + * We don't overwrite save_boot_params() here, to save the FEL state
> upon
> + * entry, since this would run *after* the RMR reset, which clobbers
> that
> + * state.
> + * Instead we store the state _very_ early in the boot0 hook,
> *before*
> + * resetting to AArch64.
> + */
> +
> +/*
> + * The FEL routines in BROM run in AArch32.
> + * Reset back into 32-bit mode here and restore the saved FEL state
> + * afterwards.
> + * Resetting back into AArch32/EL3 using the RMR always enters the
> BROM,
> + * but we can use the CPU hotplug mechanism to branch back to our
> code
> + * immediately.
> + */
> +ENTRY(return_to_fel)
> + /*
> +  * the RMR reset will clear all registers, so save the
> arguments
> +  * (LR and SP) in the fel_stash structure, which we read
> anyways later
> +  */
> + adr x2, fel_stash
> + str w0, [x2]
> + str w1, [x2, #4]
> +
> + adr x1, fel_stash_addr  // to find the fel_stash
> address in AA32
> + str w2, [x1]
> +
> + ldr x0, =0xfa50392f // CPU hotplug magic
> +#ifndef CONFIG_MACH_SUN50I_H6
> + ldr x2, =(SUNXI_CPUCFG_BASE + 0x1a4) // offset for CPU
> hotplug base
> + str w0, [x2, #0x8]
> +#else
> + ldr x2, =(SUNXI_RTC_BASE + 0x1b8)   //
> BOOT_CPU_HP_FLAG_REG
> + str w0, [x2], #0x4
> +#endif
> + adr x0, back_in_32
> + str w0, [x2]
> +
> + dsb sy
> + isb sy
> + mov x0, #2  // RMR reset into AArch32
> + dsb sy
> + msr RMR_EL3, x0
> + isb sy
> +1:   wfi
> + b   1b
> +
> +/* AArch32 code to restore the state from fel_stash and return back
> to FEL. */
> +back_in_32:
> + .word   0xe59f0028  // ldr  r0, [pc, #40]   ; load
> fel_stash address
> + .word   0xe5901008  // ldr  r1, [r0, #8]
> + .word   0xe129f001  // msr  CPSR_fc, r1
> + .word   0xf57ff06f  // isb
> + .word   0xe590d000  // ldr  sp, [r0]
> + .word   0xe590e004  // ldr  lr, [r0, #4]
> + .word   0xe5901010  // ldr  r1, [r0, #16]
> + .word   0xee0c1f10  // mcr  15, 0, r1, cr12, cr0, {0} ;
> VBAR
> + .word   0xe590100c  // ldr  r1, [r0, #12]
> + .word   0xee011f10  // mcr  15, 0, r1, cr1, cr0, {0}  ;
> SCTLR
> + .word   0xf57ff06f  // isb
> + .word   0xe12fff1e  // bx   lr  ; return to
> FEL
> 

Re: [PATCH] gpio: Add support for DM GPIO for Kirkwood

2020-11-28 Thread Stefan Roese

Hi Harm,

On 27.11.20 22:56, Harm Berntsen wrote:

The Armada driver also works on Nedap's ax8008 Kirkwood board with a
Marvell 88F6180 CPU. The original commit of that driver,
704d9a645e1790e568abf43c5eff2de0d7b135ed also mentions that this driver
would be suitable for Kirkwood.


Well, this was really a long time ago. ;)


This driver does not completely replace the Kirkwood specific driver as
there are still dependencies on that driver(i.e. soft_i2c.c. in our
case).


So what work needs to be doney to completely replace the old legacy
kw_gpio driver and remove it completely? Could you perhaps tackle it
as well?

Other than that:

Reviewed-by: Stefan Roese 

Thanks,
Stefan


Signed-off-by: Harm Berntsen 
CC: Stefan Roese 
---

  drivers/gpio/Kconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 202fcc6f47..1f41bd3d55 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -374,7 +374,7 @@ config SIFIVE_GPIO
  
  config MVEBU_GPIO

bool "Marvell MVEBU GPIO driver"
-   depends on DM_GPIO && ARCH_MVEBU
+   depends on DM_GPIO && (ARCH_MVEBU || ARCH_KIRKWOOD)
default y
help
  Say yes here to support Marvell MVEBU (Armada XP/38x) GPIOs.




Viele Grüße,
Stefan

--
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: s...@denx.de


[PATCH v4 18/18] global_data: Enable spl_handoff only if CONFIG_HANDOFF is set

2020-11-28 Thread Ovidiu Panait
spl_handoff should only be enabled when CONFIG_HANDOFF is set. Drop the
nested ifdefs and check for CONFIG_HANDOFF instead.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 include/asm-generic/global_data.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/global_data.h 
b/include/asm-generic/global_data.h
index 87d827d0f4..5b1a7f1131 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -400,12 +400,12 @@ struct global_data {
 * @new_bloblist: relocated blob list information
 */
struct bloblist_hdr *new_bloblist;
-# ifdef CONFIG_SPL
+#endif
+#if CONFIG_IS_ENABLED(HANDOFF)
/**
 * @spl_handoff: SPL hand-off information
 */
struct spl_handoff *spl_handoff;
-# endif
 #endif
 #if defined(CONFIG_TRANSLATION_OFFSET)
/**
-- 
2.17.1



[PATCH v4 16/18] common: board_r: Drop arch-specific ifdefs around initr_trap

2020-11-28 Thread Ovidiu Panait
In order to remove the arch-specific ifdefs around initr_trap, introduce
arch_initr_trap weak initcall. Implementations for ppc/m68k/mips have
been moved to arch//lib/traps.c

Default implementation is a nop stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- Drop trap_init declaration from init.h and make arch-specific
implementations static for mips and m68k (on powerpc trap_init is an
asm routine)

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 arch/m68k/lib/traps.c |  9 -
 arch/mips/lib/traps.c |  9 -
 arch/powerpc/lib/Makefile |  1 +
 arch/powerpc/lib/traps.c  | 19 +++
 common/board_r.c  | 16 ++--
 include/init.h| 10 +-
 6 files changed, 47 insertions(+), 17 deletions(-)
 create mode 100644 arch/powerpc/lib/traps.c

diff --git a/arch/m68k/lib/traps.c b/arch/m68k/lib/traps.c
index c49141f376..0c2c1a9965 100644
--- a/arch/m68k/lib/traps.c
+++ b/arch/m68k/lib/traps.c
@@ -40,7 +40,7 @@ void exc_handler(struct pt_regs *fp) {
for(;;);
 }
 
-void trap_init(ulong value) {
+static void trap_init(ulong value) {
unsigned long *vec = (ulong *)value;
int i;
 
@@ -59,3 +59,10 @@ void trap_init(ulong value) {
 
setvbr(value);  /* set vector base register to new table */
 }
+
+int arch_initr_trap(void)
+{
+   trap_init(CONFIG_SYS_SDRAM_BASE);
+
+   return 0;
+}
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
index df8b63f383..540ea48e32 100644
--- a/arch/mips/lib/traps.c
+++ b/arch/mips/lib/traps.c
@@ -99,7 +99,7 @@ static void set_handler(unsigned long offset, void *addr, 
unsigned long size)
flush_cache(ebase + offset, size);
 }
 
-void trap_init(ulong reloc_addr)
+static void trap_init(ulong reloc_addr)
 {
unsigned long ebase = gd->irq_sp;
 
@@ -131,3 +131,10 @@ void trap_restore(void)
clear_c0_status(ST0_BEV);
execution_hazard_barrier();
 }
+
+int arch_initr_trap(void)
+{
+   trap_init(CONFIG_SYS_SDRAM_BASE);
+
+   return 0;
+}
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index f61809ab05..2782740bf5 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -40,6 +40,7 @@ obj-y += interrupts.o
 obj-$(CONFIG_CMD_KGDB) += kgdb.o
 obj-y  += stack.o
 obj-y  += time.o
+obj-y  += traps.o
 endif # not minimal
 
 ifdef CONFIG_SPL_BUILD
diff --git a/arch/powerpc/lib/traps.c b/arch/powerpc/lib/traps.c
new file mode 100644
index 00..288e377632
--- /dev/null
+++ b/arch/powerpc/lib/traps.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, w...@denx.de.
+ */
+
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void trap_init(unsigned long reloc_addr);
+
+int arch_initr_trap(void)
+{
+   trap_init(gd->relocaddr);
+
+   return 0;
+}
diff --git a/common/board_r.c b/common/board_r.c
index c083eb0a03..9fa4d4b42e 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -182,20 +182,10 @@ static int initr_reloc_global_data(void)
return 0;
 }
 
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
-static int initr_trap(void)
+__weak int arch_initr_trap(void)
 {
-   /*
-* Setup trap handlers
-*/
-#if defined(CONFIG_PPC)
-   trap_init(gd->relocaddr);
-#else
-   trap_init(CONFIG_SYS_SDRAM_BASE);
-#endif
return 0;
 }
-#endif
 
 #ifdef CONFIG_ADDR_MAP
 static int initr_addr_map(void)
@@ -669,9 +659,7 @@ static init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
initr_manual_reloc_cmdtable,
 #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
-   initr_trap,
-#endif
+   arch_initr_trap,
 #ifdef CONFIG_ADDR_MAP
initr_addr_map,
 #endif
diff --git a/include/init.h b/include/init.h
index dded1cb871..980be27993 100644
--- a/include/init.h
+++ b/include/init.h
@@ -300,7 +300,15 @@ int board_early_init_r(void);
 /* TODO(s...@chromium.org): Drop this when DM_PCI migration is completed */
 void pci_init_board(void);
 
-void trap_init(unsigned long reloc_addr);
+/**
+ * arch_initr_trap() - Init traps
+ *
+ * Arch specific routine for initializing traps. It is called during the
+ * generic board init sequence, after relocation.
+ *
+ * Return: 0 if OK
+ */
+int arch_initr_trap(void);
 
 /**
  * main_loop() - Enter the main loop of U-Boot
-- 
2.17.1



[PATCH v4 13/18] common: board_r: Drop initr_jumptable wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to jumptable_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 common/board_r.c  |  8 +---
 common/exports.c  |  4 +++-
 include/exports.h | 10 --
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index a5cbbcc343..32ad40d372 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -490,12 +490,6 @@ static int initr_malloc_bootparams(void)
 }
 #endif
 
-static int initr_jumptable(void)
-{
-   jumptable_init();
-   return 0;
-}
-
 #if defined(CONFIG_API)
 static int initr_api(void)
 {
@@ -757,7 +751,7 @@ static init_fnc_t init_sequence_r[] = {
pci_init,
 #endif
stdio_add_devices,
-   initr_jumptable,
+   jumptable_init,
 #ifdef CONFIG_API
initr_api,
 #endif
diff --git a/common/exports.c b/common/exports.c
index 6253b55694..4578f07021 100644
--- a/common/exports.c
+++ b/common/exports.c
@@ -25,8 +25,10 @@ unsigned long get_version(void)
 # define miiphy_set_current_devdummy
 #endif
 
-void jumptable_init(void)
+int jumptable_init(void)
 {
gd->jt = malloc(sizeof(struct jt_funcs));
 #include <_exports.h>
+
+   return 0;
 }
diff --git a/include/exports.h b/include/exports.h
index b300554091..faf0f59244 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -15,8 +15,14 @@
 struct cmd_tbl;
 struct spi_slave;
 
-/* Set up the jump table for use by the API */
-void jumptable_init(void);
+/**
+ * jumptable_init() - Set up the jump table for use by the API
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int jumptable_init(void);
 
 /* These are declarations of exported functions available in C code */
 unsigned long get_version(void);
-- 
2.17.1



[PATCH v4 12/18] common: board_r: Drop initr_xen wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to xen_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/board_r.c | 10 +-
 drivers/xen/hypervisor.c |  4 +++-
 include/xen.h|  2 +-
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index 48e898b586..a5cbbcc343 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -428,14 +428,6 @@ static int initr_mmc(void)
 }
 #endif
 
-#ifdef CONFIG_XEN
-static int initr_xen(void)
-{
-   xen_init();
-   return 0;
-}
-#endif
-
 #ifdef CONFIG_PVBLOCK
 static int initr_pvblock(void)
 {
@@ -743,7 +735,7 @@ static init_fnc_t init_sequence_r[] = {
initr_mmc,
 #endif
 #ifdef CONFIG_XEN
-   initr_xen,
+   xen_init,
 #endif
 #ifdef CONFIG_PVBLOCK
initr_pvblock,
diff --git a/drivers/xen/hypervisor.c b/drivers/xen/hypervisor.c
index 178c206f5b..2560894832 100644
--- a/drivers/xen/hypervisor.c
+++ b/drivers/xen/hypervisor.c
@@ -232,7 +232,7 @@ void clear_evtchn(uint32_t port)
synch_clear_bit(port, >evtchn_pending[0]);
 }
 
-void xen_init(void)
+int xen_init(void)
 {
debug("%s\n", __func__);
 
@@ -240,6 +240,8 @@ void xen_init(void)
init_events();
init_xenbus();
init_gnttab();
+
+   return 0;
 }
 
 void xen_fini(void)
diff --git a/include/xen.h b/include/xen.h
index a952a2c84b..868132156e 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -11,7 +11,7 @@
  * Map Xen memory pages, initialize event handler and xenbus,
  * setup the grant table.
  */
-void xen_init(void);
+int xen_init(void);
 
 /**
  * xen_fini() - Board cleanup before Linux kernel start
-- 
2.17.1



[PATCH v4 17/18] spl: Kconfig: Add SPL dependency to CONFIG_HANDOFF

2020-11-28 Thread Ovidiu Panait
CONFIG_HANDOFF is used in u-boot proper to locate handoff info from SPL
during pre-relocation init (in setup_spl_handoff). Add explicit dependency
on CONFIG_SPL, to fix the following build error when CONFIG_HANDOFF &&
!CONFIG_SPL:

common/board_f.c: In function ‘setup_spl_handoff’:
common/board_f.c:283:4: error: ‘gd_t {aka struct global_data}’
has no member named ‘spl_handoff’
  gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
^~

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/spl/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index d8086bd9e8..cd980e96b8 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -117,7 +117,7 @@ endmenu
 
 config HANDOFF
bool "Pass hand-off information from SPL to U-Boot proper"
-   depends on BLOBLIST
+   depends on SPL && BLOBLIST
help
  It is useful to be able to pass information from SPL to U-Boot
  proper to preserve state that is known in SPL and is needed in U-Boot.
-- 
2.17.1



[PATCH v4 15/18] common: board_r: Drop initr_bbmii wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to bb_miiphy_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 common/board_r.c   | 10 +-
 drivers/net/phy/miiphybb.c |  4 +++-
 include/miiphy.h   | 10 +-
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index 500457b080..c083eb0a03 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -534,14 +534,6 @@ static int initr_scsi(void)
 }
 #endif
 
-#ifdef CONFIG_BITBANGMII
-static int initr_bbmii(void)
-{
-   bb_miiphy_init();
-   return 0;
-}
-#endif
-
 #ifdef CONFIG_CMD_NET
 static int initr_net(void)
 {
@@ -783,7 +775,7 @@ static init_fnc_t init_sequence_r[] = {
initr_scsi,
 #endif
 #ifdef CONFIG_BITBANGMII
-   initr_bbmii,
+   bb_miiphy_init,
 #endif
 #ifdef CONFIG_PCI_ENDPOINT
pci_ep_init,
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index ba97a54c06..59a32c4913 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -105,7 +105,7 @@ int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
  sizeof(bb_miiphy_buses[0]);
 #endif
 
-void bb_miiphy_init(void)
+int bb_miiphy_init(void)
 {
int i;
 
@@ -124,6 +124,8 @@ void bb_miiphy_init(void)
bb_miiphy_buses[i].init(_miiphy_buses[i]);
}
}
+
+   return 0;
 }
 
 static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
diff --git a/include/miiphy.h b/include/miiphy.h
index 61c136b114..8b77bac01e 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -81,7 +81,15 @@ struct bb_miiphy_bus {
 extern struct bb_miiphy_bus bb_miiphy_buses[];
 extern int bb_miiphy_buses_num;
 
-void bb_miiphy_init(void);
+/**
+ * bb_miiphy_init() - Initialize bit-banged MII bus driver
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int bb_miiphy_init(void);
+
 int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg);
 int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
u16 value);
-- 
2.17.1



[PATCH v4 14/18] common: board_r: Drop initr_api wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to api_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 api/api.c |  6 --
 api/api_private.h |  2 +-
 common/board_r.c  | 11 +--
 include/api.h | 10 +-
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/api/api.c b/api/api.c
index 493b77f809..89003c161c 100644
--- a/api/api.c
+++ b/api/api.c
@@ -642,7 +642,7 @@ int syscall(int call, int *retval, ...)
return 1;
 }
 
-void api_init(void)
+int api_init(void)
 {
struct api_signature *sig;
 
@@ -679,7 +679,7 @@ void api_init(void)
sig = malloc(sizeof(struct api_signature));
if (sig == NULL) {
printf("API: could not allocate memory for the signature!\n");
-   return;
+   return -ENOMEM;
}
 
env_set_hex("api_address", (unsigned long)sig);
@@ -691,6 +691,8 @@ void api_init(void)
sig->checksum = crc32(0, (unsigned char *)sig,
  sizeof(struct api_signature));
debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
+
+   return 0;
 }
 
 void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long 
size,
diff --git a/api/api_private.h b/api/api_private.h
index 07fd50ad3a..bb23821c2c 100644
--- a/api/api_private.h
+++ b/api/api_private.h
@@ -8,7 +8,7 @@
 #ifndef _API_PRIVATE_H_
 #define _API_PRIVATE_H_
 
-void   api_init(void);
+intapi_init(void);
 void   platform_set_mr(struct sys_info *, unsigned long, unsigned long, int);
 intplatform_sys_info(struct sys_info *);
 
diff --git a/common/board_r.c b/common/board_r.c
index 32ad40d372..500457b080 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -490,15 +490,6 @@ static int initr_malloc_bootparams(void)
 }
 #endif
 
-#if defined(CONFIG_API)
-static int initr_api(void)
-{
-   /* Initialize API */
-   api_init();
-   return 0;
-}
-#endif
-
 #ifdef CONFIG_CMD_NET
 static int initr_ethaddr(void)
 {
@@ -753,7 +744,7 @@ static init_fnc_t init_sequence_r[] = {
stdio_add_devices,
jumptable_init,
 #ifdef CONFIG_API
-   initr_api,
+   api_init,
 #endif
console_init_r, /* fully init console as a device */
 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
diff --git a/include/api.h b/include/api.h
index 84d81dc817..83412a7c87 100644
--- a/include/api.h
+++ b/include/api.h
@@ -7,6 +7,14 @@
 #ifndef __API_H
 #define __API_H
 
-void api_init(void);
+/**
+ * api_init() - Initialize API for external applications
+ *
+ * Initialize API for external (standalone) applications running on top of
+ * U-Boot. It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int api_init(void);
 
 #endif
-- 
2.17.1



[PATCH v4 11/18] common: board_r: Drop initr_noncached wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to noncached_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 arch/arm/include/asm/system.h | 13 -
 arch/arm/lib/cache.c  |  4 +++-
 common/board_r.c  | 10 +-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index ce552944b7..5fe83699f4 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -628,7 +628,18 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, 
size_t size,
 enum dcache_option option);
 
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
-void noncached_init(void);
+/**
+ * noncached_init() - Initialize non-cached memory region
+ *
+ * Initialize non-cached memory area. This memory region will be typically
+ * located right below the malloc() area and mapped uncached in the MMU.
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int noncached_init(void);
+
 phys_addr_t noncached_alloc(size_t size, size_t align);
 #endif /* CONFIG_SYS_NONCACHED_MEMORY */
 
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index ee7d14b2d3..bdde9cdad5 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -86,7 +86,7 @@ void noncached_set_region(void)
 #endif
 }
 
-void noncached_init(void)
+int noncached_init(void)
 {
phys_addr_t start, end;
size_t size;
@@ -103,6 +103,8 @@ void noncached_init(void)
noncached_next = start;
 
noncached_set_region();
+
+   return 0;
 }
 
 phys_addr_t noncached_alloc(size_t size, size_t align)
diff --git a/common/board_r.c b/common/board_r.c
index 414b6272c5..48e898b586 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -242,14 +242,6 @@ static int initr_malloc(void)
return 0;
 }
 
-#ifdef CONFIG_SYS_NONCACHED_MEMORY
-static int initr_noncached(void)
-{
-   noncached_init();
-   return 0;
-}
-#endif
-
 static int initr_of_live(void)
 {
if (CONFIG_IS_ENABLED(OF_LIVE)) {
@@ -668,7 +660,7 @@ static init_fnc_t init_sequence_r[] = {
console_record_init,
 #endif
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
-   initr_noncached,
+   noncached_init,
 #endif
initr_of_live,
 #ifdef CONFIG_DM
-- 
2.17.1



[PATCH v4 10/18] common: board_r: Drop initr_pci wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to pci_init and use it directly in the post-relocation
init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 common/board_r.c | 18 --
 drivers/pci/pci-uclass.c |  4 +++-
 drivers/pci/pci.c|  6 --
 include/init.h   | 13 -
 4 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index d86ff0cb5e..414b6272c5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -214,16 +214,6 @@ static int initr_unlock_ram_in_cache(void)
 }
 #endif
 
-#ifdef CONFIG_PCI
-static int initr_pci(void)
-{
-   if (IS_ENABLED(CONFIG_PCI_INIT_R))
-   pci_init();
-
-   return 0;
-}
-#endif
-
 static int initr_barrier(void)
 {
 #ifdef CONFIG_PPC
@@ -732,12 +722,12 @@ static init_fnc_t init_sequence_r[] = {
post_output_backlog,
 #endif
INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
+#if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
 * Do early PCI configuration _before_ the flash gets initialised,
 * because PCU resources are crucial for flash access on some boards.
 */
-   initr_pci,
+   pci_init,
 #endif
 #ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r,
@@ -776,11 +766,11 @@ static init_fnc_t init_sequence_r[] = {
mac_read_from_eeprom,
 #endif
INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
+#if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
 * Do pci configuration
 */
-   initr_pci,
+   pci_init,
 #endif
stdio_add_devices,
initr_jumptable,
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index eb07d25301..7e9b5cf0fa 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1834,7 +1834,7 @@ U_BOOT_DRIVER(pci_generic_drv) = {
.of_match   = pci_generic_ids,
 };
 
-void pci_init(void)
+int pci_init(void)
 {
struct udevice *bus;
 
@@ -1847,4 +1847,6 @@ void pci_init(void)
 uclass_next_device_check()) {
;
}
+
+   return 0;
 }
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 664e8379eb..a7453e5755 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -454,16 +454,18 @@ int pci_hose_scan(struct pci_controller *hose)
return pci_hose_scan_bus(hose, hose->current_busno);
 }
 
-void pci_init(void)
+int pci_init(void)
 {
hose_head = NULL;
 
/* allow env to disable pci init/enum */
if (env_get("pcidisable") != NULL)
-   return;
+   return 0;
 
/* now call board specific pci_init()... */
pci_init_board();
+
+   return 0;
 }
 
 /* Returns the address of the requested capability structure within the
diff --git a/include/init.h b/include/init.h
index c6c5f34b55..dded1cb871 100644
--- a/include/init.h
+++ b/include/init.h
@@ -186,6 +186,18 @@ int cpu_secondary_init_r(void);
  */
 int pci_ep_init(void);
 
+/**
+ * pci_init() - Enumerate pci devices
+ *
+ * It is called during the generic post-relocation init sequence to enumerate
+ * pci buses. This is needed, for instance, in the case of DM PCI-based
+ * Ethernet devices, which will not be detected without having the enumeration
+ * performed earlier.
+ *
+ * Return: 0 if OK
+ */
+int pci_init(void);
+
 /**
  * init_cache_f_r() - Turn on the cache in preparation for relocation
  *
@@ -257,7 +269,6 @@ int mac_read_from_eeprom(void);
 int set_cpu_clk_info(void);
 int update_flash_size(int flash_size);
 int arch_early_init_r(void);
-void pci_init(void);
 int misc_init_r(void);
 #if defined(CONFIG_VID)
 int init_func_vid(void);
-- 
2.17.1



[PATCH v4 08/18] common: board_r: Drop initr_post_backlog wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to post_output_backlog and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 common/board_r.c | 10 +-
 include/post.h   | 11 ++-
 post/post.c  |  4 +++-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index a291543d74..7a06627ba9 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -206,14 +206,6 @@ static int initr_addr_map(void)
 }
 #endif
 
-#ifdef CONFIG_POST
-static int initr_post_backlog(void)
-{
-   post_output_backlog();
-   return 0;
-}
-#endif
-
 #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
 static int initr_unlock_ram_in_cache(void)
 {
@@ -746,7 +738,7 @@ static init_fnc_t init_sequence_r[] = {
 #endif
INIT_FUNC_WATCHDOG_RESET
 #ifdef CONFIG_POST
-   initr_post_backlog,
+   post_output_backlog,
 #endif
INIT_FUNC_WATCHDOG_RESET
 #if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
diff --git a/include/post.h b/include/post.h
index eb218acde5..5695e2b533 100644
--- a/include/post.h
+++ b/include/post.h
@@ -107,7 +107,6 @@ int post_init_f (void);
 void post_bootmode_init (void);
 int post_bootmode_get (unsigned int * last_test);
 void post_bootmode_clear (void);
-void post_output_backlog ( void );
 int post_run (char *name, int flags);
 int post_info (char *name);
 int post_log (char *format, ...);
@@ -116,6 +115,16 @@ void post_reloc (void);
 #endif
 unsigned long post_time_ms (unsigned long base);
 
+/**
+ * post_output_backlog() - Print POST results
+ *
+ * Print POST results during the generic board init sequence, after
+ * relocation.
+ *
+ * Return: 0 if OK
+ */
+int post_output_backlog(void);
+
 extern struct post_test post_list[];
 extern unsigned int post_list_size;
 extern int post_hotkeys_pressed(void);
diff --git a/post/post.c b/post/post.c
index 0f1fe8d905..7d6a647312 100644
--- a/post/post.c
+++ b/post/post.c
@@ -128,7 +128,7 @@ static void post_log_mark_succ(unsigned long testid)
 }
 
 /* ... and the messages are output once we are relocated */
-void post_output_backlog(void)
+int post_output_backlog(void)
 {
int j;
 
@@ -143,6 +143,8 @@ void post_output_backlog(void)
}
}
}
+
+   return 0;
 }
 
 static void post_bootmode_test_on(unsigned int last_test)
-- 
2.17.1



[PATCH v4 07/18] common: board_r: Drop initr_secondary_cpu wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to cpu_secondary_init_r and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
---
v4 updates:
- add reviewed-by tag

v3 updates:
-none

v2 updates:
- add function comment

 arch/powerpc/cpu/mpc85xx/cpu_init.c |  4 +++-
 common/board_r.c| 17 ++---
 include/init.h  | 14 ++
 3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c 
b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index e0f0f7ecda..e920e01b25 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -1028,7 +1028,7 @@ void arch_preboot_os(void)
mtmsr(msr);
 }
 
-void cpu_secondary_init_r(void)
+int cpu_secondary_init_r(void)
 {
 #ifdef CONFIG_QE
 #ifdef CONFIG_U_QE
@@ -1040,6 +1040,8 @@ void cpu_secondary_init_r(void)
qe_init(qe_base);
qe_reset();
 #endif
+
+   return 0;
 }
 
 #ifdef CONFIG_BOARD_LATE_INIT
diff --git a/common/board_r.c b/common/board_r.c
index 07c0ad363e..a291543d74 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -91,21 +91,8 @@ __weak int board_flash_wp_on(void)
return 0;
 }
 
-__weak void cpu_secondary_init_r(void)
+__weak int cpu_secondary_init_r(void)
 {
-}
-
-static int initr_secondary_cpu(void)
-{
-   /*
-* after non-volatile devices & environment is setup and cpu code have
-* another round to deal with any initialization that might require
-* full access to the environment or loading of some image (firmware)
-* from a non-volatile device
-*/
-   /* TODO: maybe define this for all archs? */
-   cpu_secondary_init_r();
-
return 0;
 }
 
@@ -801,7 +788,7 @@ static init_fnc_t init_sequence_r[] = {
initr_malloc_bootparams,
 #endif
INIT_FUNC_WATCHDOG_RESET
-   initr_secondary_cpu,
+   cpu_secondary_init_r,
 #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
mac_read_from_eeprom,
 #endif
diff --git a/include/init.h b/include/init.h
index 0f48ccb57a..7cdc47cff1 100644
--- a/include/init.h
+++ b/include/init.h
@@ -163,6 +163,20 @@ int arch_setup_bdinfo(void);
  */
 int setup_bdinfo(void);
 
+/**
+ * cpu_secondary_init_r() - CPU-specific secondary initialization
+ *
+ * After non-volatile devices, environment and cpu code are setup, have
+ * another round to deal with any initialization that might require
+ * full access to the environment or loading of some image (firmware)
+ * from a non-volatile device.
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int cpu_secondary_init_r(void);
+
 /**
  * init_cache_f_r() - Turn on the cache in preparation for relocation
  *
-- 
2.17.1



[PATCH v4 09/18] common: board_r: Drop initr_pci_ep wrapper

2020-11-28 Thread Ovidiu Panait
Add a return value to pci_ep_init and use it directly in the
post-relocation init sequence, rather than using a wrapper stub.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- add reviewed-by tag

v2 updates:
- add function comment

 common/board_r.c | 11 +--
 drivers/pci_endpoint/pci_ep-uclass.c |  4 +++-
 include/init.h   | 10 +-
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index 7a06627ba9..d86ff0cb5e 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -214,15 +214,6 @@ static int initr_unlock_ram_in_cache(void)
 }
 #endif
 
-#ifdef CONFIG_PCI_ENDPOINT
-static int initr_pci_ep(void)
-{
-   pci_ep_init();
-
-   return 0;
-}
-#endif
-
 #ifdef CONFIG_PCI
 static int initr_pci(void)
 {
@@ -836,7 +827,7 @@ static init_fnc_t init_sequence_r[] = {
initr_bbmii,
 #endif
 #ifdef CONFIG_PCI_ENDPOINT
-   initr_pci_ep,
+   pci_ep_init,
 #endif
 #ifdef CONFIG_CMD_NET
INIT_FUNC_WATCHDOG_RESET
diff --git a/drivers/pci_endpoint/pci_ep-uclass.c 
b/drivers/pci_endpoint/pci_ep-uclass.c
index 38a5f08376..aa89701de8 100644
--- a/drivers/pci_endpoint/pci_ep-uclass.c
+++ b/drivers/pci_endpoint/pci_ep-uclass.c
@@ -210,7 +210,7 @@ UCLASS_DRIVER(pci_ep) = {
.flags  = DM_UC_FLAG_SEQ_ALIAS,
 };
 
-void pci_ep_init(void)
+int pci_ep_init(void)
 {
struct udevice *dev;
 
@@ -219,4 +219,6 @@ void pci_ep_init(void)
 uclass_next_device_check()) {
;
}
+
+   return 0;
 }
diff --git a/include/init.h b/include/init.h
index 7cdc47cff1..c6c5f34b55 100644
--- a/include/init.h
+++ b/include/init.h
@@ -177,6 +177,15 @@ int setup_bdinfo(void);
  */
 int cpu_secondary_init_r(void);
 
+/**
+ * pci_ep_init() - Initialize pci endpoint devices
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int pci_ep_init(void);
+
 /**
  * init_cache_f_r() - Turn on the cache in preparation for relocation
  *
@@ -249,7 +258,6 @@ int set_cpu_clk_info(void);
 int update_flash_size(int flash_size);
 int arch_early_init_r(void);
 void pci_init(void);
-void pci_ep_init(void);
 int misc_init_r(void);
 #if defined(CONFIG_VID)
 int init_func_vid(void);
-- 
2.17.1



[PATCH v4 05/18] common: board_f: Use IS_ENABLED(CONFIG_OF_EMBED) in reserve_fdt, reloc_fdt

2020-11-28 Thread Ovidiu Panait
Use IS_ENABLED(CONFIG_OF_EMBED) in instead of #ifdefs in reserve_fdt,
reloc_fdt functions.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/board_f.c | 41 +
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index fbf622e0f0..ae3001bed1 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -514,21 +514,21 @@ static int reserve_global_data(void)
 
 static int reserve_fdt(void)
 {
-#ifndef CONFIG_OF_EMBED
-   /*
-* If the device tree is sitting immediately above our image then we
-* must relocate it. If it is embedded in the data section, then it
-* will be relocated with other data.
-*/
-   if (gd->fdt_blob) {
-   gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
+   if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+   /*
+* If the device tree is sitting immediately above our image
+* then we must relocate it. If it is embedded in the data
+* section, then it will be relocated with other data.
+*/
+   if (gd->fdt_blob) {
+   gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
 
-   gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
-   gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
-   debug("Reserving %lu Bytes for FDT at: %08lx\n",
- gd->fdt_size, gd->start_addr_sp);
+   gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
+   gd->new_fdt = map_sysmem(gd->start_addr_sp, 
gd->fdt_size);
+   debug("Reserving %lu Bytes for FDT at: %08lx\n",
+ gd->fdt_size, gd->start_addr_sp);
+   }
}
-#endif
 
return 0;
 }
@@ -616,14 +616,15 @@ static int init_post(void)
 
 static int reloc_fdt(void)
 {
-#ifndef CONFIG_OF_EMBED
-   if (gd->flags & GD_FLG_SKIP_RELOC)
-   return 0;
-   if (gd->new_fdt) {
-   memcpy(gd->new_fdt, gd->fdt_blob, fdt_totalsize(gd->fdt_blob));
-   gd->fdt_blob = gd->new_fdt;
+   if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+   if (gd->flags & GD_FLG_SKIP_RELOC)
+   return 0;
+   if (gd->new_fdt) {
+   memcpy(gd->new_fdt, gd->fdt_blob,
+  fdt_totalsize(gd->fdt_blob));
+   gd->fdt_blob = gd->new_fdt;
+   }
}
-#endif
 
return 0;
 }
-- 
2.17.1



[PATCH v4 06/18] common: board_r: Drop initr_console_record wrapper

2020-11-28 Thread Ovidiu Panait
Drop initr_console_record wrapper and call console_record_init directly.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/board_r.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index 29dd7d26d9..07c0ad363e 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -282,15 +282,6 @@ static int initr_malloc(void)
return 0;
 }
 
-static int initr_console_record(void)
-{
-#if defined(CONFIG_CONSOLE_RECORD)
-   return console_record_init();
-#else
-   return 0;
-#endif
-}
-
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
 static int initr_noncached(void)
 {
@@ -713,7 +704,9 @@ static init_fnc_t init_sequence_r[] = {
initr_malloc,
log_init,
initr_bootstage,/* Needs malloc() but has its own timer */
-   initr_console_record,
+#if defined(CONFIG_CONSOLE_RECORD)
+   console_record_init,
+#endif
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
initr_noncached,
 #endif
-- 
2.17.1



[PATCH v4 04/18] common: board_f: Move setup_machine code to setup_bdinfo

2020-11-28 Thread Ovidiu Panait
setup_bdinfo is used to populate various bdinfo fields, so move
setup_machine code there, as all it does is setting
gd->bd->bi_arch_number.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/board_f.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index 3c4437341a..fbf622e0f0 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -503,14 +503,6 @@ static int reserve_board(void)
return 0;
 }
 
-static int setup_machine(void)
-{
-#ifdef CONFIG_MACH_TYPE
-   gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
-#endif
-   return 0;
-}
-
 static int reserve_global_data(void)
 {
gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t));
@@ -605,6 +597,10 @@ int setup_bdinfo(void)
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;  /* size  of SRAM */
}
 
+#ifdef CONFIG_MACH_TYPE
+   bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
+#endif
+
return arch_setup_bdinfo();
 }
 
@@ -916,7 +912,6 @@ static const init_fnc_t init_sequence_f[] = {
reserve_uboot,
reserve_malloc,
reserve_board,
-   setup_machine,
reserve_global_data,
reserve_fdt,
reserve_bootstage,
-- 
2.17.1



[PATCH v4 03/18] common: board_f: Use IS_ENABLED(CONFIG_TIMER_EARLY) in initf_dm

2020-11-28 Thread Ovidiu Panait
Use IS_ENABLED(CONFIG_TIMER_EARLY) instead of #ifdef in initf_dm. Also,
move timer code to the main ifdef, so that ret is defined.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- none

v3 updates:
- none

v2 updates:
- add reviewed-by tag

 common/board_f.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index 552552e328..3c4437341a 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -775,11 +775,12 @@ static int initf_dm(void)
bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_F);
if (ret)
return ret;
-#endif
-#ifdef CONFIG_TIMER_EARLY
-   ret = dm_timer_init();
-   if (ret)
-   return ret;
+
+   if (IS_ENABLED(CONFIG_TIMER_EARLY)) {
+   ret = dm_timer_init();
+   if (ret)
+   return ret;
+   }
 #endif
 
return 0;
-- 
2.17.1



[PATCH v4 02/18] common: board_f: Drop initf_console_record wrapper

2020-11-28 Thread Ovidiu Panait
Drop initf_console_record wrapper and call console_record_init directly.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- add reviewed-by tag

v3 updates:
- none

v2 updates:
- check defined(CONFIG_CONSOLE_RECORD_INIT_F) in ifdef condition

 common/board_f.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index e5e69ff0fa..552552e328 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -765,14 +765,6 @@ static int initf_bootstage(void)
return 0;
 }
 
-static int initf_console_record(void)
-{
-   if (IS_ENABLED(CONFIG_CONSOLE_RECORD_INIT_F))
-   return console_record_init();
-
-   return 0;
-}
-
 static int initf_dm(void)
 {
 #if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN)
@@ -829,7 +821,9 @@ static const init_fnc_t init_sequence_f[] = {
bloblist_init,
 #endif
setup_spl_handoff,
-   initf_console_record,
+#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
+   console_record_init,
+#endif
 #if defined(CONFIG_HAVE_FSP)
arch_fsp_init,
 #endif
-- 
2.17.1



[PATCH v4 01/18] common: Kconfig: Introduce CONFIG_CONSOLE_RECORD_INIT_F

2020-11-28 Thread Ovidiu Panait
Currently, the following #ifdef construct is used to check whether to run
console_record_init() during pre-relocation init:
 defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN)

Introduce CONFIG_CONSOLE_RECORD_INIT_F Kconfig option to get rid of the
complex ifdef check. Also, use IS_ENABLED() instead of #ifdef.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---
v4 updates:
- add reviewed-by tag

v3 updates:
- use only "default y" for CONSOLE_RECORD_INIT_F

v2 updates:
- new patch

 common/Kconfig   | 8 
 common/board_f.c | 7 +++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 2bce8c9ba1..d8982ba377 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -17,6 +17,14 @@ config CONSOLE_RECORD
  To enable console recording, call console_record_reset_enable()
  from your code.
 
+config CONSOLE_RECORD_INIT_F
+   bool "Enable console recording during pre-relocation init"
+   depends on CONSOLE_RECORD && SYS_MALLOC_F
+   default y
+   help
+ This option enables console recording during pre-relocation init.
+ CONFIG_SYS_MALLOC_F must be enabled to use this feature.
+
 config CONSOLE_RECORD_OUT_SIZE
hex "Output buffer size"
depends on CONSOLE_RECORD
diff --git a/common/board_f.c b/common/board_f.c
index 9f441c44f1..e5e69ff0fa 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -767,11 +767,10 @@ static int initf_bootstage(void)
 
 static int initf_console_record(void)
 {
-#if defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN)
-   return console_record_init();
-#else
+   if (IS_ENABLED(CONFIG_CONSOLE_RECORD_INIT_F))
+   return console_record_init();
+
return 0;
-#endif
 }
 
 static int initf_dm(void)
-- 
2.17.1



[PATCH v4 00/18] Minor board_f/board_r cleanups

2020-11-28 Thread Ovidiu Panait
v4:
* Drop trap_init declaration from init.h and make arch-specific
implementations static for mips and m68k (on powerpc trap_init is an
asm routine)

v3:
* Use only "default y" for CONFIG_CONSOLE_RECORD_INIT_F Kconfig option
* Add reviewed-by tags

v2:
* Introduce CONFIG_CONSOLE_RECORD_INIT_F Kconfig to eliminate complex ifdef
  around console_record_init in board_f.c
* Add function comments to all routines that get their signatures changed
* Add reviewed-by tags

v1:
* Use IS_ENABLED() instead of #ifdef where possible
* Add int return values to various functions so we can drop multiple initr_*
  stub wrappers
* Clean some arch-specific ifdefs
* Minor CONFIG_HANDOFF patches

Ovidiu Panait (18):
  common: Kconfig: Introduce CONFIG_CONSOLE_RECORD_INIT_F
  common: board_f: Drop initf_console_record wrapper
  common: board_f: Use IS_ENABLED(CONFIG_TIMER_EARLY) in initf_dm
  common: board_f: Move setup_machine code to setup_bdinfo
  common: board_f: Use IS_ENABLED(CONFIG_OF_EMBED) in
reserve_fdt,reloc_fdt
  common: board_r: Drop initr_console_record wrapper
  common: board_r: Drop initr_secondary_cpu wrapper
  common: board_r: Drop initr_post_backlog wrapper
  common: board_r: Drop initr_pci_ep wrapper
  common: board_r: Drop initr_pci wrapper
  common: board_r: Drop initr_noncached wrapper
  common: board_r: Drop initr_xen wrapper
  common: board_r: Drop initr_jumptable wrapper
  common: board_r: Drop initr_api wrapper
  common: board_r: Drop initr_bbmii wrapper
  common: board_r: Drop arch-specific ifdefs around initr_trap
  spl: Kconfig: Add SPL dependency to CONFIG_HANDOFF
  global_data: Enable spl_handoff only if CONFIG_HANDOFF is set

 api/api.c|   6 +-
 api/api_private.h|   2 +-
 arch/arm/include/asm/system.h|  13 ++-
 arch/arm/lib/cache.c |   4 +-
 arch/m68k/lib/traps.c|   7 ++
 arch/mips/lib/traps.c|   7 ++
 arch/powerpc/cpu/mpc85xx/cpu_init.c  |   4 +-
 arch/powerpc/lib/Makefile|   1 +
 arch/powerpc/lib/traps.c |  17 
 common/Kconfig   |   8 ++
 common/board_f.c |  78 +++-
 common/board_r.c | 134 ---
 common/exports.c |   4 +-
 common/spl/Kconfig   |   2 +-
 drivers/net/phy/miiphybb.c   |   4 +-
 drivers/pci/pci-uclass.c |   4 +-
 drivers/pci/pci.c|   6 +-
 drivers/pci_endpoint/pci_ep-uclass.c |   4 +-
 drivers/xen/hypervisor.c |   4 +-
 include/api.h|  10 +-
 include/asm-generic/global_data.h|   4 +-
 include/exports.h|  10 +-
 include/init.h   |  46 -
 include/miiphy.h |  10 +-
 include/post.h   |  11 ++-
 include/xen.h|   2 +-
 post/post.c  |   4 +-
 27 files changed, 221 insertions(+), 185 deletions(-)
 create mode 100644 arch/powerpc/lib/traps.c

-- 
2.17.1



[PATCH] spi: ti_qspi: Fix "spi-max-frequency" error path in ti_qspi_ofdata_to_platdata

2020-11-28 Thread Ovidiu Panait
struct ti_qspi_priv->max_hz is declared as unsigned int, so the following
error path check will always be false, even when "spi-max-frequency"
property is invalid/missing:
  priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
  if (priv->max_hz < 0) {
...
  }

Replace the fdtdec call with dev_read_u32_default() and use 0 as the
default value. Error out if max_hz is zero.

Signed-off-by: Ovidiu Panait 
---

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

diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index 5fdbb49442..91be18e0a7 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -467,8 +467,8 @@ static int ti_qspi_ofdata_to_platdata(struct udevice *bus)
priv->memory_map = map_physmem(mmap_addr, mmap_size, MAP_NOCACHE);
priv->mmap_size = mmap_size;
 
-   priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
-   if (priv->max_hz < 0) {
+   priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
+   if (!priv->max_hz) {
debug("Error: Max frequency missing\n");
return -ENODEV;
}
-- 
2.17.1