lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
authorAnup Patel <apatel@ventanamicro.com>
Wed, 19 Apr 2023 11:22:44 +0000 (16:52 +0530)
committerAnup Patel <anup@brainfault.org>
Mon, 5 Jun 2023 10:25:45 +0000 (15:55 +0530)
Let's use heap allocation in DesignWare and SiFive I2C drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
lib/utils/i2c/fdt_i2c_dw.c
lib/utils/i2c/fdt_i2c_sifive.c

index 71062f4..99b2ddb 100644 (file)
@@ -9,17 +9,12 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_string.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/i2c/dw_i2c.h>
 #include <sbi_utils/i2c/fdt_i2c.h>
 
-#define FDT_DW_I2C_ADAPTER_MAX 7
-
-static unsigned int fdt_dw_i2c_adapter_count;
-static struct dw_i2c_adapter
-       fdt_dw_i2c_adapter_array[FDT_DW_I2C_ADAPTER_MAX];
-
 extern struct fdt_i2c_adapter fdt_i2c_adapter_dw;
 
 static int fdt_dw_i2c_init(void *fdt, int nodeoff,
@@ -29,23 +24,24 @@ static int fdt_dw_i2c_init(void *fdt, int nodeoff,
        struct dw_i2c_adapter *adapter;
        u64 addr;
 
-       if (fdt_dw_i2c_adapter_count >= FDT_DW_I2C_ADAPTER_MAX)
-               return SBI_ENOSPC;
-
-       adapter = &fdt_dw_i2c_adapter_array[fdt_dw_i2c_adapter_count];
+       adapter = sbi_zalloc(sizeof(*adapter));
+       if (!adapter)
+               return SBI_ENOMEM;
 
        rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-       if (rc)
+       if (rc) {
+               sbi_free(adapter);
                return rc;
+       }
 
        adapter->addr = addr;
        adapter->adapter.driver = &fdt_i2c_adapter_dw;
 
        rc = dw_i2c_init(&adapter->adapter, nodeoff);
-       if (rc)
+       if (rc) {
+               sbi_free(adapter);
                return rc;
-
-       fdt_dw_i2c_adapter_count++;
+       }
 
        return 0;
 }
index 195541c..b85b245 100644 (file)
@@ -9,12 +9,11 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_timer.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/i2c/fdt_i2c.h>
 
-#define SIFIVE_I2C_ADAPTER_MAX 2
-
 #define SIFIVE_I2C_PRELO       0x00
 #define SIFIVE_I2C_PREHI       0x04
 #define SIFIVE_I2C_CTR         0x08
@@ -47,10 +46,6 @@ struct sifive_i2c_adapter {
        struct i2c_adapter adapter;
 };
 
-static unsigned int sifive_i2c_adapter_count;
-static struct sifive_i2c_adapter
-       sifive_i2c_adapter_array[SIFIVE_I2C_ADAPTER_MAX];
-
 extern struct fdt_i2c_adapter fdt_i2c_adapter_sifive;
 
 static inline void sifive_i2c_setreg(struct sifive_i2c_adapter *adap,
@@ -244,14 +239,15 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
        struct sifive_i2c_adapter *adapter;
        uint64_t addr;
 
-       if (sifive_i2c_adapter_count >= SIFIVE_I2C_ADAPTER_MAX)
-               return SBI_ENOSPC;
-
-       adapter = &sifive_i2c_adapter_array[sifive_i2c_adapter_count];
+       adapter = sbi_zalloc(sizeof(*adapter));
+       if (!adapter)
+               return SBI_ENOMEM;
 
        rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-       if (rc)
+       if (rc) {
+               sbi_free(adapter);
                return rc;
+       }
 
        adapter->addr = addr;
        adapter->adapter.driver = &fdt_i2c_adapter_sifive;
@@ -259,10 +255,11 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
        adapter->adapter.write = sifive_i2c_adapter_write;
        adapter->adapter.read = sifive_i2c_adapter_read;
        rc = i2c_adapter_add(&adapter->adapter);
-       if (rc)
+       if (rc) {
+               sbi_free(adapter);
                return rc;
+       }
 
-       sifive_i2c_adapter_count++;
        return 0;
 }