soc: sunxi: export a regmap for EMAC clock reg on A64
authorIcenowy Zheng <icenowy@aosc.io>
Wed, 11 Apr 2018 14:16:40 +0000 (22:16 +0800)
committerChen-Yu Tsai <wens@csie.org>
Tue, 19 Jun 2018 14:55:51 +0000 (22:55 +0800)
The A64 SRAM controller memory zone has a EMAC clock register, which is
needed by the Ethernet MAC driver (dwmac-sun8i).

Export a regmap for this register on A64.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[wens@csie.org: export whole address range with only EMAC register
accessible and drop regmap name]
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
drivers/soc/sunxi/sunxi_sram.c

index 882be5e..eec7fc6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/sunxi/sunxi_sram.h>
 
@@ -281,13 +282,51 @@ int sunxi_sram_release(struct device *dev)
 }
 EXPORT_SYMBOL(sunxi_sram_release);
 
+struct sunxi_sramc_variant {
+       bool has_emac_clock;
+};
+
+static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
+       /* Nothing special */
+};
+
+static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
+       .has_emac_clock = true,
+};
+
+#define SUNXI_SRAM_EMAC_CLOCK_REG      0x30
+static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
+                                            unsigned int reg)
+{
+       if (reg == SUNXI_SRAM_EMAC_CLOCK_REG)
+               return true;
+       return false;
+}
+
+static struct regmap_config sunxi_sram_emac_clock_regmap = {
+       .reg_bits       = 32,
+       .val_bits       = 32,
+       .reg_stride     = 4,
+       /* last defined register */
+       .max_register   = SUNXI_SRAM_EMAC_CLOCK_REG,
+       /* other devices have no business accessing other registers */
+       .readable_reg   = sunxi_sram_regmap_accessible_reg,
+       .writeable_reg  = sunxi_sram_regmap_accessible_reg,
+};
+
 static int sunxi_sram_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct dentry *d;
+       struct regmap *emac_clock;
+       const struct sunxi_sramc_variant *variant;
 
        sram_dev = &pdev->dev;
 
+       variant = of_device_get_match_data(&pdev->dev);
+       if (!variant)
+               return -EINVAL;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
@@ -300,12 +339,26 @@ static int sunxi_sram_probe(struct platform_device *pdev)
        if (!d)
                return -ENOMEM;
 
+       if (variant->has_emac_clock) {
+               emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
+                                                  &sunxi_sram_emac_clock_regmap);
+
+               if (IS_ERR(emac_clock))
+                       return PTR_ERR(emac_clock);
+       }
+
        return 0;
 }
 
 static const struct of_device_id sunxi_sram_dt_match[] = {
-       { .compatible = "allwinner,sun4i-a10-sram-controller" },
-       { .compatible = "allwinner,sun50i-a64-sram-controller" },
+       {
+               .compatible = "allwinner,sun4i-a10-sram-controller",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun50i-a64-sram-controller",
+               .data = &sun50i_a64_sramc_variant,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);