Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/7] regulator: core: Add regulator_set_voltage_rdev()
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

Refactor regulator_set_voltage_unlocked() by taking code related to
regulator_dev and creating a new function regulator_set_voltage_rdev(),
which operates only on struct regulator_dev.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index b740426..413a824 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -105,6 +105,9 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data);
 static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 				     int min_uV, int max_uV);
+static int regulator_set_voltage_rdev(struct regulator_dev *rdev,
+				      int min_uV, int max_uV,
+				      suspend_state_t state);
 static struct regulator *create_regulator(struct regulator_dev *rdev,
 					  struct device *dev,
 					  const char *supply_name);
@@ -2996,8 +2999,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	int ret = 0;
 	int old_min_uV, old_max_uV;
 	int current_uV;
-	int best_supply_uV = 0;
-	int supply_change_uV = 0;
 
 	pr_err("%s: %d\n", __func__, __LINE__);
 	/* If we're setting the same range as last time the change
@@ -3042,6 +3043,26 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	if (ret < 0)
 		goto out2;
 
+	ret = regulator_set_voltage_rdev(rdev, min_uV, max_uV, state);
+	if (ret < 0)
+		goto out2;
+
+out:
+	return 0;
+out2:
+	voltage->min_uV = old_min_uV;
+	voltage->max_uV = old_max_uV;
+
+	return ret;
+}
+
+static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
+				      int max_uV, suspend_state_t state)
+{
+	int best_supply_uV = 0;
+	int supply_change_uV = 0;
+	int ret;
+
 	if (rdev->supply &&
 	    regulator_ops_is_valid(rdev->supply->rdev,
 				   REGULATOR_CHANGE_VOLTAGE) &&
@@ -3053,13 +3074,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		selector = regulator_map_voltage(rdev, min_uV, max_uV);
 		if (selector < 0) {
 			ret = selector;
-			goto out2;
+			goto out;
 		}
 
 		best_supply_uV = _regulator_list_voltage(rdev, selector, 0);
 		if (best_supply_uV < 0) {
 			ret = best_supply_uV;
-			goto out2;
+			goto out;
 		}
 
 		best_supply_uV += rdev->desc->min_dropout_uV;
@@ -3067,7 +3088,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);
 		if (current_supply_uV < 0) {
 			ret = current_supply_uV;
-			goto out2;
+			goto out;
 		}
 
 		supply_change_uV = best_supply_uV - current_supply_uV;
@@ -3079,7 +3100,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		if (ret) {
 			dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
 					ret);
-			goto out2;
+			goto out;
 		}
 	}
 
@@ -3089,7 +3110,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		ret = _regulator_do_set_suspend_voltage(rdev, min_uV,
 							max_uV, state);
 	if (ret < 0)
-		goto out2;
+		goto out;
 
 	if (supply_change_uV < 0) {
 		ret = regulator_set_voltage_unlocked(rdev->supply,
@@ -3103,11 +3124,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 
 out:
 	return ret;
-out2:
-	voltage->min_uV = old_min_uV;
-	voltage->max_uV = old_max_uV;
-
-	return ret;
 }
 
 /**
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/7] regulator: core: Use re-entrant locks
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

Re-entrant locks were implemented in previous patches. They should
substitute all mutex_lock() and mutex_unlock() calls on regulators'
mutexes.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 413a824..c5478d2 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2274,9 +2274,9 @@ int regulator_enable(struct regulator *regulator)
 			return ret;
 	}
 
-	mutex_lock(&rdev->mutex);
+	regulator_lock(rdev);
 	ret = _regulator_enable(rdev);
-	mutex_unlock(&rdev->mutex);
+	regulator_unlock(rdev);
 
 	if (ret != 0 && rdev->supply)
 		regulator_disable(rdev->supply);
@@ -2384,9 +2384,9 @@ int regulator_disable(struct regulator *regulator)
 	if (regulator->always_on)
 		return 0;
 
-	mutex_lock(&rdev->mutex);
+	regulator_lock(rdev);
 	ret = _regulator_disable(rdev);
-	mutex_unlock(&rdev->mutex);
+	regulator_unlock(rdev);
 
 	if (ret == 0 && rdev->supply)
 		regulator_disable(rdev->supply);
@@ -2436,10 +2436,10 @@ int regulator_force_disable(struct regulator *regulator)
 	struct regulator_dev *rdev = regulator->rdev;
 	int ret;
 
-	mutex_lock(&rdev->mutex);
+	regulator_lock(rdev);
 	regulator->uA_load = 0;
 	ret = _regulator_force_disable(regulator->rdev);
-	mutex_unlock(&rdev->mutex);
+	regulator_unlock(rdev);
 
 	if (rdev->supply)
 		while (rdev->open_count--)
@@ -2587,9 +2587,9 @@ int regulator_is_enabled(struct regulator *regulator)
 	if (regulator->always_on)
 		return 1;
 
-	mutex_lock(&regulator->rdev->mutex);
+	regulator_lock(regulator->rdev);
 	ret = _regulator_is_enabled(regulator->rdev);
-	mutex_unlock(&regulator->rdev->mutex);
+	regulator_unlock(regulator->rdev);
 
 	return ret;
 }
-- 
2.7.4

^ permalink raw reply related

* [PATCH 4/7] regulator: core: Implement voltage balancing algorithm
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

On Odroid XU3/4 and other Exynos5422 based boards there is a case, that
different devices on the board are supplied by different regulators
with non-fixed voltages. If one of these devices temporarily requires
higher voltage, there might occur a situation that the spread between
two devices' voltages is so high, that there is a risk of changing
'high' and 'low' states on the interconnection between devices powered
by those regulators.

Introduce new function regulator_balance_voltage(), which
keeps max_spread constraint fulfilled between a group of coupled
regulators. It should be called if a regulator changes its
voltage or after disabling or enabling. Disabled regulators should
follow changes of the enabled ones, but their consumers' demands
shouldn't be taken into account while calculating voltage of other
coupled regulators.

Find voltages, which are closest to suiting all the consumers' demands,
while fulfilling max_spread constraint, keeping the following rules:
- if one regulator is about to rise its voltage, rise others
  voltages in order to keep the max_spread
- if a regulator, which has caused rising other regulators, is
  lowered, lower other regulators if possible
- if one regulator is about to lower its voltage, but it hasn't caused
  rising other regulators, don't change its voltage if it breaks the
  max_spread

Change regulators' voltages step by step, keeping max_spread constraint
fulfilled all the time. Function regulator_get_optimal_voltage()
should find the best possible change for the regulator, which doesn't
break max_spread constraint. In function regulator_balance_voltage()
optimize number of steps by finding highest voltage difference on
each iteration.

If a regulator, which is about to change its voltage, is not coupled,
method regulator_get_optimal_voltage() should simply return the lowest
voltage fulfilling consumers' demands.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c5478d2..0b366c5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -105,6 +105,8 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data);
 static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 				     int min_uV, int max_uV);
+static int regulator_balance_voltage(struct regulator_dev *rdev,
+				     suspend_state_t state);
 static int regulator_set_voltage_rdev(struct regulator_dev *rdev,
 				      int min_uV, int max_uV,
 				      suspend_state_t state);
@@ -3126,6 +3128,187 @@ static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
 	return ret;
 }
 
+static int regulator_get_optimal_voltage(struct regulator_dev *rdev)
+{
+	struct coupling_desc *c_desc = &rdev->coupling_desc;
+	struct regulator_dev **c_rdevs = c_desc->coupled_rdevs;
+	int max_spread = rdev->constraints->max_spread;
+	int n_coupled = c_desc->n_coupled;
+	int desired_min_uV, desired_max_uV, min_current_uV = INT_MAX;
+	int max_current_uV = 0, highest_min_uV = 0, target_uV, possible_uV;
+	int i, ret;
+
+	/* If consumers don't provide any demands, set voltage to min_uV */
+	desired_min_uV = rdev->constraints->min_uV;
+	desired_max_uV = rdev->constraints->max_uV;
+	ret = regulator_check_consumers(rdev,
+					&desired_min_uV,
+					&desired_max_uV, PM_SUSPEND_ON);
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * If there are no coupled regulators, simply set the voltage demanded
+	 * by consumers.
+	 */
+	if (n_coupled == 1) {
+		ret = desired_min_uV;
+		goto out;
+	}
+
+	/* Find highest min desired voltage */
+	for (i = 0; i < n_coupled; i++) {
+		int tmp_min = 0;
+		int tmp_max = INT_MAX;
+
+		if (!_regulator_is_enabled(c_rdevs[i]))
+			continue;
+
+		ret = regulator_check_consumers(c_rdevs[i],
+						&tmp_min,
+						&tmp_max, PM_SUSPEND_ON);
+		if (ret < 0)
+			goto out;
+
+		if (tmp_min > highest_min_uV)
+			highest_min_uV = tmp_min;
+	}
+
+	/*
+	 * Let target_uV be equal to the desired one if possible.
+	 * If not, set it to minimum voltage, allowed by other coupled
+	 * regulators.
+	 */
+	target_uV = max(desired_min_uV,  highest_min_uV - max_spread);
+
+	/*
+	 * Find min and max voltages, which currently aren't
+	 * violating max_spread
+	 */
+	for (i = 0; i < n_coupled; i++) {
+		int tmp_act;
+
+		/*
+		 * Don't check the regulator, which is about
+		 * to change voltage
+		 */
+		if (c_rdevs[i] == rdev)
+			continue;
+		if (!_regulator_is_enabled(c_rdevs[i]))
+			continue;
+
+		tmp_act = _regulator_get_voltage(c_rdevs[i]);
+		if (tmp_act < 0) {
+			ret = tmp_act;
+			goto out;
+		}
+
+		if (tmp_act < min_current_uV)
+			min_current_uV = tmp_act;
+
+		if (tmp_act > max_current_uV)
+			max_current_uV = tmp_act;
+	}
+
+	/* There aren't any other regulators enabled */
+	if (max_current_uV == 0) {
+		possible_uV = target_uV;
+	} else {
+		/*
+		 * Correct target voltage, so as it currently isn't
+		 * violating max_spread
+		 */
+		possible_uV = max(target_uV, max_current_uV - max_spread);
+		possible_uV = min(possible_uV, min_current_uV + max_spread);
+	}
+
+	if (possible_uV > desired_max_uV) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = possible_uV;
+
+out:
+	return ret;
+}
+
+static int regulator_balance_voltage(struct regulator_dev *rdev,
+				     suspend_state_t state)
+{
+	struct regulator_dev **c_rdevs;
+	struct regulator_dev *best_rdev;
+	struct coupling_desc *c_desc = &rdev->coupling_desc;
+	int n_coupled;
+	int i, best_delta, best_uV, ret = 1;
+
+	c_rdevs = c_desc->coupled_rdevs;
+	n_coupled = c_desc->n_coupled;
+
+	/*
+	 * if system is in a state other than PM_SUSPEND_ON, don't check
+	 * other coupled regulators
+	 */
+	if (state != PM_SUSPEND_ON)
+		n_coupled = 1;
+
+	/*
+	 * Find the best possible voltage change on each loop. Leave the loop
+	 * if there isn't any possible change.
+	 */
+	while (1) {
+		best_delta = 0;
+		best_uV = 0;
+		best_rdev = NULL;
+
+		/*
+		 * Find highest difference between optimal voltage
+		 * and current voltage.
+		 */
+		for (i = 0; i < n_coupled; i++) {
+			/*
+			 * optimal_uV is the best voltage that can be set for
+			 * i-th regulator@the moment without violating
+			 * max_spread constraint in order to balance
+			 * the coupled voltages.
+			 */
+			int optimal_uV, current_uV;
+
+			optimal_uV = regulator_get_optimal_voltage(c_rdevs[i]);
+			if (optimal_uV < 0) {
+				ret = optimal_uV;
+				goto out;
+			}
+
+			current_uV = _regulator_get_voltage(c_rdevs[i]);
+			if (current_uV < 0) {
+				ret = optimal_uV;
+				goto out;
+			}
+
+			if (abs(best_delta) < abs(optimal_uV - current_uV)) {
+				best_delta = optimal_uV - current_uV;
+				best_rdev = c_rdevs[i];
+				best_uV = optimal_uV;
+			}
+		}
+
+		/* Nothing to change, return successfully */
+		if (!best_rdev) {
+			ret = 0;
+			goto out;
+		}
+
+		ret = regulator_set_voltage_rdev(best_rdev, best_uV,
+						 best_uV, state);
+
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
 /**
  * regulator_set_voltage - set regulator output voltage
  * @regulator: regulator source
-- 
2.7.4

^ permalink raw reply related

* [PATCH 5/7] regulator: core: Lock dependent regulators
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

Implementing coupled regulators adds a new dependency between
regulators. Therefore, the current locking model should be changed.
Coupled regulators should be locked with regulator's supplies at the
same time.

Add new function regulator_lock_dependent(), which locks all regulators
related with the one, that is being changed.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 75 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 52 insertions(+), 23 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 0b366c5..7c57268 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -201,38 +201,67 @@ static void regulator_unlock(struct regulator_dev *rdev)
 	}
 }
 
-/**
- * regulator_lock_supply - lock a regulator and its supplies
- * @rdev:         regulator source
- */
-static void regulator_lock_supply(struct regulator_dev *rdev)
+static int regulator_lock_recursive(struct regulator_dev *rdev,
+				    unsigned int subclass)
 {
+	struct regulator_dev *c_rdev;
 	int i;
 
-	for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
-		regulator_lock_nested(rdev, i);
+	for (i = 0; i < rdev->coupling_desc.n_coupled; i++) {
+		c_rdev = rdev->coupling_desc.coupled_rdevs[i];
+
+		if (!c_rdev)
+			continue;
+
+		regulator_lock_nested(c_rdev, subclass++);
+
+		if (c_rdev->supply)
+			subclass =
+				regulator_lock_recursive(c_rdev->supply->rdev,
+							 subclass);
+	}
+
+	return subclass;
 }
 
 /**
- * regulator_unlock_supply - unlock a regulator and its supplies
- * @rdev:         regulator source
+ * regulator_unlock_dependent - unlock regulator's suppliers and coupled
+ *				regulators
+ * @rdev:			regulator source
+ *
+ * Unlock all regulators related with rdev by coupling or suppling.
  */
-static void regulator_unlock_supply(struct regulator_dev *rdev)
+static void regulator_unlock_dependent(struct regulator_dev *rdev)
 {
-	struct regulator *supply;
+	struct regulator_dev *c_rdev;
+	int i;
 
-	while (1) {
-		regulator_unlock(rdev);
-		supply = rdev->supply;
+	for (i = 0; i < rdev->coupling_desc.n_coupled; i++) {
+		c_rdev = rdev->coupling_desc.coupled_rdevs[i];
 
-		if (!rdev->supply)
-			return;
+		if (!c_rdev)
+			continue;
+
+		regulator_unlock(c_rdev);
 
-		rdev = supply->rdev;
+		if (c_rdev->supply)
+			regulator_unlock_dependent(c_rdev->supply->rdev);
 	}
 }
 
 /**
+ * regulator_lock_dependent - lock regulator's suppliers and coupled regulators
+ * @rdev:			regulator source
+ *
+ * This function as a wrapper on regulator_lock_recursive(), which locks
+ * all regulators related with rdev by coupling or suppling.
+ */
+static inline void regulator_lock_dependent(struct regulator_dev *rdev)
+{
+	regulator_lock_recursive(rdev, 0);
+}
+
+/**
  * of_get_regulator - get a regulator device node based on supply name
  * @dev: Device pointer for the consumer (of regulator) device
  * @supply: regulator supply name
@@ -3332,12 +3361,12 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
 	int ret = 0;
 
 	pr_err("%s: %d\n", __func__, __LINE__);
-	regulator_lock_supply(regulator->rdev);
+	regulator_lock_dependent(regulator->rdev);
 
 	ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
 					     PM_SUSPEND_ON);
 
-	regulator_unlock_supply(regulator->rdev);
+	regulator_unlock_dependent(regulator->rdev);
 
 	return ret;
 }
@@ -3415,12 +3444,12 @@ int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
 	if (regulator_check_states(state) || state == PM_SUSPEND_ON)
 		return -EINVAL;
 
-	regulator_lock_supply(regulator->rdev);
+	regulator_lock_dependent(regulator->rdev);
 
 	ret = _regulator_set_suspend_voltage(regulator, min_uV,
 					     max_uV, state);
 
-	regulator_unlock_supply(regulator->rdev);
+	regulator_unlock_dependent(regulator->rdev);
 
 	return ret;
 }
@@ -3612,11 +3641,11 @@ int regulator_get_voltage(struct regulator *regulator)
 {
 	int ret;
 
-	regulator_lock_supply(regulator->rdev);
+	regulator_lock_dependent(regulator->rdev);
 
 	ret = _regulator_get_voltage(regulator->rdev);
 
-	regulator_unlock_supply(regulator->rdev);
+	regulator_unlock_dependent(regulator->rdev);
 
 	return ret;
 }
-- 
2.7.4

^ permalink raw reply related

* [PATCH 6/7] regulator: core: Lock dependent regulators on regulator_enable()
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

Since regulator_enable() might now call regulator_balance_voltage(),
it should also lock its coupled regulators and suppliers.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 7c57268..2a7ffb7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2305,9 +2305,9 @@ int regulator_enable(struct regulator *regulator)
 			return ret;
 	}
 
-	regulator_lock(rdev);
+	regulator_lock_dependent(rdev);
 	ret = _regulator_enable(rdev);
-	regulator_unlock(rdev);
+	regulator_unlock_dependent(rdev);
 
 	if (ret != 0 && rdev->supply)
 		regulator_disable(rdev->supply);
@@ -2415,9 +2415,9 @@ int regulator_disable(struct regulator *regulator)
 	if (regulator->always_on)
 		return 0;
 
-	regulator_lock(rdev);
+	regulator_lock_dependent(rdev);
 	ret = _regulator_disable(rdev);
-	regulator_unlock(rdev);
+	regulator_unlock_dependent(rdev);
 
 	if (ret == 0 && rdev->supply)
 		regulator_disable(rdev->supply);
@@ -2467,10 +2467,10 @@ int regulator_force_disable(struct regulator *regulator)
 	struct regulator_dev *rdev = regulator->rdev;
 	int ret;
 
-	regulator_lock(rdev);
+	regulator_lock_dependent(rdev);
 	regulator->uA_load = 0;
 	ret = _regulator_force_disable(regulator->rdev);
-	regulator_unlock(rdev);
+	regulator_unlock_dependent(rdev);
 
 	if (rdev->supply)
 		while (rdev->open_count--)
-- 
2.7.4

^ permalink raw reply related

* [PATCH 7/7] regulator: core: Enable voltage balancing
From: Maciej Purski @ 2018-06-04 13:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-1-git-send-email-m.purski@samsung.com>

Call regulator_balance_voltage() instead of set_voltage_rdev()
in set_voltage_unlocked() and in enabling and disabling functions,
but only if the regulator is coupled.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/regulator/core.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2a7ffb7..2dd1f99 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2296,6 +2296,11 @@ int regulator_enable(struct regulator *regulator)
 	int ret = 0;
 
 	pr_err("%s: %d\n", __func__, __LINE__);
+	if (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled) {
+		rdev_err(rdev, "not all coupled regulators registered\n");
+		return -EPERM;
+	}
+
 	if (regulator->always_on)
 		return 0;
 
@@ -2307,6 +2312,9 @@ int regulator_enable(struct regulator *regulator)
 
 	regulator_lock_dependent(rdev);
 	ret = _regulator_enable(rdev);
+	/* balance only if there are regulators coupled */
+	if (rdev->coupling_desc.n_coupled > 1)
+		regulator_balance_voltage(rdev, PM_SUSPEND_ON);
 	regulator_unlock_dependent(rdev);
 
 	if (ret != 0 && rdev->supply)
@@ -2417,6 +2425,8 @@ int regulator_disable(struct regulator *regulator)
 
 	regulator_lock_dependent(rdev);
 	ret = _regulator_disable(rdev);
+	if (rdev->coupling_desc.n_coupled > 1)
+		regulator_balance_voltage(rdev, PM_SUSPEND_ON);
 	regulator_unlock_dependent(rdev);
 
 	if (ret == 0 && rdev->supply)
@@ -2470,6 +2480,8 @@ int regulator_force_disable(struct regulator *regulator)
 	regulator_lock_dependent(rdev);
 	regulator->uA_load = 0;
 	ret = _regulator_force_disable(regulator->rdev);
+	if (rdev->coupling_desc.n_coupled > 1)
+		regulator_balance_voltage(rdev, PM_SUSPEND_ON);
 	regulator_unlock_dependent(rdev);
 
 	if (rdev->supply)
@@ -3031,7 +3043,16 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	int old_min_uV, old_max_uV;
 	int current_uV;
 
+<<<<<<< HEAD
 	pr_err("%s: %d\n", __func__, __LINE__);
+=======
+	if (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled) {
+		rdev_err(rdev, "not all coupled regulators registered\n");
+		ret = -EPERM;
+		goto out;
+	}
+
+>>>>>>> fcbf6fa... regulator: core: Enable voltage balancing
 	/* If we're setting the same range as last time the change
 	 * should be a noop (some cpufreq implementations use the same
 	 * voltage for multiple frequencies, for example).
@@ -3074,7 +3095,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	if (ret < 0)
 		goto out2;
 
-	ret = regulator_set_voltage_rdev(rdev, min_uV, max_uV, state);
+	/* for not coupled regulators this will just set the voltage */
+	ret = regulator_balance_voltage(rdev, state);
 	if (ret < 0)
 		goto out2;
 
-- 
2.7.4

^ permalink raw reply related

* [GIT PULL] EDAC pile for 4.18
From: Borislav Petkov @ 2018-06-04 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

please pull the current pile of fixes to the EDAC tree.

There's a merge commit in there with an immutable branch from
the socfpga's tree as changes there are touching the same
socfpga_stratix10.dtsi file, patches in my tree are touching so I
thought this was the best way to avoid merge conflicts. Please let me
know if this way is wrong.

And that's why you see those unrelated changes in the list below. So
depending on the pull order, you'll either get them through my tree or
through the arm-soc tree.

Btw, I'm not aware of any order those merges are *required* to happen so
let me CC the relevant parties in case order is important after all.

Thanks!

---
The following changes since commit 6d08b06e67cd117f6992c46611dfb4ce267cd71e:

  Linux 4.17-rc2 (2018-04-22 19:20:09 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git tags/edac_for_4.18

for you to fetch changes up to eaa3a1d46cfdbf1af50311e7a22f5d38c0418b56:

  EDAC, ghes: Make platform-based whitelisting x86-only (2018-05-21 12:18:57 +0200)

----------------------------------------------------------------
* Stratix10 SDRAM support to altera_edac (Thor Thayer)

* the usual misc fixes all over the place

----------------------------------------------------------------
Alan Tull (1):
      arm64: dts: stratix10: enable i2c, add i2c periperals

Alexandru Gagniuc (1):
      EDAC, ghes: Remove unused argument to ghes_edac_report_mem_error()

Bartosz Golaszewski (1):
      ARM: dts: consistently use 'atmel' as at24 manufacturer in cyclone5

Borislav Petkov (4):
      ghes, EDAC: Fix ghes_edac registration
      Merge tag 'socfpga_updates_for_v4.18_part2' into edac-for-4.18
      EDAC, ghes: Use BIT() macro
      EDAC, ghes: Make platform-based whitelisting x86-only

Colin Ian King (1):
      EDAC, i7core: Fix spelling mistake: "redundacy" -> "redundancy"

Dinh Nguyen (1):
      arm64: dts: stratix10: use clock bindings for the Stratix10 platform

Graham Moore (1):
      arm64: dts: stratix10: Add PL330 DMAC to Stratix10 dts

Ooi, Joyce (1):
      arm64: dts: stratix10: Change pad skew values for EMAC0 PHY driver

Randy Dunlap (1):
      EDAC, skx: Fix skx_edac build error when ACPI_NFIT=m

Sughosh Ganu (1):
      EDAC, ghes: Add a null pointer check in ghes_edac_unregister()

Thor Thayer (6):
      arm64: dts: stratix10: add sdram ecc
      Documentation: dt: socfpga: Add Stratix10 ECC Manager binding
      EDAC, altera: Add support for Stratix10 SDRAM EDAC
      Documentation: dt: edac: Move Altera SOCFPGA EDAC file
      EDAC, altera: Handle SDRAM Uncorrectable Errors on Stratix10
      EDAC, altera: Fix ARM64 build warning

Toshi Kani (1):
      EDAC, ghes: Add DDR4 and NVDIMM memory types

 .../{arm/altera => edac}/socfpga-eccmgr.txt        |  35 ++
 arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts |   6 +-
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  |  83 +++-
 .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  44 +-
 drivers/acpi/apei/ghes.c                           |  16 +-
 drivers/edac/Kconfig                               |   3 +-
 drivers/edac/altera_edac.c                         | 504 ++++++++++++++++++++-
 drivers/edac/altera_edac.h                         | 132 +++++-
 drivers/edac/ghes_edac.c                           |  55 ++-
 drivers/edac/i7core_edac.c                         |   2 +-
 include/acpi/ghes.h                                |   7 +-
 11 files changed, 817 insertions(+), 70 deletions(-)
 rename Documentation/devicetree/bindings/{arm/altera => edac}/socfpga-eccmgr.txt (87%)

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imend?rffer, Jane Smithard, Graham Norton, HRB 21284 (AG N?rnberg)
-- 

^ permalink raw reply

* [PATCH v3] of: platform: stop accessing invalid dev in of_platform_device_destroy
From: Srinivas Kandagatla @ 2018-06-04 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

Immediately after the platform_device_unregister() the device will be
cleaned up. Accessing the freed pointer immediately after that will
crash the system.

Found this bug when kernel is built with CONFIG_PAGE_POISONING and testing
loading/unloading audio drivers in a loop on Qcom platforms.

Fix this by moving of_node_clear_flag() just before the unregister calls.

Below is the crash trace:

Unable to handle kernel paging request at virtual address 6b6b6b6b6b6c03
Mem abort info:
  ESR = 0x96000021
  Exception class = DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x00000021
  CM = 0, WnR = 0
[006b6b6b6b6b6c03] address between user and kernel address ranges
Internal error: Oops: 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 1784 Comm: sh Tainted: G        W         4.17.0-rc7-02230-ge3a63a7ef641-dirty #204
Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO)
pc : clear_bit+0x18/0x2c
lr : of_platform_device_destroy+0x64/0xb8
sp : ffff00000c9c3930
x29: ffff00000c9c3930 x28: ffff80003d39b200
x27: ffff000008bb1000 x26: 0000000000000040
x25: 0000000000000124 x24: ffff80003a9a3080
x23: 0000000000000060 x22: ffff00000939f518
x21: ffff80003aa79e98 x20: ffff80003aa3dae0
x19: ffff80003aa3c890 x18: ffff800009feb794
x17: 0000000000000000 x16: 0000000000000000
x15: ffff800009feb790 x14: 0000000000000000
x13: ffff80003a058778 x12: ffff80003a058728
x11: ffff80003a058750 x10: 0000000000000000
x9 : 0000000000000006 x8 : ffff80003a825988
x7 : bbbbbbbbbbbbbbbb x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000008 x2 : 0000000000000001
x1 : 6b6b6b6b6b6b6c03 x0 : 0000000000000000
Process sh (pid: 1784, stack limit = 0x        (ptrval))
Call trace:
 clear_bit+0x18/0x2c
 q6afe_remove+0x20/0x38
 apr_device_remove+0x30/0x70
 device_release_driver_internal+0x170/0x208
 device_release_driver+0x14/0x20
 bus_remove_device+0xcc/0x150
 device_del+0x10c/0x310
 device_unregister+0x1c/0x70
 apr_remove_device+0xc/0x18
 device_for_each_child+0x50/0x80
 apr_remove+0x18/0x20
 rpmsg_dev_remove+0x38/0x68
 device_release_driver_internal+0x170/0x208
 device_release_driver+0x14/0x20
 bus_remove_device+0xcc/0x150
 device_del+0x10c/0x310
 device_unregister+0x1c/0x70
 qcom_smd_remove_device+0xc/0x18
 device_for_each_child+0x50/0x80
 qcom_smd_unregister_edge+0x3c/0x70
 smd_subdev_remove+0x18/0x28
 rproc_stop+0x48/0xd8
 rproc_shutdown+0x60/0xe8
 state_store+0xbc/0xf8
 dev_attr_store+0x18/0x28
 sysfs_kf_write+0x3c/0x50
 kernfs_fop_write+0x118/0x1e0
 __vfs_write+0x18/0x110
 vfs_write+0xa4/0x1a8
 ksys_write+0x48/0xb0
 sys_write+0xc/0x18
 el0_svc_naked+0x30/0x34
Code: d2800022 8b400c21 f9800031 9ac32043 (c85f7c22)
---[ end trace 32020935775616a2 ]---

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
Changes since v2:
 Move the calls to of_node_clear_flag just before unregister,
 suggested by Rob.

 drivers/of/platform.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c00d81dfac0b..9c91f97ffbe1 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -537,6 +537,9 @@ int of_platform_device_destroy(struct device *dev, void *data)
 	if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS))
 		device_for_each_child(dev, NULL, of_platform_device_destroy);
 
+	of_node_clear_flag(dev->of_node, OF_POPULATED);
+	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
+
 	if (dev->bus == &platform_bus_type)
 		platform_device_unregister(to_platform_device(dev));
 #ifdef CONFIG_ARM_AMBA
@@ -544,8 +547,6 @@ int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_node_clear_flag(dev->of_node, OF_POPULATED);
-	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_platform_device_destroy);
-- 
2.16.2

