From 222782ff647dfeb33bb442031792a893372fad82 Mon Sep 17 00:00:00 2001
From: Christophe Priouzeau <christophe.priouzeau@st.com>
Date: Mon, 26 Nov 2018 14:43:58 +0100
Subject: [PATCH 25/52] ARM-stm32mp1-r0-rc2-REMOTEPROC

---
 .../devicetree/bindings/remoteproc/rproc-srm.txt   |  14 ++-
 .../devicetree/bindings/remoteproc/stm32-rproc.txt |  15 ++-
 drivers/nvmem/stm32-romem.c                        |  44 +++++----
 drivers/remoteproc/rproc_srm_core.h                |  14 +--
 drivers/remoteproc/rproc_srm_dev.c                 | 103 +--------------------
 drivers/remoteproc/stm32_rproc.c                   |   2 +-
 6 files changed, 42 insertions(+), 150 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/rproc-srm.txt b/Documentation/devicetree/bindings/remoteproc/rproc-srm.txt
index dce10c0..19a5255 100644
--- a/Documentation/devicetree/bindings/remoteproc/rproc-srm.txt
+++ b/Documentation/devicetree/bindings/remoteproc/rproc-srm.txt
@@ -23,12 +23,16 @@ Optional properties:
 - clocks: clocks required by the coprocessor
 - clock-names: see clock-bindings.txt
 - pinctrl-x: pins configurations required by the coprocessor
-- pinctrl-names: see pinctrl-bindings.txt.
-	"rproc_default" is a special pin configuration which is applied except
-	if the 'early-booted' property is set.
-	In a general way, it is recommended to use names prefixed with "rproc_".
+	The SRM reserves the pins for the coprocessor, which prevents the local
+	processor to use them.
+- pinctrl-names: all names must be prefixed with "rproc_" (ex: "rproc_default").
+	This rule must be strictly followed in order to prevent the SRM to
+	(over)write a pin configuration which is done by the coprocessor.
 - x-supply: power supplies required by the coprocessor
-- interrupts: see interrupts.txt
+- interrupts: external interrupts configurations required by the coprocessor.
+	This is optional since the configuration is done by the coprocessor.
+	When defined, the SRM (over)writes the configuration which allows the
+	interrupt controller to check for configuration conflicts.
 - interrupt-parent: see interrupts.txt
 - interrupt-names: see interrupts.txt
 
diff --git a/Documentation/devicetree/bindings/remoteproc/stm32-rproc.txt b/Documentation/devicetree/bindings/remoteproc/stm32-rproc.txt
index ee00f1c..7df6a26 100644
--- a/Documentation/devicetree/bindings/remoteproc/stm32-rproc.txt
+++ b/Documentation/devicetree/bindings/remoteproc/stm32-rproc.txt
@@ -33,18 +33,15 @@ Optional properties:
 		      - from local to remote = send message
 		      - from remote to local = send message ack
 		- a channel (b) working the opposite direction of channel (a)
-		- a channel (c) used for two different purposes:
-		    - used by the remote proc to signal when it has completed
-		      its critical initalisation.
-		      Mono-directional channel: from remote to local
-		    - used by the local proc to notify the remote proc that it
-		      is about to be shut down.
-		      Mono-directional channel: from local to remote, where ACK
-		      from the remote means that it is ready for shutdown
+		- a channel (c) used by the local proc to notify the remote proc
+		  that it is about to be shut down.
+		  Mono-directional channel:
+		      - from local to remote, where ACK from the remote means
+		        that it is ready for shutdown
 - mbox-names:	This property is required if the mboxes property is used.
 		- must be "vq0" for channel (a)
 		- must be "vq1" for channel (b)
-		- must be "init_shdn" for channel (c)
+		- must be "shutdown" for channel (c)
 - memory-region: phandle to the reserved memory node to be associated with the
 		remoteproc device.
 - st,syscfg-pdds: Reference to the system configuration controlling the remote
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index 198872f..34b388c 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -19,6 +19,12 @@
 #define STM32_SMC_WRITE_SHADOW		0x03
 #define STM32_SMC_READ_OTP		0x04
 
