@@ -20,6 +20,7 @@
#include <linux/math.h>
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/rcar_fuse.h>
#include <linux/platform_device.h>
#include <linux/psci.h>
#include <linux/slab.h>
@@ -27,6 +28,8 @@
#include "core.h"
+#define FUSE_MON0 0x3e4 /* R-Car Gen3 */
+
static int sh_pfc_map_resources(struct sh_pfc *pfc,
struct platform_device *pdev)
{
@@ -1372,6 +1375,21 @@ static int sh_pfc_probe(struct platform_device *pdev)
}
#endif
+ if (pfc->info->nr_fuse_regs) {
+ struct rcar_fuse_platform_data pdata = {
+ .base = pfc->windows[0].virt,
+ .offset = FUSE_MON0,
+ .nregs = pfc->info->nr_fuse_regs,
+ };
+ struct platform_device *fdev;
+
+ fdev = platform_device_register_data(pfc->dev, "rcar_fuse", -1,
+ &pdata, sizeof(pdata));
+ if (IS_ERR(fdev))
+ dev_err_probe(pfc->dev, PTR_ERR(fdev),
+ "failed to register fuses, ignoring\n");
+ }
+
platform_set_drvdata(pdev, pfc);
dev_info(pfc->dev, "%s support registered\n", info->name);
@@ -6187,5 +6187,7 @@ const struct sh_pfc_soc_info r8a77951_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
#endif
@@ -6139,6 +6139,8 @@ const struct sh_pfc_soc_info r8a77960_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
#endif
@@ -6166,5 +6168,7 @@ const struct sh_pfc_soc_info r8a77961_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
#endif
@@ -6380,5 +6380,7 @@ const struct sh_pfc_soc_info r8a77965_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
#endif
@@ -2557,4 +2557,6 @@ const struct sh_pfc_soc_info r8a77970_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 4,
};
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/of.h>
#include "sh_pfc.h"
@@ -3048,13 +3049,22 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = {
{ /* sentinel */ }
};
+static int r8a77980_pinmux_init(struct sh_pfc *pfc)
+{
+ if (of_machine_is_compatible("renesas,r8a77980a"))
+ r8a77980_pinmux_info.nr_fuse_regs = 5;
+
+ return 0;
+}
+
static const struct sh_pfc_soc_operations r8a77980_pfc_ops = {
+ .init = r8a77980_pinmux_init,
.pin_to_pocctrl = r8a77980_pin_to_pocctrl,
.get_bias = rcar_pinmux_get_bias,
.set_bias = rcar_pinmux_set_bias,
};
-const struct sh_pfc_soc_info r8a77980_pinmux_info = {
+struct sh_pfc_soc_info r8a77980_pinmux_info = {
.name = "r8a77980_pfc",
.ops = &r8a77980_pfc_ops,
.unlock_reg = 0xe6060000, /* PMMR */
@@ -3074,4 +3084,6 @@ const struct sh_pfc_soc_info r8a77980_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
@@ -5336,5 +5336,7 @@ const struct sh_pfc_soc_info r8a77990_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
#endif
@@ -3193,4 +3193,6 @@ const struct sh_pfc_soc_info r8a77995_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+
+ .nr_fuse_regs = 1,
};
@@ -290,6 +290,8 @@ struct sh_pfc_soc_info {
unsigned int pinmux_data_size;
u32 unlock_reg; /* can be literal address or mask */
+
+ unsigned int nr_fuse_regs;
};
extern const struct sh_pfc_soc_info emev2_pinmux_info;
@@ -316,7 +318,7 @@ extern const struct sh_pfc_soc_info r8a77960_pinmux_info;
extern const struct sh_pfc_soc_info r8a77961_pinmux_info;
extern const struct sh_pfc_soc_info r8a77965_pinmux_info;
extern const struct sh_pfc_soc_info r8a77970_pinmux_info;
-extern const struct sh_pfc_soc_info r8a77980_pinmux_info;
+extern struct sh_pfc_soc_info r8a77980_pinmux_info;
extern const struct sh_pfc_soc_info r8a77990_pinmux_info;
extern const struct sh_pfc_soc_info r8a77995_pinmux_info;
extern const struct sh_pfc_soc_info r8a779a0_pinmux_info;
On R-Car Gen3 SoCs, the fuse registers are tightly integrated into the Pin Function Controller. Add support for them by providing the rcar-fuse driver with all needed info through a platform device and platform data. Note that the number of fuse registers on R-Car V3H and V3H2 differs, while their PFC blocks use the same compatible value, hence this is handled by checking the top-level compatible value. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> --- FUSE_MON[1-3] on R-Car V3M were only briefly documented in Hardware User's Manual Rev. 0.52/0.53 --- drivers/pinctrl/renesas/core.c | 18 ++++++++++++++++++ drivers/pinctrl/renesas/pfc-r8a77951.c | 2 ++ drivers/pinctrl/renesas/pfc-r8a7796.c | 4 ++++ drivers/pinctrl/renesas/pfc-r8a77965.c | 2 ++ drivers/pinctrl/renesas/pfc-r8a77970.c | 2 ++ drivers/pinctrl/renesas/pfc-r8a77980.c | 14 +++++++++++++- drivers/pinctrl/renesas/pfc-r8a77990.c | 2 ++ drivers/pinctrl/renesas/pfc-r8a77995.c | 2 ++ drivers/pinctrl/renesas/sh_pfc.h | 4 +++- 9 files changed, 48 insertions(+), 2 deletions(-)