^ permalink raw reply related

* [PATCH 1/3] rtc: ftrtc010: switch to devm_rtc_allocate_device
From: Alexandre Belloni @ 2018-06-04 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

Switch to devm_rtc_allocate_device/rtc_register_device. This allow or
further improvement and simplifies ftrtc010_rtc_remove().

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ftrtc010.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index af8d6beae20c..165d0b62db00 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -166,14 +166,18 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
 	if (!rtc->rtc_base)
 		return -ENOMEM;
 
+	rtc->rtc_dev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(rtc->rtc_dev))
+		return PTR_ERR(rtc->rtc_dev);
+
+	rtc->rtc_dev->ops = &ftrtc010_rtc_ops;
+
 	ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt,
 			       IRQF_SHARED, pdev->name, dev);
 	if (unlikely(ret))
 		return ret;
 
-	rtc->rtc_dev = rtc_device_register(pdev->name, dev,
-					   &ftrtc010_rtc_ops, THIS_MODULE);
-	return PTR_ERR_OR_ZERO(rtc->rtc_dev);
+	return rtc_register_device(rtc->rtc_dev);
 }
 
 static int ftrtc010_rtc_remove(struct platform_device *pdev)
@@ -184,7 +188,6 @@ static int ftrtc010_rtc_remove(struct platform_device *pdev)
 		clk_disable_unprepare(rtc->extclk);
 	if (!IS_ERR(rtc->pclk))
 		clk_disable_unprepare(rtc->pclk);