+/* shadow registers offest */
+#define STM32MP15_BSEC_DATA0		0x200
+
+/* 32 (x 32-bits) lower shadow registers */
+#define STM32MP15_BSEC_NUM_LOWER	32
+
 struct stm32_romem_cfg {
 	int size;
 };
@@ -77,13 +83,21 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
 		return -EINVAL;
 
 	for (i = roffset; (i < roffset + rbytes); i += 4) {
-		ret = stm32_bsec_smc(STM32_SMC_READ_OTP, i >> 2, 0, &val);
-		if (ret) {
-			dev_err(priv->dev, "Failed to read data%d (%d)\n",
-				i >> 2, ret);
-			return ret;
+		u32 otp = i >> 2;
+
+		if (otp < STM32MP15_BSEC_NUM_LOWER) {
+			/* read lower data from shadow registers */
+			val = readl_relaxed(
+				priv->base + STM32MP15_BSEC_DATA0 + i);
+		} else {
+			ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, otp, 0,
+					     &val);
+			if (ret) {
+				dev_err(priv->dev, "Can't read data%d (%d)\n",
+					otp, ret);
+				return ret;
+			}
 		}
-
 		/* skip first bytes in case of unaligned read */
 		if (skip_bytes)
 			size = min(bytes, (size_t)(4 - skip_bytes));
@@ -127,7 +141,6 @@ static int stm32_romem_probe(struct platform_device *pdev)
 	const struct stm32_romem_cfg *cfg;
 	struct device *dev = &pdev->dev;
 	struct stm32_romem_priv *priv;
-	struct nvmem_device *nvmem;
 	struct resource *res;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -154,26 +167,12 @@ static int stm32_romem_probe(struct platform_device *pdev)
 		priv->cfg.size = resource_size(res);
 		priv->cfg.reg_read = stm32_romem_read;
 	} else {
-		priv->cfg.read_only = false;
 		priv->cfg.size = cfg->size;
 		priv->cfg.reg_read = stm32_bsec_read;
 		priv->cfg.reg_write = stm32_bsec_write;
 	}
 
-	nvmem = nvmem_register(&priv->cfg);
-	if (IS_ERR(nvmem))
-		return PTR_ERR(nvmem);
-
-	platform_set_drvdata(pdev, nvmem);
-
-	return 0;
-}
-
-static int stm32_romem_remove(struct platform_device *pdev)
-{
-	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
-
-	return nvmem_unregister(nvmem);
+	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
 }
 
 static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
