[PATCH v8 12/24] core: remap: fix regmap_init_mem_plat() reg size handeling
Johan Jonker
jbx6244 at gmail.com
Mon Mar 13 01:30:46 CET 2023
The fdt_addr_t and phys_addr_t size have been decoupled.
A 32bit CPU can expect 64-bit data from the device tree parser,
so convert regmap_init_mem_plat() input to handel both. The
syscon class driver also makes use of the regmap_init_mem_plat()
function, but has no way of knowing the format of the
device-specific platform data. In case of odd reg structures other
then that the syscon class driver assumes the regmap must be
filled in the individual syscon driver before pre-probe.
Also fix the ARRAY_SIZE divider in the syscon class driver.
Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
Changed V8:
fix comment
Changed V7:
changed title
add reg size input
rework function calls
---
drivers/core/regmap.c | 23 +++++++++++++++++++----
drivers/core/syscon-uclass.c | 23 ++++++++++++++++++-----
drivers/ram/rockchip/sdram_rk3066.c | 2 +-
drivers/ram/rockchip/sdram_rk3188.c | 2 +-
drivers/ram/rockchip/sdram_rk322x.c | 2 +-
drivers/ram/rockchip/sdram_rk3288.c | 2 +-
drivers/ram/rockchip/sdram_rk3328.c | 2 +-
drivers/ram/rockchip/sdram_rk3399.c | 2 +-
include/regmap.h | 5 +++--
include/syscon.h | 13 -------------
10 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index e33bb9d7..dd323280 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -79,7 +79,7 @@ static struct regmap *regmap_alloc(int count)
}
#if CONFIG_IS_ENABLED(OF_PLATDATA)
-int regmap_init_mem_plat(struct udevice *dev, fdt_val_t *reg, int count,
+int regmap_init_mem_plat(struct udevice *dev, void *reg, int size, int count,
struct regmap **mapp)
{
struct regmap_range *range;
@@ -89,9 +89,24 @@ int regmap_init_mem_plat(struct udevice *dev, fdt_val_t *reg, int count,
if (!map)
return -ENOMEM;
- for (range = map->ranges; count > 0; reg += 2, range++, count--) {
- range->start = *reg;
- range->size = reg[1];
+ if (size == sizeof(fdt32_t)) {
+ fdt32_t *ptr = (fdt32_t *)reg;
+
+ for (range = map->ranges; count > 0;
+ ptr += 2, range++, count--) {
+ range->start = *ptr;
+ range->size = ptr[1];
+ }
+ } else if (size == sizeof(fdt64_t)) {
+ fdt64_t *ptr = (fdt64_t *)reg;
+
+ for (range = map->ranges; count > 0;
+ ptr += 2, range++, count--) {
+ range->start = *ptr;
+ range->size = ptr[1];
+ }
+ } else {
+ return -EINVAL;
}
*mapp = map;
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c
index 25fdb66e..a47b8bd3 100644
--- a/drivers/core/syscon-uclass.c
+++ b/drivers/core/syscon-uclass.c
@@ -49,17 +49,30 @@ static int syscon_pre_probe(struct udevice *dev)
if (device_get_uclass_id(dev->parent) == UCLASS_PCI)
return 0;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
/*
* With OF_PLATDATA we really have no way of knowing the format of
* the device-specific platform data. So we assume that it starts with
- * a 'reg' member, and this holds a single address and size. Drivers
- * using OF_PLATDATA will need to ensure that this is true.
+ * a 'reg' member that holds a single address and size. Drivers
+ * using OF_PLATDATA will need to ensure that this is true. In case of
+ * odd reg structures other then the syscon_base_plat structure
+ * below the regmap must be defined in the individual syscon driver.
*/
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct syscon_base_plat {
+ phys_addr_t reg[2];
+ };
+
struct syscon_base_plat *plat = dev_get_plat(dev);
- return regmap_init_mem_plat(dev, plat->reg, ARRAY_SIZE(plat->reg),
- &priv->regmap);
+ /*
+ * Return if the regmap is already defined in the individual
+ * syscon driver.
+ */
+ if (priv->regmap)
+ return 0;
+
+ return regmap_init_mem_plat(dev, plat->reg, sizeof(plat->reg[0]),
+ ARRAY_SIZE(plat->reg) / 2, &priv->regmap);
#else
return regmap_init_mem(dev_ofnode(dev), &priv->regmap);
#endif
diff --git a/drivers/ram/rockchip/sdram_rk3066.c b/drivers/ram/rockchip/sdram_rk3066.c
index a2425f22..39c0be56 100644
--- a/drivers/ram/rockchip/sdram_rk3066.c
+++ b/drivers/ram/rockchip/sdram_rk3066.c
@@ -801,7 +801,7 @@ static int rk3066_dmc_conv_of_plat(struct udevice *dev)
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
/* RK3066 supports dual-channel, set default channel num to 2. */
plat->num_channels = 1;
- ret = regmap_init_mem_plat(dev, of_plat->reg,
+ ret = regmap_init_mem_plat(dev, of_plat->reg, sizeof(of_plat->reg[0]),
ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 272b1b2d..ad9f936d 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -867,7 +867,7 @@ static int conv_of_plat(struct udevice *dev)
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
/* rk3188 supports dual-channel, set default channel num to 2 */
plat->num_channels = 1;
- ret = regmap_init_mem_plat(dev, of_plat->reg,
+ ret = regmap_init_mem_plat(dev, of_plat->reg, sizeof(of_plat->reg[0]),
ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
index 1b204fb5..892766a8 100644
--- a/drivers/ram/rockchip/sdram_rk322x.c
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -769,7 +769,7 @@ static int conv_of_plat(struct udevice *dev)
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
plat->num_channels = 1;
- ret = regmap_init_mem_plat(dev, of_plat->reg,
+ ret = regmap_init_mem_plat(dev, of_plat->reg, sizeof(of_plat->reg[0]),
ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 83778ad1..c99118fd 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -1029,7 +1029,7 @@ static int conv_of_plat(struct udevice *dev)
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
/* Rk3288 supports dual-channel, set default channel num to 2 */
plat->num_channels = 2;
- ret = regmap_init_mem_plat(dev, of_plat->reg,
+ ret = regmap_init_mem_plat(dev, of_plat->reg, sizeof(of_plat->reg[0]),
ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index 184c93f7..b5ca8ca4 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -54,7 +54,7 @@ static int conv_of_plat(struct udevice *dev)
struct dtd_rockchip_rk3328_dmc *dtplat = &plat->dtplat;
int ret;
- ret = regmap_init_mem_plat(dev, dtplat->reg,
+ ret = regmap_init_mem_plat(dev, dtplat->reg, sizeof(dtplat->reg[0]),
ARRAY_SIZE(dtplat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index b1fea04e..ec9baddd 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -3048,7 +3048,7 @@ static int conv_of_plat(struct udevice *dev)
struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
int ret;
- ret = regmap_init_mem_plat(dev, dtplat->reg,
+ ret = regmap_init_mem_plat(dev, dtplat->reg, sizeof(dtplat->reg[0]),
ARRAY_SIZE(dtplat->reg) / 2, &plat->map);
if (ret)
return ret;
diff --git a/include/regmap.h b/include/regmap.h
index e81a3602..22b04340 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -378,17 +378,18 @@ int regmap_init_mem(ofnode node, struct regmap **mapp);
*
* @dev: Device that uses this map
* @reg: List of address, size pairs
+ * @size: Size of one reg array item
* @count: Number of pairs (e.g. 1 if the regmap has a single entry)
* @mapp: Returns allocated map
* Return: 0 if OK, -ve on error
*
* This creates a new regmap with a list of regions passed in, rather than
- * using the device tree. It only supports 32-bit machines.
+ * using the device tree.
*
* Use regmap_uninit() to free it.
*
*/
-int regmap_init_mem_plat(struct udevice *dev, fdt_val_t *reg, int count,
+int regmap_init_mem_plat(struct udevice *dev, void *reg, int size, int count,
struct regmap **mapp);
int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index);
diff --git a/include/syscon.h b/include/syscon.h
index f5e6cc1a..7a5ee3fa 100644
--- a/include/syscon.h
+++ b/include/syscon.h
@@ -25,19 +25,6 @@ struct syscon_ops {
#define syscon_get_ops(dev) ((struct syscon_ops *)(dev)->driver->ops)
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-/*
- * We don't support 64-bit machines. If they are so resource-contrained that
- * they need to use OF_PLATDATA, something is horribly wrong with the
- * education of our hardware engineers.
- *
- * Update: 64-bit is now supported and we have an education crisis.
- */
-struct syscon_base_plat {
- fdt_val_t reg[2];
-};
-#endif
-
/**
* syscon_get_regmap() - Get access to a register map
*
--
2.20.1
More information about the U-Boot
mailing list