-	rtc_device_unregister(rtc->rtc_dev);
 
 	return 0;
 }
-- 
2.17.1

^ permalink raw reply related

* [PATCH 2/3] rtc: ftrtc010: handle dates after 2106
From: Alexandre Belloni @ 2018-06-04 14:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604141528.15635-1-alexandre.belloni@bootlin.com>

Use correct types for offset and time and use
rtc_time64_to_tm/rtc_tm_to_time64 to handle dates after 2106 properly.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ftrtc010.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index 165d0b62db00..2cdc78ffeb17 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -73,8 +73,8 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
 
-	unsigned int  days, hour, min, sec;
-	unsigned long offset, time;
+	u32 days, hour, min, sec, offset;
+	timeu64_t time;
 
 	sec  = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
 	min  = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
@@ -84,7 +84,7 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
 
 	time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
 
-	rtc_time_to_tm(time, tm);
+	rtc_time64_to_tm(time, tm);
 
 	return 0;
 }
@@ -92,13 +92,13 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int sec, min, hour, day;
-	unsigned long offset, time;
+	u32 sec, min, hour, day, offset;
+	timeu64_t time;
 
 	if (tm->tm_year >= 2148)	/* EPOCH Year + 179 */
 		return -EINVAL;
 
-	rtc_tm_to_time(tm, &time);
+	time = rtc_tm_to_time64(tm);
 
 	sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
 	min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