@@ -191,7 +190,6 @@ MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
 
 static struct platform_driver stm32_romem_driver = {
 	.probe = stm32_romem_probe,
-	.remove = stm32_romem_remove,
 	.driver = {
 		.name = "stm32-romem",
 		.of_match_table = of_match_ptr(stm32_romem_of_match),
diff --git a/drivers/remoteproc/rproc_srm_core.h b/drivers/remoteproc/rproc_srm_core.h
index 7915f35..7dffdb38 100644
--- a/drivers/remoteproc/rproc_srm_core.h
+++ b/drivers/remoteproc/rproc_srm_core.h
@@ -20,12 +20,10 @@
 /**
  * Resource type used in resource manager rpmsg:
  *  RPROC_SRM_RSC_CLOCK:        clock resource
- *  RPROC_SRM_RSC_PIN:          pin resource
  *  RPROC_SRM_RSC_REGU:         regulator resource
  */
 #define RPROC_SRM_RSC_CLOCK     0x00
-#define RPROC_SRM_RSC_PIN       0x01
-#define RPROC_SRM_RSC_REGU      0x02
+#define RPROC_SRM_RSC_REGU      0x01
 
 /**
  * struct clock_cfg - clock configuration used in resource manager rpmsg
@@ -63,14 +61,6 @@ struct regu_cfg {
 };
 
 /**
- * struct pin_cfg - pin configuration used in resource manager rpmsg
- * @name:       current pin configuration name (meaningful in GetConfig message)
- */
-struct pin_cfg {
-	u8 name[16];
-};
-
-/**
  * struct rpmsg_srm_msg - message structure used between processors to
  *                        dynamically update resources configuration
  * @message_type: type of the message: see RPROC_SRM_MSG*
@@ -81,7 +71,6 @@ struct pin_cfg {
  *              see RPROC_SRM_RSC*
  * @clock_cfg:  clock config - relevant if &rsc_type is RPROC_SRM_RSC_CLOCK
  * @regu_cfg:   regulator config - relevant if &rsc_type is RPROC_SRM_RSC_REGU
- * @pin_cfg:    pin config - relevant if &rsc_type is RPROC_SRM_RSC_PIN
  */
 struct rpmsg_srm_msg {
 	u32 message_type;
@@ -90,7 +79,6 @@ struct rpmsg_srm_msg {
 	union {
 		struct clock_cfg clock_cfg;
 		struct regu_cfg regu_cfg;
-		struct pin_cfg pin_cfg;
 	};
 };
 
diff --git a/drivers/remoteproc/rproc_srm_dev.c b/drivers/remoteproc/rproc_srm_dev.c
index b026f961..7dc99c5 100644
--- a/drivers/remoteproc/rproc_srm_dev.c
+++ b/drivers/remoteproc/rproc_srm_dev.c
@@ -31,7 +31,6 @@ struct rproc_srm_pin_info {
 	struct list_head list;
 	unsigned int index;
 	char *name;
-	bool selected;
 };
 
 struct rproc_srm_regu_info {
@@ -544,83 +543,6 @@ static int rproc_srm_dev_regus_get(struct rproc_srm_dev *rproc_srm_dev)
 }
 
 /* Pins */
-static int rproc_srm_dev_pin_set_cfg(struct rproc_srm_dev *rproc_srm_dev,
-				     struct pin_cfg *cfg)
-{
-	struct rproc_srm_pin_info *pi, *p = NULL;
-	struct device *dev = rproc_srm_dev->dev;
-	struct pinctrl_state *state;
-	int ret;
-
-	list_for_each_entry(pi, &rproc_srm_dev->pin_list_head, list) {
-		if (!strcmp(pi->name, cfg->name)) {
-			p = pi;
-			break;
-		}
-	}
-
-	if (!p) {
-		dev_err(dev, "unknown pin config (%s)\n", cfg->name);
-		return -EINVAL;
-	}
-
-	state = pinctrl_lookup_state(rproc_srm_dev->pctrl, cfg->name);
-	if (IS_ERR(state)) {
-		dev_err(dev, "cannot get pin config (%s)\n", cfg->name);
-		return -EINVAL;
-	}
-
-	ret = pinctrl_select_state(rproc_srm_dev->pctrl, state);
-	if (ret < 0) {
-		dev_err(dev, "cannot set pin config (%s)\n", cfg->name);
-		return ret;
-	}
-
-	list_for_each_entry(pi, &rproc_srm_dev->pin_list_head, list) {
-		pi->selected = (pi == p);
-	}
-
-	dev_dbg(dev, "pin config (%s) selected\n", p->name);
-
-	return 0;
-}
-
-static int rproc_srm_dev_pin_get_cfg(struct rproc_srm_dev *rproc_srm_dev,
-				     struct pin_cfg *cfg)
-{
-	struct rproc_srm_pin_info *p;
-
-	list_for_each_entry(p, &rproc_srm_dev->pin_list_head, list) {
-		if (p->selected) {
-			strlcpy(cfg->name, p->name, sizeof(cfg->name));
-			return 0;
-		}
-	}
-
-	dev_warn(rproc_srm_dev->dev, "cannot find selected pin state\n");
-	strcpy(cfg->name, "");
-
-	return 0;
-}
-
-static int rproc_srm_dev_pins_setup(struct rproc_srm_dev *rproc_srm_dev)
-{
-	struct rproc_srm_pin_info *p;
-	struct pin_cfg cfg = { .name = "rproc_default" };
-
-	if (rproc_srm_dev->early_boot)
-		/* in early_boot mode do not update pin config */
-		return 0;
-
-	/* set the "rproc_default" pin config if defined */
-	list_for_each_entry(p, &rproc_srm_dev->pin_list_head, list) {
-		if (!strcmp(p->name, cfg.name))
-			return rproc_srm_dev_pin_set_cfg(rproc_srm_dev, &cfg);
-	}
-
-	return 0;
-}
-
 static void rproc_srm_dev_pins_put(struct rproc_srm_dev *rproc_srm_dev)
 {
 	struct device *dev = rproc_srm_dev->dev;
@@ -677,11 +599,9 @@ static int rproc_srm_dev_pins_get(struct rproc_srm_dev *rproc_srm_dev)
 		}
 		p->name = devm_kstrdup(dev, name, GFP_KERNEL);
 
-		if (!strcmp(p->name, PINCTRL_STATE_DEFAULT)) {
-			if (rproc_srm_dev->early_boot)
-				dev_warn(dev, "pin config potentially overwritten!\n");
-			p->selected = true;
-		}
+		/* pinctrl-names shall not be "default" (but "rproc_default") */
+		if (!strcmp(p->name, PINCTRL_STATE_DEFAULT))
+			dev_warn(dev, "pin config potentially overwritten!\n");
 
 		p->index = i;
 
@@ -726,13 +646,6 @@ static int rproc_srm_dev_notify_cb(struct notifier_block *nb, unsigned long evt,
 				ret = rproc_srm_dev_clock_get_cfg(rproc_srm_dev,
 								  &o.clock_cfg);
 			break;
-		case RPROC_SRM_RSC_PIN:
-			ret = rproc_srm_dev_pin_set_cfg(rproc_srm_dev,
-							&i->pin_cfg);
-			if (!ret)
-				ret = rproc_srm_dev_pin_get_cfg(rproc_srm_dev,
-								&o.pin_cfg);
-			break;
 		case RPROC_SRM_RSC_REGU:
 			ret = rproc_srm_dev_regu_set_cfg(rproc_srm_dev,
 							 &i->regu_cfg);
@@ -752,10 +665,6 @@ static int rproc_srm_dev_notify_cb(struct notifier_block *nb, unsigned long evt,
 			ret = rproc_srm_dev_clock_get_cfg(rproc_srm_dev,
 							  &o.clock_cfg);
 			break;
-		case RPROC_SRM_RSC_PIN:
-			ret = rproc_srm_dev_pin_get_cfg(rproc_srm_dev,
-							&o.pin_cfg);
-			break;
 		case RPROC_SRM_RSC_REGU:
 			ret = rproc_srm_dev_regu_get_cfg(rproc_srm_dev,
 							 &o.regu_cfg);
@@ -810,11 +719,7 @@ rproc_srm_dev_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		return ret;
 
-	ret = rproc_srm_dev_pins_setup(rproc_srm_dev);
-	if (ret)
-		return ret;
-
-	/* For IRQs: nothing to setup */
+	/* For pins and IRQs: nothing to setup */
 	return 0;
 }
 
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 998de67..548afdd 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -29,7 +29,7 @@
 
 #define STM32_MBX_VQ0		"vq0"
 #define STM32_MBX_VQ1		"vq1"
-#define STM32_MBX_SHUTDOWN	"init_shdn"
+#define STM32_MBX_SHUTDOWN	"shutdown"
 
 struct stm32_syscon {
 	struct regmap *map;
-- 
2.7.4

