This series cleans up a few issues in the system controller driver, and
then expands the exported regmap to support one of the pairs of LDOs
built in to the D1 SoC.
Eventually, we will need to update the SRAM region claiming API so
ownership can be swapped back and forth by consumer drivers. This is
necessary for uploading firmware to the R329/D1 DSPs, but it is not
needed for initial bringup.
Samuel Holland (9):
dt-bindings: sram: sunxi-sram: Add D1 compatible string
soc: sunxi: sram: Actually claim SRAM regions
soc: sunxi: sram: Prevent the driver from being unbound
soc: sunxi: sram: Fix probe function ordering issues
soc: sunxi: sram: Fix debugfs info for A64 SRAM C
soc: sunxi: sram: Return void from the release function
soc: sunxi: sram: Save a pointer to the OF match data
soc: sunxi: sram: Export the LDO control register
soc: sunxi: sram: Add support for the D1 system control
.../allwinner,sun4i-a10-system-control.yaml | 1 +
drivers/soc/sunxi/sunxi_sram.c | 74 ++++++++++---------
include/linux/soc/sunxi/sunxi_sram.h | 2 +-
3 files changed, 42 insertions(+), 35 deletions(-)
--
2.35.1
sunxi_sram_claim() checks the sram_desc->claimed flag before updating
the register, with the intent that only one device can claim a region.
However, this was ineffective because the flag was never set.
Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs")
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index a8f3876963a0..f3d3f9259df9 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -254,6 +254,7 @@ int sunxi_sram_claim(struct device *dev)
writel(val | ((device << sram_data->offset) & mask),
base + sram_data->reg);
+ sram_desc->claimed = true;
spin_unlock(&sram_lock);
return 0;
--
2.35.1
Errors from debugfs are intended to be non-fatal, and should not prevent
the driver from probing.
Since debugfs file creation is treated as infallible, move it below the
parts of the probe function that can fail. This prevents an error
elsewhere in the probe function from causing the file to leak. Do the
same for the call to of_platform_populate().
Finally, checkpatch suggests an octal literal for the file permissions.
Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs")
Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64")
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index a858a37fcdd4..52d07bed7664 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -332,9 +332,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
static int __init sunxi_sram_probe(struct platform_device *pdev)
{
- struct dentry *d;
struct regmap *emac_clock;
const struct sunxi_sramc_variant *variant;
+ struct device *dev = &pdev->dev;
sram_dev = &pdev->dev;
@@ -346,13 +346,6 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-
- d = debugfs_create_file("sram", S_IRUGO, NULL, NULL,
- &sunxi_sram_fops);
- if (!d)
- return -ENOMEM;
-
if (variant->num_emac_clocks > 0) {
emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
&sunxi_sram_emac_clock_regmap);
@@ -361,6 +354,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
return PTR_ERR(emac_clock);
}
+ of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+ debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops);
+
return 0;
}
--
2.35.1
It is inefficient to match the compatible string every time the regmap
is accessed.
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 9622fd45f5e5..7c6fb17cfe7f 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -305,9 +305,7 @@ static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
unsigned int reg)
{
- const struct sunxi_sramc_variant *variant;
-
- variant = of_device_get_match_data(dev);
+ const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
if (reg < SUNXI_SRAM_EMAC_CLOCK_REG)
return false;
@@ -340,6 +338,8 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
if (!variant)
return -EINVAL;
+ dev_set_drvdata(dev, (struct sunxi_sramc_variant *)variant);
+
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
--
2.35.1
D1 has a single EMAC and some LDOs that need to be exported.
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 7e8dab0f0ec4..92f9186c1c42 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -294,6 +294,11 @@ static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = {
.num_emac_clocks = 1,
};
+static const struct sunxi_sramc_variant sun20i_d1_sramc_variant = {
+ .num_emac_clocks = 1,
+ .has_ldo_ctrl = true,
+};
+
static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
.num_emac_clocks = 1,
};
@@ -382,6 +387,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
.compatible = "allwinner,sun8i-h3-system-control",
.data = &sun8i_h3_sramc_variant,
},
+ {
+ .compatible = "allwinner,sun20i-d1-system-control",
+ .data = &sun20i_d1_sramc_variant,
+ },
{
.compatible = "allwinner,sun50i-a64-sram-controller",
.data = &sun50i_a64_sramc_variant,
--
2.35.1
Some newer Allwinner SoCs contain internal LDOs managed by a register in
the system control MMIO space. Export this from the regmap in addtion to
the EMAC register.
Use generic names now that the regmap is no longer EMAC-specific.
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 7c6fb17cfe7f..7e8dab0f0ec4 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -283,6 +283,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
struct sunxi_sramc_variant {
int num_emac_clocks;
+ bool has_ldo_ctrl;
};
static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
@@ -302,25 +303,28 @@ static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
};
#define SUNXI_SRAM_EMAC_CLOCK_REG 0x30
+#define SUNXI_SYS_LDO_CTRL_REG 0x150
+
static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
unsigned int reg)
{
const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
- if (reg < SUNXI_SRAM_EMAC_CLOCK_REG)
- return false;
- if (reg > SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
- return false;
+ if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
+ reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
+ return true;
+ if (reg == SUNXI_SYS_LDO_CTRL_REG && variant->has_ldo_ctrl)
+ return true;
- return true;
+ return false;
}
-static struct regmap_config sunxi_sram_emac_clock_regmap = {
+static struct regmap_config sunxi_sram_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
/* last defined register */
- .max_register = SUNXI_SRAM_EMAC_CLOCK_REG + 4,
+ .max_register = SUNXI_SYS_LDO_CTRL_REG,
/* other devices have no business accessing other registers */
.readable_reg = sunxi_sram_regmap_accessible_reg,
.writeable_reg = sunxi_sram_regmap_accessible_reg,
@@ -328,9 +332,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
static int __init sunxi_sram_probe(struct platform_device *pdev)
{
- struct regmap *emac_clock;
const struct sunxi_sramc_variant *variant;
struct device *dev = &pdev->dev;
+ struct regmap *regmap;
sram_dev = &pdev->dev;
@@ -344,12 +348,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- if (variant->num_emac_clocks > 0) {
- emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
- &sunxi_sram_emac_clock_regmap);
-
- if (IS_ERR(emac_clock))
- return PTR_ERR(emac_clock);
+ if (variant->num_emac_clocks || variant->has_ldo_ctrl) {
+ regmap = devm_regmap_init_mmio(dev, base, &sunxi_sram_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
}
of_platform_populate(dev->of_node, NULL, NULL, dev);
--
2.35.1
There is no point in returning an error here, as the caller can do
nothing about it. In fact, all callers already ignore the return value.
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 8 +++-----
include/linux/soc/sunxi/sunxi_sram.h | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 09754cd1d57d..9622fd45f5e5 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -261,25 +261,23 @@ int sunxi_sram_claim(struct device *dev)
}
EXPORT_SYMBOL(sunxi_sram_claim);
-int sunxi_sram_release(struct device *dev)
+void sunxi_sram_release(struct device *dev)
{
const struct sunxi_sram_data *sram_data;
struct sunxi_sram_desc *sram_desc;
if (!dev || !dev->of_node)
- return -EINVAL;
+ return;
sram_data = sunxi_sram_of_parse(dev->of_node, NULL);
if (IS_ERR(sram_data))
- return -EINVAL;
+ return;
sram_desc = to_sram_desc(sram_data);
spin_lock(&sram_lock);
sram_desc->claimed = false;
spin_unlock(&sram_lock);
-
- return 0;
}
EXPORT_SYMBOL(sunxi_sram_release);
diff --git a/include/linux/soc/sunxi/sunxi_sram.h b/include/linux/soc/sunxi/sunxi_sram.h
index c5f663bba9c2..60e274d1b821 100644
--- a/include/linux/soc/sunxi/sunxi_sram.h
+++ b/include/linux/soc/sunxi/sunxi_sram.h
@@ -14,6 +14,6 @@
#define _SUNXI_SRAM_H_
int sunxi_sram_claim(struct device *dev);
-int sunxi_sram_release(struct device *dev);
+void sunxi_sram_release(struct device *dev);
#endif /* _SUNXI_SRAM_H_ */
--
2.35.1
This driver exports a regmap tied to the platform device (as opposed to
a syscon, which exports a regmap tied to the OF node). Because of this,
the driver can never be unbound, as that would destroy the regmap. Use
builtin_platform_driver_probe() to enforce this limitation.
Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64")
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index f3d3f9259df9..a858a37fcdd4 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -330,7 +330,7 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
.writeable_reg = sunxi_sram_regmap_accessible_reg,
};
-static int sunxi_sram_probe(struct platform_device *pdev)
+static int __init sunxi_sram_probe(struct platform_device *pdev)
{
struct dentry *d;
struct regmap *emac_clock;
@@ -410,9 +410,8 @@ static struct platform_driver sunxi_sram_driver = {
.name = "sunxi-sram",
.of_match_table = sunxi_sram_dt_match,
},
- .probe = sunxi_sram_probe,
};
-module_platform_driver(sunxi_sram_driver);
+builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);
MODULE_AUTHOR("Maxime Ripard <[email protected]>");
MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
--
2.35.1
The labels were backward with respect to the register values. The SRAM
is mapped to the CPU when the register value is 1.
Fixes: 5e4fb6429761 ("drivers: soc: sunxi: add support for A64 and its SRAM C")
Signed-off-by: Samuel Holland <[email protected]>
---
drivers/soc/sunxi/sunxi_sram.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 52d07bed7664..09754cd1d57d 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = {
static struct sunxi_sram_desc sun50i_a64_sram_c = {
.data = SUNXI_SRAM_DATA("C", 0x4, 24, 1,
- SUNXI_SRAM_MAP(0, 1, "cpu"),
- SUNXI_SRAM_MAP(1, 0, "de2")),
+ SUNXI_SRAM_MAP(1, 0, "cpu"),
+ SUNXI_SRAM_MAP(0, 1, "de2")),
};
static const struct of_device_id sunxi_sram_dt_ids[] = {
--
2.35.1
Dne ponedeljek, 01. avgust 2022 ob 05:05:03 CEST je Samuel Holland napisal(a):
> This driver exports a regmap tied to the platform device (as opposed to
> a syscon, which exports a regmap tied to the OF node). Because of this,
> the driver can never be unbound, as that would destroy the regmap. Use
> builtin_platform_driver_probe() to enforce this limitation.
>
> Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on
> A64") Signed-off-by: Samuel Holland <[email protected]>
Reviewed-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:02 CEST je Samuel Holland napisal(a):
> sunxi_sram_claim() checks the sram_desc->claimed flag before updating
> the register, with the intent that only one device can claim a region.
> However, this was ineffective because the flag was never set.
>
> Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map
> SRAMs") Signed-off-by: Samuel Holland <[email protected]>
Reviewed-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:04 CEST je Samuel Holland napisal(a):
> Errors from debugfs are intended to be non-fatal, and should not prevent
> the driver from probing.
>
> Since debugfs file creation is treated as infallible, move it below the
> parts of the probe function that can fail. This prevents an error
> elsewhere in the probe function from causing the file to leak. Do the
> same for the call to of_platform_populate().
>
> Finally, checkpatch suggests an octal literal for the file permissions.
>
> Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map
> SRAMs") Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock
> reg on A64") Signed-off-by: Samuel Holland <[email protected]>
Reviewed-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:06 CEST je Samuel Holland napisal(a):
> There is no point in returning an error here, as the caller can do
> nothing about it. In fact, all callers already ignore the return value.
>
> Signed-off-by: Samuel Holland <[email protected]>
Acked-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:09 CEST je Samuel Holland napisal(a):
> D1 has a single EMAC and some LDOs that need to be exported.
>
> Signed-off-by: Samuel Holland <[email protected]>
Acked-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:05 CEST je Samuel Holland napisal(a):
> The labels were backward with respect to the register values. The SRAM
> is mapped to the CPU when the register value is 1.
>
> Fixes: 5e4fb6429761 ("drivers: soc: sunxi: add support for A64 and its SRAM
> C")
> Signed-off-by: Samuel Holland <[email protected]>
Acked-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:07 CEST je Samuel Holland napisal(a):
> It is inefficient to match the compatible string every time the regmap
> is accessed.
>
> Signed-off-by: Samuel Holland <[email protected]>
Acked-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej
Dne ponedeljek, 01. avgust 2022 ob 05:05:08 CEST je Samuel Holland napisal(a):
> Some newer Allwinner SoCs contain internal LDOs managed by a register in
> the system control MMIO space. Export this from the regmap in addtion to
> the EMAC register.
>
> Use generic names now that the regmap is no longer EMAC-specific.
>
> Signed-off-by: Samuel Holland <[email protected]>
Acked-by: Jernej Skrabec <[email protected]>
Best regards,
Jernej