-- 
2.17.1

^ permalink raw reply related

* [PATCH 3/3] rtc: ftrtc010: let the core handle range
From: Alexandre Belloni @ 2018-06-04 14:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604141528.15635-1-alexandre.belloni@bootlin.com>

The current range handling is highly suspicious. Anyway, let the core
handle it.
The RTC has a 32 bit counter on top of days + hh:mm:ss registers.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ftrtc010.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index 2cdc78ffeb17..61f798c6101f 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -95,9 +95,6 @@ static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	u32 sec, min, hour, day, offset;
 	timeu64_t time;
 
-	if (tm->tm_year >= 2148)	/* EPOCH Year + 179 */
-		return -EINVAL;
-
 	time = rtc_tm_to_time64(tm);
 
 	sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
@@ -120,6 +117,7 @@ static const struct rtc_class_ops ftrtc010_rtc_ops = {
 
 static int ftrtc010_rtc_probe(struct platform_device *pdev)
 {
+	u32 days, hour, min, sec;
 	struct ftrtc010_rtc *rtc;
 	struct device *dev = &pdev->dev;
 	struct resource *res;
@@ -172,6 +170,15 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
 
 	rtc->rtc_dev->ops = &ftrtc010_rtc_ops;
 
+	sec  = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
+	min  = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
+	hour = readl(rtc->rtc_base + FTRTC010_RTC_HOUR);
+	days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
+
+	rtc->rtc_dev->range_min = (u64)days * 86400 + hour * 3600 +
+				  min * 60 + sec;
+	rtc->rtc_dev->range_max = U32_MAX + rtc->rtc_dev->range_min;
+
 	ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt,
 			       IRQF_SHARED, pdev->name, dev);
 	if (unlikely(ret))
-- 
2.17.1

^ permalink raw reply related

* [PATCH 1/6] PCI: iproc: Update iProc PCI binding for INTx support
From: Rob Herring @ 2018-06-04 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527631130-20045-2-git-send-email-ray.jui@broadcom.com>

+Arnd

On Tue, May 29, 2018 at 4:58 PM, Ray Jui <ray.jui@broadcom.com> wrote:
> Update the iProc PCIe binding document for better modeling of the legacy
> interrupt (INTx) support
>
> Signed-off-by: Ray Jui <ray.jui@broadcom.com>
> ---
>  .../devicetree/bindings/pci/brcm,iproc-pcie.txt    | 31 +++++++++++++++++-----
>  1 file changed, 24 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
> index b8e48b4..7ea24dc 100644
> --- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
> @@ -13,9 +13,6 @@ controller, used in Stingray
>    PAXB-based root complex is used for external endpoint devices. PAXC-based
>  root complex is connected to emulated endpoint devices internal to the ASIC
>  - reg: base address and length of the PCIe controller I/O register space
> -- #interrupt-cells: set to <1>
> -- interrupt-map-mask and interrupt-map, standard PCI properties to define the
> -  mapping of the PCIe interface to interrupt numbers
>  - linux,pci-domain: PCI domain ID. Should be unique for each host controller
>  - bus-range: PCI bus numbers covered
>  - #address-cells: set to <3>
> @@ -41,6 +38,16 @@ Required:
>  - brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal
>  address used by the iProc PCIe core (not the PCIe address)
>
> +Legacy interrupt (INTx) support (optional):
> +
> +Note INTx is for PAXB only.
> +
> +- interrupt-controller: claims itself as an interrupt controller for INTx
> +- #interrupt-cells: set to <1>
> +- interrupt-map-mask and interrupt-map, standard PCI properties to define
> +the mapping of the PCIe interface to interrupt numbers
> +- interrupts: interrupt line wired to the generic GIC for INTx support
> +
>  MSI support (optional):
>
>  For older platforms without MSI integrated in the GIC, iProc PCIe core provides
> @@ -77,9 +84,14 @@ Example:
>                 compatible = "brcm,iproc-pcie";
>                 reg = <0x18012000 0x1000>;
>
> +               interrupt-controller;
>                 #interrupt-cells = <1>;
> -               interrupt-map-mask = <0 0 0 0>;
> -               interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
> +               interrupt-map-mask = <0 0 0 7>;
> +               interrupt-map = <0 0 0 1 &pcie0 1>,

Are you sure this works? The irq parsing code will ignore
interrupt-map if interrupt-controller is found. In other words, you
should have one or the other, but not both.

Maybe it happens to work because "pcie0" is this node and your irq
numbers are the same.

Arnd, any thoughts on this?

> +                               <0 0 0 2 &pcie0 2>,
> +                               <0 0 0 3 &pcie0 3>,
> +                               <0 0 0 4 &pcie0 4>;
> +               interrupts = <GIC_SPI 100 IRQ_TYPE_NONE>;
>
>                 linux,pci-domain = <0>;
>
> @@ -115,9 +127,14 @@ Example:
>                 compatible = "brcm,iproc-pcie";
>                 reg = <0x18013000 0x1000>;
>
> +               interrupt-controller;
>                 #interrupt-cells = <1>;
> -               interrupt-map-mask = <0 0 0 0>;
> -               interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
> +               interrupt-map-mask = <0 0 0 7>;
> +               interrupt-map = <0 0 0 1 &pcie1 1>,
> +                               <0 0 0 2 &pcie1 2>,
> +                               <0 0 0 3 &pcie1 3>,
> +                               <0 0 0 4 &pcie1 4>;
> +               interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
>
>                 linux,pci-domain = <1>;
>
> --
> 2.1.4
>

^ permalink raw reply

* [RFC PATCH 7/8] dts: coresight: Define new bindings for direction of data flow
From: Suzuki K Poulose @ 2018-06-04 14:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180601203928.GD9838@xps15>

On 06/01/2018 09:39 PM, Mathieu Poirier wrote:
> On Fri, Jun 01, 2018 at 02:16:06PM +0100, Suzuki K Poulose wrote:
>> So far we have relied on an undocumented property "slave-mode",
>> to indicate if the given port is input or not. Since we are
>> redefining the coresight bindings, define new property for the
>> "direction" of data flow for a given connection endpoint in the
>> device.
>>
>> Each endpoint must define the following property.
>>
>>   - "direction" : 0 => Port is input
>> 		 1 => Port is output
>>
>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>>   drivers/hwtracing/coresight/of_coresight.c | 20 ++++++++++++++++----
> 
> You haven't documented the binding in bindings/arm/coresight.txt the same way
> you did with "coresight,hwid".  I'm guessing you simply forgot to do a "git add"
> on the file when preparing the patchset.
> 
>>   1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
>> index 99d7a9c..63c1668 100644
>> --- a/drivers/hwtracing/coresight/of_coresight.c
>> +++ b/drivers/hwtracing/coresight/of_coresight.c
>> @@ -52,7 +52,19 @@ of_coresight_get_endpoint_device(struct device_node *endpoint)
>>   			       endpoint, of_dev_node_match);
>>   }
>>   
>> -static void of_coresight_get_ports(const struct device_node *node,
>> +static bool of_coresight_ep_is_input(struct device *dev, struct device_node *ep_node)
> 
> I suggested of_coresight_endpoint_get_port_id() in my review of 6/8.  I'm good
> with either "ep" or "endpoint", as long as the names are consistent.

Yep, that's right. This is what I have for the documentation :

--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -103,9 +103,11 @@ with a specific direction of data flow, each 
connection must define the
  following properties to uniquely identify the connection details.

   * Direction of the data flow w.r.t the component :
-   Each input port must have the following property defined at the 
"endpoint"
+   Each hardware port must have the following property defined at the 
"endpoint"
     for the port.
-       "slave-mode"
+       "direction" - 32bit integer, whose values are defined as follows :
+               0 => the endpoint is an Input port
+               1 => the endpoint is an Output port.


and changes to the examples as well..


Cheers
Suzuki

^ permalink raw reply

* [PATCH 5/7] regulator: core: Lock dependent regulators
From: Lucas Stach @ 2018-06-04 14:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528120764-14316-6-git-send-email-m.purski@samsung.com>

Hi Maciej,

Am Montag, den 04.06.2018, 15:59 +0200 schrieb Maciej Purski:
> Implementing coupled regulators adds a new dependency between
> regulators. Therefore, the current locking model should be changed.
> Coupled regulators should be locked with regulator's supplies at the
> same time.
> 
> Add new function regulator_lock_dependent(), which locks all regulators
> related with the one, that is being changed.

Sort of high level comment, but this doesn't look right: With dependent
regulators you don't strictly lock the regulators in the direction of
the tree root, but also siblings at the same level. This is prone with
deadlocks, as you can't control the order of the regulator locks being
taken by different tasks. This really needs a ww_mutex to be
implemented in a robust way.

Regards,
Lucas

> Signed-off-by: Maciej Purski <m.purski@samsung.com>
> ---
> ?drivers/regulator/core.c | 75 +++++++++++++++++++++++++++++++++---------------
> ?1 file changed, 52 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 0b366c5..7c57268 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -201,38 +201,67 @@ static void regulator_unlock(struct regulator_dev *rdev)
> > ?	}
> ?}
> ?
> -/**
> - * regulator_lock_supply - lock a regulator and its supplies
> - * @rdev:?????????regulator source
> - */
> -static void regulator_lock_supply(struct regulator_dev *rdev)
> +static int regulator_lock_recursive(struct regulator_dev *rdev,
> > +				????unsigned int subclass)
> ?{
> > +	struct regulator_dev *c_rdev;
> > ?	int i;
> ?
> > -	for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
> > -		regulator_lock_nested(rdev, i);
> > +	for (i = 0; i < rdev->coupling_desc.n_coupled; i++) {
> > +		c_rdev = rdev->coupling_desc.coupled_rdevs[i];
> +
> > +		if (!c_rdev)
> > +			continue;
> +
> > +		regulator_lock_nested(c_rdev, subclass++);
> +
> > +		if (c_rdev->supply)
> > +			subclass =
> > +				regulator_lock_recursive(c_rdev->supply->rdev,
> > +							?subclass);
> > +	}
> +
> > +	return subclass;
> ?}
> ?
> ?/**
> - * regulator_unlock_supply - unlock a regulator and its supplies
> - * @rdev:?????????regulator source
> + * regulator_unlock_dependent - unlock regulator's suppliers and coupled
> > + *				regulators
> > + * @rdev:			regulator source
> + *
> + * Unlock all regulators related with rdev by coupling or suppling.
> ? */
> -static void regulator_unlock_supply(struct regulator_dev *rdev)
> +static void regulator_unlock_dependent(struct regulator_dev *rdev)
> ?{
> > -	struct regulator *supply;
> > +	struct regulator_dev *c_rdev;
> > +	int i;
> ?
> > -	while (1) {
> > -		regulator_unlock(rdev);
> > -		supply = rdev->supply;
> > +	for (i = 0; i < rdev->coupling_desc.n_coupled; i++) {
> > +		c_rdev = rdev->coupling_desc.coupled_rdevs[i];
> ?
> > -		if (!rdev->supply)
> > -			return;
> > +		if (!c_rdev)
> > +			continue;
> +
> > +		regulator_unlock(c_rdev);
> ?
> > -		rdev = supply->rdev;
> > +		if (c_rdev->supply)
> > +			regulator_unlock_dependent(c_rdev->supply->rdev);
> > ?	}
> ?}
> ?
> ?/**
> + * regulator_lock_dependent - lock regulator's suppliers and coupled regulators
> > + * @rdev:			regulator source
> + *
> + * This function as a wrapper on regulator_lock_recursive(), which locks
> + * all regulators related with rdev by coupling or suppling.
> + */
> +static inline void regulator_lock_dependent(struct regulator_dev *rdev)
> +{
> > +	regulator_lock_recursive(rdev, 0);
> +}
> +
> +/**
> ? * of_get_regulator - get a regulator device node based on supply name
> ? * @dev: Device pointer for the consumer (of regulator) device
> ? * @supply: regulator supply name
> @@ -3332,12 +3361,12 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
> > ?	int ret = 0;
> ?
> > ?	pr_err("%s: %d\n", __func__, __LINE__);
> > -	regulator_lock_supply(regulator->rdev);
> > +	regulator_lock_dependent(regulator->rdev);
> ?
> > ?	ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
> > ?					?????PM_SUSPEND_ON);
> ?
> > -	regulator_unlock_supply(regulator->rdev);
> > +	regulator_unlock_dependent(regulator->rdev);
> ?
> > ?	return ret;
> ?}
> @@ -3415,12 +3444,12 @@ int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
> > ?	if (regulator_check_states(state) || state == PM_SUSPEND_ON)
> > ?		return -EINVAL;
> ?
> > -	regulator_lock_supply(regulator->rdev);
> > +	regulator_lock_dependent(regulator->rdev);
> ?
> > ?	ret = _regulator_set_suspend_voltage(regulator, min_uV,
> > ?					?????max_uV, state);
> ?
> > -	regulator_unlock_supply(regulator->rdev);
> > +	regulator_unlock_dependent(regulator->rdev);
> ?
> > ?	return ret;
> ?}
> @@ -3612,11 +3641,11 @@ int regulator_get_voltage(struct regulator *regulator)
> ?{
> > ?	int ret;
> ?
> > -	regulator_lock_supply(regulator->rdev);
> > +	regulator_lock_dependent(regulator->rdev);
> ?
> > ?	ret = _regulator_get_voltage(regulator->rdev);
> ?
> > -	regulator_unlock_supply(regulator->rdev);
> > +	regulator_unlock_dependent(regulator->rdev);
> ?
> > ?	return ret;
> ?}

^ permalink raw reply

* [PATCH 2/3] arm64: dts: renesas: condor: specify EtherAVB PHY IRQ
From: Sergei Shtylyov @ 2018-06-04 14:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604103302.f5kx5fqhbl3ohfpi@verge.net.au>

On 06/04/2018 01:33 PM, Simon Horman wrote:

>> Specify EtherAVB PHY IRQ in the Condor board's device tree, now that
>> we have the GPIO support (previously phylib had to resort to polling).
>>
>> Based on the original (and large) patch by Vladimir Barinov.
>>
>> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>
>> ---
>>  arch/arm64/boot/dts/renesas/r8a77980-condor.dts |    2 ++
>>  1 file changed, 2 insertions(+)
>>
>> Index: renesas/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
>> ===================================================================
>> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
>> +++ renesas/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
>> @@ -59,6 +59,8 @@
>>  	phy0: ethernet-phy at 0 {
>>  		rxc-skew-ps = <1500>;
>>  		reg = <0>;
>> +		interrupt-parent = <&gpio1>;
>> +		interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
> 
> I don't see this documented. Perhaps I'm missing something obvious.

   Have you looked into the V3H PFC section for where in the GPSRs AVB_PHY_INT
is mapped?
   The Condor schematics doesn't explicitly list the GPIO for AVB_PHY_INT
because that signal is meant to be routed thru the MAC. Unfortunately, the
sh_eth/ravb drivers don't support the PHY interrupt (the phylib function,
phy_mac_interrupt() reporting the PHY interrupts routed thru MAC is clearly
inadequate as it wants the link state as an argument), so we have to resort
to the GPIO interrupts...

> Or you have some extra information or newer documentation?

   No.

> Also, given Olof Johansson's recent comments in ("Re: [GIT PULL] Renesas
> ARM64 Based SoC DT Updates for v4.18") please consider squashing this patch
> and the following one.

   Hm... note that the different Ether cores are involved in these 2 PHY IRQ
patches. If that's OK, I can merge the patches...

[...]

MBR< Sergei

^ permalink raw reply

* [PATCH v5 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: Rob Herring @ 2018-06-04 14:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <af7152133afd7bbf9ad207905ec4e8d5cbe4e718.1527901471.git.collinsd@codeaurora.org>

On Fri, Jun 01, 2018 at 06:34:05PM -0700, David Collins wrote:
> Introduce bindings for RPMh regulator devices found on some
> Qualcomm Technlogies, Inc. SoCs.  These devices allow a given
> processor within the SoC to make PMIC regulator requests which
> are aggregated within the RPMh hardware block along with requests
> from other processors in the SoC to determine the final PMIC
> regulator hardware state.
> 
> Signed-off-by: David Collins <collinsd@codeaurora.org>
> ---
>  .../bindings/regulator/qcom,rpmh-regulator.txt     | 160 +++++++++++++++++++++
>  .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 +++++
>  2 files changed, 196 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
>  create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v5 4/4] ARM: dts: imx: add missing compatible and clock properties for EPIT
From: kbuild test robot @ 2018-06-04 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604100035.19558-5-peron.clem@gmail.com>

Hi Colin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on shawnguo/for-next]
[also build test ERROR on v4.17 next-20180601]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Cl-ment-P-ron/Reintroduce-i-MX-EPIT-Timer/20180604-211036
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
config: arm-realview_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> Error: arch/arm/boot/dts/imx6sl.dtsi:661.19-20 syntax error
   FATAL ERROR: Unable to parse input tree

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 18007 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180604/87639177/attachment-0001.gz>

^ permalink raw reply

* [PATCH 1/5] arm64: topology: refactor reset_cpu_topology to add support for removing topology
From: Jeffrey Hugo @ 2018-06-04 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528108797-13743-2-git-send-email-sudeep.holla@arm.com>

On 6/4/2018 4:39 AM, Sudeep Holla wrote:
> Currently reset_cpu_topology clears all the CPU topology information
> and resets to default values. However we may need to just clear the
> information when we hotplig out the CPU. In preparation to add the

hotplug

> support the same, let's refactor reset_cpu_topology to clear out the
> information and reset them only if explicitly requested.
> 



-- 
Jeffrey Hugo
Qualcomm Datacenter Technologies as an affiliate of Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH v12 4/5] arm64: Implement page table free interfaces
From: Will Deacon @ 2018-06-04 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <98ef3cd0-a9a1-d5b5-f1a6-c0ab8b15ec6a@codeaurora.org>

On Mon, Jun 04, 2018 at 07:13:18PM +0530, Chintan Pandya wrote:
> On 6/4/2018 5:43 PM, Will Deacon wrote:
> >On Fri, Jun 01, 2018 at 06:09:17PM +0530, Chintan Pandya wrote:
> >>+		next = addr;
> >>+		end = addr + PUD_SIZE;
> >>+		do {
> >>+			pmd_free_pte_page(entry, next);
> >>+		} while (entry++, next += PMD_SIZE, next != end);
> >>+
> >>+		pud_clear(pudp);
> >>+		__flush_tlb_kernel_pgtable(addr);
> >>+		pmd_free(NULL, table);
> >>+	}
> >>+	return 1;
> >
> >So with these patches, we only ever return 1 from these helpers. It looks
> >like the same is true for x86, so how about we make them void and move the
> >calls inside the conditionals in lib/ioremap.c? Obviously, this would be a
> >separate patch on the end.
> 
> That sounds valid code churn to me. But since x86 discussion is not
> concluded yet, I would wait to share until that gets resolved. May be
> not in v13 but separate effort. Would that be okay to you ?

Yes, fine by me.

Will

^ permalink raw reply

* [PATCH 06/15] drm/sun4i: tcon: Add support for tcon-top
From: Jernej Škrabec @ 2018-06-04 15:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604115034.kuy35s4ajewapk4m@flea>

Dne ponedeljek, 04. junij 2018 ob 13:50:34 CEST je Maxime Ripard napisal(a):
> On Fri, Jun 01, 2018 at 09:19:43AM -0700, Chen-Yu Tsai wrote:
> > On Fri, Jun 1, 2018 at 8:29 AM, Maxime Ripard <maxime.ripard@bootlin.com> 
wrote:
> > > On Thu, May 31, 2018 at 07:54:08PM +0200, Jernej ?krabec wrote:
> > >> Dne ?etrtek, 31. maj 2018 ob 11:21:33 CEST je Maxime Ripard napisal(a):
> > >> > On Thu, May 24, 2018 at 03:01:09PM -0700, Chen-Yu Tsai wrote:
> > >> > > >> > > + if (tcon->quirks->needs_tcon_top) {
> > >> > > >> > > +         struct device_node *np;
> > >> > > >> > > +
> > >> > > >> > > +         np = of_parse_phandle(dev->of_node,
> > >> > > >> > > "allwinner,tcon-top",
> > >> > > >> > > 0);
> > >> > > >> > > +         if (np) {
> > >> > > >> > > +                 struct platform_device *pdev;
> > >> > > >> > > +
> > >> > > >> > > +                 pdev = of_find_device_by_node(np);
> > >> > > >> > > +                 if (pdev)
> > >> > > >> > > +                         tcon->tcon_top =
> > >> > > >> > > platform_get_drvdata(pdev);
> > >> > > >> > > +                 of_node_put(np);
> > >> > > >> > > +
> > >> > > >> > > +                 if (!tcon->tcon_top)
> > >> > > >> > > +                         return -EPROBE_DEFER;
> > >> > > >> > > +         }
> > >> > > >> > > + }
> > >> > > >> > > +
> > >> > > >> > 
> > >> > > >> > I might have missed it, but I've not seen the bindings
> > >> > > >> > additions for
> > >> > > >> > that property. This shouldn't really be done that way anyway,
> > >> > > >> > instead
> > >> > > >> > of using a direct phandle, you should be using the of-graph,
> > >> > > >> > with the
> > >> > > >> > TCON-top sitting where it belongs in the flow of data.
> > >> > > >> 
> > >> > > >> Just to answer to the first question, it did describe it in
> > >> > > >> "[PATCH
> > >> > > >> 07/15] dt- bindings: display: sun4i-drm: Add R40 HDMI pipeline".
> > >> > > >> 
> > >> > > >> As why I designed it that way - HW representation could be
> > >> > > >> described
> > >> > > >> that way> >>
> > >> > > >> 
> > >> > > >> (ASCII art makes sense when fixed width font is used to view 
it):
> > >> > > >>                             / LCD0/LVDS0
> > >> > > >>                 
> > >> > > >>                 / TCON-LCD0
> > >> > > >>                 
> > >> > > >>                 |           \ MIPI DSI
> > >> > > >> 
> > >> > > >> mixer0          |
> > >> > > >> 
> > >> > > >>        \        / TCON-LCD1 - LCD1/LVDS1
> > >> > > >>        
> > >> > > >>         TCON-TOP
> > >> > > >>        
> > >> > > >>        /        \ TCON-TV0 - TVE0/RGB
> > >> > > >> 
> > >> > > >> mixer1          |          \
> > >> > > >> 
> > >> > > >>                 |           TCON-TOP - HDMI
> > >> > > >>                 |          
> > >> > > >>                 |          /
> > >> > > >>                 
> > >> > > >>                 \ TCON-TV1 - TVE1/RGB
> > >> > > >> 
> > >> > > >> This is a bit simplified, since there is also TVE-TOP, which is
> > >> > > >> responsible
> > >> > > >> for sharing 4 DACs between both TVE encoders. You can have two
> > >> > > >> TV outs
> > >> > > >> (PAL/ NTSC) or TVE0 as TV out and TVE1 as RGB or vice versa. It
> > >> > > >> even
> > >> > > >> seems that you can arbitrarly choose which DAC is responsible
> > >> > > >> for
> > >> > > >> which signal, so there is a ton of possible end combinations,
> > >> > > >> but I'm
> > >> > > >> not 100% sure.
> > >> > > >> 
> > >> > > >> Even though I wrote TCON-TOP twice, this is same unit in HW. R40
> > >> > > >> manual
> > >> > > >> suggest more possibilities, although some of them seem wrong,
> > >> > > >> like RGB
> > >> > > >> feeding from LCD TCON. That is confirmed to be wrong when
> > >> > > >> checking BSP
> > >> > > >> code.
> > >> > > >> 
> > >> > > >> Additionally, TCON-TOP comes in the middle of TVE0 and LCD0,
> > >> > > >> TVE1 and
> > >> > > >> LCD1 for pin muxing, although I'm not sure why is that needed at
> > >> > > >> all,
> > >> > > >> since according to R40 datasheet, TVE0 and TVE1 pins are
> > >> > > >> dedicated and
> > >> > > >> not on PORT D and PORT H, respectively, as TCON-TOP
> > >> > > >> documentation
> > >> > > >> suggest. However, HSYNC and PSYNC lines might be shared between
> > >> > > >> TVE
> > >> > > >> (when it works in RGB mode) and LCD. But that is just my guess
> > >> > > >> since
> > >> > > >> I'm not really familiar with RGB and LCD interfaces.
> > >> > > >> 
> > >> > > >> I'm really not sure what would be the best representation in
> > >> > > >> OF-graph.
> > >> > > >> Can you suggest one?
> > >> > > > 
> > >> > > > Rob might disagree on this one, but I don't see anything wrong
> > >> > > > with
> > >> > > > having loops in the graph. If the TCON-TOP can be both the input
> > >> > > > and
> > >> > > > output of the TCONs, then so be it, and have it described that
> > >> > > > way in
> > >> > > > the graph.
> > >> > > > 
> > >> > > > The code is already able to filter out nodes that have already
> > >> > > > been
> > >> > > > added to the list of devices we need to wait for in the component
> > >> > > > framework, so that should work as well.
> > >> > > > 
> > >> > > > And we'd need to describe TVE-TOP as well, even though we don't
> > >> > > > have a
> > >> > > > driver for it yet. That will simplify the backward compatibility
> > >> > > > later
> > >> > > > on.
> > >> > > 
> > >> > > I'm getting the feeling that TCON-TOP / TVE-TOP is the glue layer
> > >> > > that
> > >> > > binds everything together, and provides signal routing, kind of
> > >> > > like
> > >> > > DE-TOP on A64. So the signal mux controls that were originally
> > >> > > found
> > >> > > in TCON0 and TVE0 were moved out.
> > >> > > 
> > >> > > The driver needs to know about that, but the graph about doesn't
> > >> > > make
> > >> > > much sense directly. Without looking at the manual, I understand it
> > >> > > to
> > >> > > likely be one mux between the mixers and TCONs, and one between the
> > >> > > TCON-TVs and HDMI. Would it make more sense to just have the graph
> > >> > > connections between the muxed components, and remove TCON-TOP from
> > >> > > it, like we had in the past? A phandle could be used to reference
> > >> > > the TCON-TOP for mux controls, in addition to the clocks and
> > >> > > resets.
> > >> > > 
> > >> > > For TVE, we would need something to represent each of the output
> > >> > > pins,
> > >> > > so the device tree can actually describe what kind of signal, be it
> > >> > > each component of RGB/YUV or composite video, is wanted on each
> > >> > > pin,
> > >> > > if any. This is also needed on the A20 for the Cubietruck, so we
> > >> > > can
> > >> > > describe which pins are tied to the VGA connector, and which one
> > >> > > does
> > >> > > R, G, or B.
> > >> > 
> > >> > I guess we'll see how the DT maintainers feel about this, but my
> > >> > impression is that the OF graph should model the flow of data between
> > >> > the devices. If there's a mux somewhere, then the data is definitely
> > >> > going through it, and as such it should be part of the graph.
> > >> 
> > >> I concur, but I spent few days thinking how to represent this sanely in
> > >> graph, but I didn't find any good solution. I'll represent here my
> > >> idea and please tell your opinion before I start implementing it.
> > >> 
> > >> First, let me be clear that mixer0 and mixer1 don't have same
> > >> capabilities
> > >> (different number of planes, mixer0 supports writeback, mixer1 does
> > >> not,
> > >> etc.). Thus, it does matter which mixer is connected to which
> > >> TCON/encoder.
> > >> mixer0 is meant to be connected to main display and mixer1 to
> > >> auxiliary. That obviously depends on end system.
> > >> 
> > >> So, TCON TOP has 3 muxes, which have to be represented in graph. Two of
> > >> them are for mixer/TCON relationship (each of them 1 input and 4
> > >> possible outputs) and one for TV TCON/HDMI pair selection (2 possible
> > >> inputs, 1 output).
> > >> 
> > >> According to current practice in sun4i-drm driver, graph has to have
> > >> port 0, representing input and port 1, representing output. This would
> > >> mean that graph looks something like that:
> > >> 
> > >> tcon_top: tcon-top at 1c70000 {
> > >> 
> > >>       compatible = "allwinner,sun8i-r40-tcon-top";
> > >>       ...
> > >>       ports {
> > >>       
> > >>               #address-cells = <1>;
> > >>               #size-cells = <0>;
> > >>               
> > >>               tcon_top_in: port at 0 {
> > >>               
> > >>                       #address-cells = <1>;
> > >>                       #size-cells = <0>;
> > >>                       reg = <0>;
> > >>                       
> > >>                       tcon_top_in_mixer0: endpoint at 0 {
> > >>                       
> > >>                               reg = <0>;
> > >>                               remote-endpoint = <&mixer0_out_tcon_top>;
> > >>                       
> > >>                       };
> > >>                       
> > >>                       tcon_top_in_mixer1: endpoint at 1 {
> > >>                       
> > >>                               reg = <1>;
> > >>                               remote-endpoint = <&mixer1_out_tcon_top>;
> > >>                       
> > >>                       };
> > >>                       
> > >>                       tcon_top_in_tcon_tv: endpoint at 2 {
> > >>                       
> > >>                               reg = <2>;
> > >>                               // here is HDMI input connection, part of
> > >>                               board DTS
> > >>                               remote-endpoint = <board specific phandle
> > >>                               to TV TCON output>;
> > >>                       
> > >>                       };
> > >>               
> > >>               };
> > >>               
> > >>               tcon_top_out: port at 1 {
> > >>               
> > >>                       #address-cells = <1>;
> > >>                       #size-cells = <0>;
> > >>                       reg = <1>;
> > >>                       
> > >>                       tcon_top_out_tcon0: endpoint at 0 {
> > >>                       
> > >>                               reg = <0>;
> > >>                               // here is mixer0 output connection, part
> > >>                               of board DTS
> > >>                               remote-endpoint = <board specific phandle
> > >>                               to TCON>;
> > >>                       
> > >>                       };
> > >>                       
> > >>                       tcon_top_out_tcon1: endpoint at 1 {
> > >>                       
> > >>                               reg = <1>;
> > >>                               // here is mixer1 output connection, part
> > >>                               of board DTS
> > >>                               remote-endpoint = <board specific phandle
> > >>                               to TCON>;
> > >>                       
> > >>                       };
> > >>                       
> > >>                       tcon_top_out_hdmi: endpoint at 2 {
> > >>                       
> > >>                               reg = <2>;
> > >>                               remote-endpoint = <&hdmi_in_tcon_top>;
> > >>                       
> > >>                       };
> > >>               
> > >>               };
> > >>       
> > >>       };
> > >> 
> > >> };
> > > 
> > > IIRC, each port is supposed to be one route for the data, so we would
> > > have multiple ports, one for the mixers in input and for the tcon in
> > > output, and one for the TCON in input and for the HDMI/TV in
> > > output. Rob might correct me here.

Ok, that seems more clean approach. I'll have to extend graph traversing 
algorithm in sun4i_drv.c, but that's no problem.

Just to be clear, you have in mind 3 pairs of ports (0/1 for mixer0 mux, 2/3 
for mixer1 and 4/5 for HDMI input), right? That way each mux is represented 
with one pair of ports, even numbered for input and odd numbered for output.

> > > 
> > >> tcon_tv0: lcd-controller at 1c73000 {
> > >> 
> > >>       compatible = "allwinner,sun8i-r40-tcon-tv-0";
> > >>       ...
> > >>       ports {
> > >>       
> > >>               #address-cells = <1>;
> > >>               #size-cells = <0>;
> > >>               
> > >>               tcon_tv0_in: port at 0 {
> > >>               
> > >>                       reg = <0>;
> > >>                       
> > >>                       tcon_tv0_in_tcon_top: endpoint {
> > >>                       
> > >>                               // endpoint depends on board, part of
> > >>                               board DTS
> > >>                               remote-endpoint = <phandle to one of
> > >>                               tcon_top_out_tcon>;
> > > 
> > > Just curious, what would be there?

Either phandle to tcon_top_out_tcon0 or tcon_top_out_tcon1.

> > > 
> > >>                       };
> > >>               
> > >>               };
> > >>               
> > >>               tcon_tv0_out: port at 1 {
> > >>               
> > >>                       #address-cells = <1>;
> > >>                       #size-cells = <0>;
> > >>                       reg = <1>;
> > >>                       
> > >>                       // endpoints to TV TOP and TCON TOP HDMI input
> > >>                       ...
> > >>               
> > >>               };
> > >>       
> > >>       };
> > >> 
> > >> };
> > >> 
> > >> tcon_tv1: lcd-controller at 1c74000 {
> > >> 
> > >>       compatible = "allwinner,sun8i-r40-tcon-tv-1";
> > >>       ...
> > >>       ports {
> > >>       
> > >>               #address-cells = <1>;
> > >>               #size-cells = <0>;
> > >>               
> > >>               tcon_tv1_in: port at 0 {
> > >>               
> > >>                       reg = <0>;
> > >>                       
> > >>                       tcon_tv1_in_tcon_top: endpoint {
> > >>                       
> > >>                               // endpoint depends on board, part of
> > >>                               board DTS
> > >>                               remote-endpoint = <phandle to one of
> > >>                               tcon_top_out_tcon>;
> > >>                       
> > >>                       };
> > >>               
> > >>               };
> > >>               
> > >>               tcon_tv1_out: port at 1 {
> > >>               
> > >>                       #address-cells = <1>;
> > >>                       #size-cells = <0>;
> > >>                       reg = <1>;
> > >>                       
> > >>                       // endpoints to TV TOP and TCON TOP HDMI input
> > >>                       ...
> > >>               
> > >>               };
> > >>       
> > >>       };
> > >> 
> > >> };
> > >> 
> > >> tcon_lcd0 and tcon_lcd1 would have similar connections, except that for
> > >> outputs would be LCD or LVDS panels or MIPI DSI encoder.
> > >> 
> > >> Please note that each TCON (there are 4 of them) would need to have
> > >> unique
> > >> compatible and have HW index stored in quirks data. It would be used by
> > >> TCON TOP driver for configuring muxes.
> > > 
> > > Can't we use the port/endpoint ID instead? If the mux is the only
> > > thing that changes, the compatible has no reason to. It's the same IP,
> > > and the only thing that changes is something that is not part of that
> > > IP.
> > 
> > I agree. Endpoint IDs should provide that information. I'm still not
> > sure How to encode multiple in/out mux groups in a device node though.
> 
> I guess we can do that through different ports?

Ok, I'll try to do something with "reg" property.

Best regards,
Jernej

^ permalink raw reply

* [PATCH v12 3/5] arm64: pgtable: Add p*d_page_vaddr helper macros
From: Will Deacon @ 2018-06-04 15:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <28cc339e-b184-5f15-eca3-cf54e9376e01@codeaurora.org>

On Mon, Jun 04, 2018 at 07:13:48PM +0530, Chintan Pandya wrote:
> 
> 
> On 6/4/2018 5:43 PM, Will Deacon wrote:
> >On Fri, Jun 01, 2018 at 06:09:16PM +0530, Chintan Pandya wrote:
> >>Add helper macros to give virtual references to page
> >>tables. These will be used while freeing dangling
> >>page tables.
> >>
> >>Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
> >>---
> >>  arch/arm64/include/asm/pgtable.h | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >>diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> >>index 7c4c8f3..ef4047f 100644
> >>--- a/arch/arm64/include/asm/pgtable.h
> >>+++ b/arch/arm64/include/asm/pgtable.h
> >>@@ -580,6 +580,9 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
> >>  #endif  /* CONFIG_PGTABLE_LEVELS > 3 */
> >>+#define pmd_page_vaddr(pmd) __va(pmd_page_paddr(pmd))
> >>+#define pud_page_vaddr(pud) __va(pud_page_paddr(pud))
> >
> >Are these actually needed, or do pte_offset_kernel and pmd_offset do the
> >job already?
> >
> 
> I introduced these macros for consistency across different arch.
> 
> Looking at pte_offset_kernel, it seems to use READ_ONCE() which looks
> little costly for its intended use (in next patch) where we already have
> dereferenced value. Do you still suggest to remove this ?

It's only an additional load instruction on the freeing path and it matches
what we do in other page table code, so I'd rather use the existing API
unless we have numbers to show otherwise.

Will

^ permalink raw reply

* [PATCH v9 00/12] Support PPTT for ARM64
From: Catalin Marinas @ 2018-06-04 15:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180517170523.h7tuvbzdfluuidcz@armageddon.cambridge.arm.com>

On Thu, May 17, 2018 at 06:05:24PM +0100, Catalin Marinas wrote:
> On Fri, May 11, 2018 at 06:57:55PM -0500, Jeremy Linton wrote:
> > Jeremy Linton (12):
> >   drivers: base: cacheinfo: move cache_setup_of_node()
> >   drivers: base: cacheinfo: setup DT cache properties early
> >   cacheinfo: rename of_node to fw_token
> >   arm64/acpi: Create arch specific cpu to acpi id helper
> >   ACPI/PPTT: Add Processor Properties Topology Table parsing
> >   ACPI: Enable PPTT support on ARM64
> >   drivers: base cacheinfo: Add support for ACPI based firmware tables
> >   arm64: Add support for ACPI based firmware tables
> >   arm64: topology: rename cluster_id
> >   arm64: topology: enable ACPI/PPTT based CPU topology
> >   ACPI: Add PPTT to injectable table list
> >   arm64: topology: divorce MC scheduling domain from core_siblings
> 
> Queued for 4.18 (without Sudeep's latest property_read_u64 cacheinfo
> patch - http://lkml.kernel.org/r/20180517154701.GA20281 at e107155-lin; I
> can add it separately).

I'm going to revert patch 12 in this series (arm64: topology: divorce MC
scheduling domain from core_siblings) until the problem is understood
and a fix proposed and tested. It's likely that the PPTT for arm64 will
only be fully enabled in 4.19.

-- 
Catalin

^ permalink raw reply

* [PATCHv9 1/3] ARM:dt-bindings:display Intel FPGA Video and Image Processing Suite
From: Rob Herring @ 2018-06-04 15:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528094404-3542-2-git-send-email-hean.loong.ong@intel.com>

On Mon, Jun 04, 2018 at 02:40:02PM +0800, Hean-Loong, Ong wrote:
> From: Ong, Hean Loong <hean.loong.ong@intel.com>
> 
> Device tree binding for Intel FPGA Video and Image Processing Suite. The binding involved would be generated from the Altera (Intel) Qsys system. The bindings would set the max width, max height, buts per pixel and memory port width. The device tree binding only supports the Intel
> Arria10 devkit and its variants. Vendor name retained as altr.

You need to wrap long lines.

> 
> V8:
> *Add port to Display port decoder
> 
> V7:
> *Fix OF graph for better description
> *Add description for encoder
> 
> V6:
> *Description have not describe DT device in general
> 
> V5:
> *remove bindings for bits per symbol as it has only one value which is 8
> 
> V4:
> *fix properties that does not describe the values
> 
> V3:
> *OF graph not in accordance to graph.txt
> 
> V2:
> *Remove Linux driver description
> 
> V1:
> *Missing vendor prefix
> 
> Signed-off-by: Ong, Hean Loong <hean.loong.ong@intel.com>
> ---
>  .../devicetree/bindings/display/altr,vip-fb2.txt   |   99 ++++++++++++++++++++
>  1 files changed, 99 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/display/altr,vip-fb2.txt
> 
> diff --git a/Documentation/devicetree/bindings/display/altr,vip-fb2.txt b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
> new file mode 100644
> index 0000000..4092804
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
> @@ -0,0 +1,99 @@
> +Intel Video and Image Processing(VIP) Frame Buffer II bindings
> +
> +Supported hardware: Intel FPGA SoC Arria10 and above with display port IP
> +
> +The Video Frame Buffer II in Video Image Processing (VIP) suite is an IP core
> +that interfaces between system memory and Avalon-ST video ports. The IP core
> +can be configured to support the memory reader (from memory to Avalon-ST)
> +and/or memory writer (from Avalon-ST to memory) interfaces.
> +
> +More information the FPGA video IP component can be acquired from
> +https://www.altera.com/content/dam/altera-www/global/en_US/pdfs\
> +/literature/ug/ug_vip.pdf

But URLs you don't need to wrap.

> +
> +DT-Bindings:
> +=============
> +Required properties:
> +----------------------------
> +- compatible: "altr,vip-frame-buffer-2.0"
> +- reg: Physical base address and length of the framebuffer controller's
> +	registers.
> +- altr,max-width: The maximum width of the framebuffer in pixels.
> +- altr,max-height: The maximum height of the framebuffer in pixels.
> +- altr,mem-port-width = the bus width of the avalon master port
> +	on the frame reader
> +
> +Optional sub-nodes:
> +- ports: The connection to the encoder
> +
> +Optional properties

These are not optional properties because this is a whole other node. 
Group things by node (perhaps even make this 2 docments) and within each 
node you describe required and optional properties.

> +----------------------------
> +- compatible: "altr, display-port"

spurious space         ^

This needs to be more specific. Is there an IP version?

This is a DisplayPort encoder?

> +- reg: Physical base address and length of the display port controller's
> +	registers
> +- clocks: required clock handles for specified pairs in clock name
> +- clock-names: required clock names. Contains:
> +	- aux_clk: auxiliary clock,
> +	- clk: 100 MHz output clock

But 'clocks' are input clocks.

Needs a better name than 'clk'.

> +	- xcvr_mgmt_clk: transceiver management clock

'_clk' is redundant.

> +
> +Optional sub-nodes:
> +- ports: The connection to the controller
> +
> +Connections between the Frame Buffer II and other video IP cores in the system
> +are modelled using the OF graph DT bindings. The Frame Buffer II node has up

s/modelled/modeled/

> +to two OF graph ports. When the memory writer interface is enabled, port 0
> +maps to the Avalon-ST Input (din) port. When the memory reader interface is
> +enabled, port 1 maps to the Avalon-ST Output (dout) port.
> +
> +The encoder is built into the FPGA HW design and therefore would not
> +be accessible from the DDR.
> +
> +		Port 0				Port1
> +---------------------------------------------------------
> +ARRIA10 AVALON_ST (DIN)		AVALON_ST (DOUT)
> +
> +Required Properties Example:
> +----------------------------
> +
> +framebuffer at 100000280 {
> +		compatible = "altr,vip-frame-buffer-2.0";
> +		reg = <0x00000001 0x00000280 0x00000040>;
> +		altr,max-width = <1280>;
> +		altr,max-height = <720>;
> +		altr,mem-port-width = <128>;

Doesn't this block require some clocks too?

> +
> +		ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +			port at 1 {
> +				reg = <1>;
> +					fb_output: endpoint {
> +						remote-endpoint = <&dp_encoder_input>;
> +					};
> +			};
> +		};
> +};
> +
> +Optional Properties Example:
> +This is not required unless there are needs to customize
> +Display Port controller settings.
> +
> +displayport at 100002000 {
> +		compatible = "altr, display-port";
> +		reg = <0x00000001 0x00002000 0x00000800>;
> +		clocks = <&dp_0_clk_16 &dp_0_clk_100 &dp_0_clk_100>;
> +		clock-names = "aux_clk", "clk", "xcvr_mgmt_clk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <1>;
> +					dp_input: endpoint {
> +						remote-endpoint = <&dp_controller_input>;
> +					};
> +			};
> +};
> -- 
> 1.7.1
> 

^ permalink raw reply

* [PATCH v3] of: platform: stop accessing invalid dev in of_platform_device_destroy
From: Rob Herring @ 2018-06-04 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180604141408.3179-1-srinivas.kandagatla@linaro.org>

On Mon, Jun 04, 2018 at 03:14:08PM +0100, Srinivas Kandagatla wrote:
> Immediately after the platform_device_unregister() the device will be
> cleaned up. Accessing the freed pointer immediately after that will
> crash the system.
> 
> Found this bug when kernel is built with CONFIG_PAGE_POISONING and testing
> loading/unloading audio drivers in a loop on Qcom platforms.
> 
> Fix this by moving of_node_clear_flag() just before the unregister calls.
> 
> Below is the crash trace:
> 
> Unable to handle kernel paging request at virtual address 6b6b6b6b6b6c03
> Mem abort info:
>   ESR = 0x96000021
>   Exception class = DABT (current EL), IL = 32 bits
>   SET = 0, FnV = 0
>   EA = 0, S1PTW = 0
> Data abort info:
>   ISV = 0, ISS = 0x00000021
>   CM = 0, WnR = 0
> [006b6b6b6b6b6c03] address between user and kernel address ranges
> Internal error: Oops: 96000021 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 2 PID: 1784 Comm: sh Tainted: G        W         4.17.0-rc7-02230-ge3a63a7ef641-dirty #204
> Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
> pstate: 80000005 (Nzcv daif -PAN -UAO)
> pc : clear_bit+0x18/0x2c
> lr : of_platform_device_destroy+0x64/0xb8
> sp : ffff00000c9c3930
> x29: ffff00000c9c3930 x28: ffff80003d39b200
> x27: ffff000008bb1000 x26: 0000000000000040
> x25: 0000000000000124 x24: ffff80003a9a3080
> x23: 0000000000000060 x22: ffff00000939f518
> x21: ffff80003aa79e98 x20: ffff80003aa3dae0
> x19: ffff80003aa3c890 x18: ffff800009feb794
> x17: 0000000000000000 x16: 0000000000000000
> x15: ffff800009feb790 x14: 0000000000000000
> x13: ffff80003a058778 x12: ffff80003a058728
> x11: ffff80003a058750 x10: 0000000000000000
> x9 : 0000000000000006 x8 : ffff80003a825988
> x7 : bbbbbbbbbbbbbbbb x6 : 0000000000000001
> x5 : 0000000000000000 x4 : 0000000000000001
> x3 : 0000000000000008 x2 : 0000000000000001
> x1 : 6b6b6b6b6b6b6c03 x0 : 0000000000000000
> Process sh (pid: 1784, stack limit = 0x        (ptrval))
> Call trace:
>  clear_bit+0x18/0x2c
>  q6afe_remove+0x20/0x38
>  apr_device_remove+0x30/0x70
>  device_release_driver_internal+0x170/0x208
>  device_release_driver+0x14/0x20
>  bus_remove_device+0xcc/0x150
>  device_del+0x10c/0x310
>  device_unregister+0x1c/0x70
>  apr_remove_device+0xc/0x18
>  device_for_each_child+0x50/0x80
>  apr_remove+0x18/0x20
>  rpmsg_dev_remove+0x38/0x68
>  device_release_driver_internal+0x170/0x208
>  device_release_driver+0x14/0x20
>  bus_remove_device+0xcc/0x150
>  device_del+0x10c/0x310
>  device_unregister+0x1c/0x70
>  qcom_smd_remove_device+0xc/0x18
>  device_for_each_child+0x50/0x80
>  qcom_smd_unregister_edge+0x3c/0x70
>  smd_subdev_remove+0x18/0x28
>  rproc_stop+0x48/0xd8
>  rproc_shutdown+0x60/0xe8
>  state_store+0xbc/0xf8
>  dev_attr_store+0x18/0x28
>  sysfs_kf_write+0x3c/0x50
>  kernfs_fop_write+0x118/0x1e0
>  __vfs_write+0x18/0x110
>  vfs_write+0xa4/0x1a8
>  ksys_write+0x48/0xb0
>  sys_write+0xc/0x18
>  el0_svc_naked+0x30/0x34
> Code: d2800022 8b400c21 f9800031 9ac32043 (c85f7c22)
> ---[ end trace 32020935775616a2 ]---
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> Changes since v2:
>  Move the calls to of_node_clear_flag just before unregister,
>  suggested by Rob.
> 
>  drivers/of/platform.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Applied, thanks.

Rob

^ permalink raw reply

* [PATCH] mtd: nand: raw: atmel: add module param to avoid using dma
From: Tudor Ambarus @ 2018-06-04 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c3cc1894-2d7d-93b6-a9de-ed9ca4564ae9@axentia.se>

Hi, Peter,

On 05/28/2018 01:10 PM, Peter Rosin wrote:

[cut]

> So, I think I want either
> 
> A) the NAND controller to use master 1 DMAC0/IF0 (i.e. slave 8 DDR2 port 2) and
>     the LCDC to use master 9 (i.e. slave 9 DDR2 Port 3)
> 
> or
> 
> B) the NAND controller to use master 2 DMAC0/IF1 (i.e. slave 7 DDR2 port 1, and
>     possibly slave 9 DDR2 port 3 (if my previous findings are relevant) and the
>     LCDC to use master 8 (i.e. slave 8 DDR2 Port 2)

My understanding is that "Table 14-3. Master to Slave Access" describes
what connections are allowed between the masters and slaves, while the
PRxSy registers just set the priorities. What happens when you assign
the highest priority to a master to slave connection that is not
allowed? Probably it is ignored, but I'll check with the hardware team.
So I expect that the NAND controller can not use DDR2 port 3 regardless
of the priority set.

[cut]

> So, output is as expected and I believe that the patch makes the NAND DMA
> accesses use master 2 DMAC0/IF1 and are thus forced to use slave 7 DDR2 Port 1
> (and possibly 9). The LCDC is using slave 8 DDR2 Port 2. So there should be no
> slave conflict?
> 
> But the on-screen crap remains during NAND accesses.

No conflict, but you missed to dispatch the load on the LCDC DMA
masters, if I understood correctly.

So, I think we want to test the following:
- NAND controller to use DMAC0/IF1 (slave 7 DDR2 port 1)
- LCDC to use master 8 (slave 8 DDR2 Port 2) and master 9 (slave 9 DDR2
Port 3).

Best,
ta

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox