[PATCH V2 RESEND 1/4] PM / devfreq: Use more accurate returned new_freq as resume_freq

2021-03-23 Thread Dong Aisheng
Use the more accurate returned new_freq as resume_freq.
It's the same as how devfreq->previous_freq was updated.

Fixes: 83f8ca45afbf0 ("PM / devfreq: add support for suspend/resume of a
devfreq device")
Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index b6d3e7db0b09..85927bd7ee76 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -388,7 +388,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
devfreq->previous_freq = new_freq;
 
if (devfreq->suspend_freq)
-   devfreq->resume_freq = cur_freq;
+   devfreq->resume_freq = new_freq;
 
return err;
 }
-- 
2.25.1



[PATCH V2 RESEND 3/4] PM / devfreq: bail out early if no freq changes in devfreq_set_target

2021-03-23 Thread Dong Aisheng
It's unnecessary to set the same freq again and run notifier calls.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 85927bd7ee76..a6ee91dd17bd 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -352,13 +352,16 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 {
struct devfreq_freqs freqs;
unsigned long cur_freq;
-   int err = 0;
+   int err;
 
if (devfreq->profile->get_cur_freq)
devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq);
else
cur_freq = devfreq->previous_freq;
 
+   if (new_freq == cur_freq)
+   return 0;
+
freqs.old = cur_freq;
freqs.new = new_freq;
devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);
@@ -375,7 +378,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 * and DEVFREQ_POSTCHANGE because for showing the correct frequency
 * change order of between devfreq device and passive devfreq device.
 */
-   if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
+   if (trace_devfreq_frequency_enabled())
trace_devfreq_frequency(devfreq, new_freq, cur_freq);
 
freqs.new = new_freq;
@@ -390,7 +393,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
if (devfreq->suspend_freq)
devfreq->resume_freq = new_freq;
 
-   return err;
+   return 0;
 }
 
 /**
-- 
2.25.1



[PATCH V2 RESEND 4/4] PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

2021-03-23 Thread Dong Aisheng
Current driver actually does not support simple ondemand governor
as it's unable to provide device load information. So removing
the unnecessary callback to avoid confusing.
Right now the driver is using userspace governor by default.

polling_ms was also dropped as it's not needed for non-ondemand
governor.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index bc82d3653bff..ecb9375aa877 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -280,18 +280,6 @@ static int imx8m_ddrc_get_cur_freq(struct device *dev, 
unsigned long *freq)
return 0;
 }
 
-static int imx8m_ddrc_get_dev_status(struct device *dev,
-struct devfreq_dev_status *stat)
-{
-   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
-
-   stat->busy_time = 0;
-   stat->total_time = 0;
-   stat->current_frequency = clk_get_rate(priv->dram_core);
-
-   return 0;
-}
-
 static int imx8m_ddrc_init_freq_info(struct device *dev)
 {
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -429,9 +417,7 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
 
-   priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
-   priv->profile.get_dev_status = imx8m_ddrc_get_dev_status;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
priv->profile.initial_freq = clk_get_rate(priv->dram_core);
-- 
2.25.1



[PATCH V2 RESEND 2/4] PM / devfreq: Remove the invalid description for get_target_freq

2021-03-23 Thread Dong Aisheng
First of all, no_central_polling was removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")
Secondly, get_target_freq() is not only called only with update_devfreq()
notified by OPP now, but also min/max freq qos notifier.

So remove this invalid description now to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 Documentation/ABI/testing/sysfs-class-devfreq | 5 +
 drivers/devfreq/governor.h| 2 --
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-devfreq 
b/Documentation/ABI/testing/sysfs-class-devfreq
index 386bc230a33d..5e6b74f30406 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -97,10 +97,7 @@ Description:
object. The values are represented in ms. If the value is
less than 1 jiffy, it is considered to be 0, which means
no polling. This value is meaningless if the governor is
-   not polling; thus. If the governor is not using
-   devfreq-provided central polling
-   (/sys/class/devfreq/.../central_polling is 0), this value
-   may be useless.
+   not polling.
 
A list of governors that support the node:
- simple_ondmenad
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 244634465170..2d69a0ce6291 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -57,8 +57,6 @@
  * Basically, get_target_freq will run
  * devfreq_dev_profile.get_dev_status() to get the
  * status of the device (load = busy_time / total_time).
- * If no_central_polling is set, this callback is called
- * only with update_devfreq() notified by OPP.
  * @event_handler:  Callback for devfreq core framework to notify events
  *  to governors. Events include per device governor
  *  init and exit, opp changes out of devfreq, suspend
-- 
2.25.1



[PATCH V2 RESEND 0/4] PM / devfreq: a few small fixes and improvements

2021-03-23 Thread Dong Aisheng
A few small fixes and improvements

ChangeLog:
v2 Resend:
 * rebase to devfreq-next
 * drop original patch 1 & 5.
   Patch 5 will be re-sent later when dependent patches merged.
v1->v2:
 * squash a few patches
 * rebase to devfreq-testing


Dong Aisheng (4):
  PM / devfreq: Use more accurate returned new_freq as resume_freq
  PM / devfreq: Remove the invalid description for get_target_freq
  PM / devfreq: bail out early if no freq changes in devfreq_set_target
  PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

 Documentation/ABI/testing/sysfs-class-devfreq |  5 +
 drivers/devfreq/devfreq.c | 11 +++
 drivers/devfreq/governor.h|  2 --
 drivers/devfreq/imx8m-ddrc.c  | 14 --
 4 files changed, 8 insertions(+), 24 deletions(-)

-- 
2.25.1



Re: [PATCH V2 0/6] PM / devfreq: a few small fixes and improvements

2021-03-22 Thread Dong Aisheng
Hi Chanwoo,

On Tue, Mar 23, 2021 at 11:13 AM Dong Aisheng  wrote:
>
> A few small fixes and improvements
>
> ChangeLog:
> v1->v2:
>  * squash a few patches
>  * rebase to devfreq-testing

I have to rebase to devfreq-testing instead of devfreq-next because
below two patches
only exist in devfreq-testing.
5cc75e9252e9 (devfreq/devfreq-testing) PM / devfreq: Add
devfreq_transitions debugfs file
dc9e557845c1 PM / devfreq: Add new up_threshold and down_differential
sysfs attrs
My patch 5 needs change based on it according to your suggestion. So i have to
rebase to that branch.

However, i found devfreq-testing can't build with GOV_PASSVIE enabled.
Patch 1 fixed it. You can squash to the original one when apply.

Please help take a look at this new series.
Thanks

Regards
Aisheng

>  * drop two patches which are already in devfreq-next
>
> Dong Aisheng (6):
>   PM / devfreq: fix build error when DEVFREQ_GOV_PASSIVE enabled
>   PM / devfreq: Use more accurate returned new_freq as resume_freq
>   PM / devfreq: Remove the invalid description for get_target_freq
>   PM / devfreq: bail out early if no freq changes in devfreq_set_target
>   PM / devfreq: governor: optimize simpleondemand get_target_freq
>   PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status
>
>  Documentation/ABI/testing/sysfs-class-devfreq |  5 +--
>  drivers/devfreq/devfreq.c | 37 +++
>  drivers/devfreq/governor.h|  2 -
>  drivers/devfreq/governor_simpleondemand.c | 31 ++--
>  drivers/devfreq/imx8m-ddrc.c  | 14 ---
>  5 files changed, 35 insertions(+), 54 deletions(-)
>
> --
> 2.25.1
>


[PATCH V2 6/6] PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

2021-03-22 Thread Dong Aisheng
Current driver actually does not support simple ondemand governor
as it's unable to provide device load information. So removing
the unnecessary callback to avoid confusing.
Right now the driver is using userspace governor by default.

polling_ms was also dropped as it's not needed for non-ondemand
governor.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index bc82d3653bff..ecb9375aa877 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -280,18 +280,6 @@ static int imx8m_ddrc_get_cur_freq(struct device *dev, 
unsigned long *freq)
return 0;
 }
 
-static int imx8m_ddrc_get_dev_status(struct device *dev,
-struct devfreq_dev_status *stat)
-{
-   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
-
-   stat->busy_time = 0;
-   stat->total_time = 0;
-   stat->current_frequency = clk_get_rate(priv->dram_core);
-
-   return 0;
-}
-
 static int imx8m_ddrc_init_freq_info(struct device *dev)
 {
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -429,9 +417,7 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
 
-   priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
-   priv->profile.get_dev_status = imx8m_ddrc_get_dev_status;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
priv->profile.initial_freq = clk_get_rate(priv->dram_core);
-- 
2.25.1



[PATCH V2 5/6] PM / devfreq: governor: optimize simpleondemand get_target_freq

2021-03-22 Thread Dong Aisheng
The device profile up_threshold/down_differential only needs to be
initialized once when calling devm_devfreq_add_device. It's unnecessary
to put the data check logic in the hot path (.get_target_freq()) where it
will be called all the time during polling. Instead, we only check and
initialize it one time during DEVFREQ_GOV_START.

This also helps check data validability in advance during DEVFREQ_GOV_START
rather than checking it later when running .get_target_freq().

Signed-off-by: Dong Aisheng 
---
Change Log:
v1->v2:
 * rebase to devfreq-testing
---
 drivers/devfreq/devfreq.c | 24 +-
 drivers/devfreq/governor_simpleondemand.c | 31 +++
 2 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index cacda7d1f858..270e51f5318f 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1908,9 +1908,7 @@ static ssize_t up_threshold_show(struct device *dev,
if (!df->profile)
return -EINVAL;
 
-   return sprintf(buf, "%d\n", df->profile->up_threshold
-   ? df->profile->up_threshold
-   : DEVFREQ_UP_THRESHOLD);
+   return sprintf(buf, "%d\n", df->profile->up_threshold);
 }
 
 static ssize_t up_threshold_store(struct device *dev,
@@ -1934,9 +1932,7 @@ static ssize_t up_threshold_store(struct device *dev,
if (value > 100)
value = 100;
 
-   down_differential = df->profile->down_differential
-   ? df->profile->down_differential
-   : DEVFREQ_DOWN_DIFFERENCTIAL;
+   down_differential = df->profile->down_differential;
if (value < down_differential)
value = down_differential;
 
@@ -1961,9 +1957,7 @@ static ssize_t down_differential_show(struct device *dev,
if (!df->profile)
return -EINVAL;
 
-   return sprintf(buf, "%d\n", df->profile->down_differential
-   ? df->profile->down_differential
-   : DEVFREQ_DOWN_DIFFERENCTIAL);
+   return sprintf(buf, "%d\n", df->profile->down_differential);
 }
 
 static ssize_t down_differential_store(struct device *dev,
@@ -1984,9 +1978,7 @@ static ssize_t down_differential_store(struct device *dev,
if (ret != 1)
return -EINVAL;
 
-   up_threshold = df->profile->up_threshold
-   ? df->profile->up_threshold
-   : DEVFREQ_UP_THRESHOLD;
+   up_threshold = df->profile->up_threshold;
if (value > up_threshold)
value = up_threshold;
 
@@ -2113,16 +2105,12 @@ static int devfreq_summary_show(struct seq_file *s, 
void *data)
polling_ms = 0;
 
if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, UP_THRESHOLD))
-   up_threshold = devfreq->profile->up_threshold
-   ? devfreq->profile->up_threshold
-   : DEVFREQ_UP_THRESHOLD;
+   up_threshold = devfreq->profile->up_threshold;
else
up_threshold = 0;
 
if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, DOWN_DIFF))
-   down_differential = devfreq->profile->down_differential
-   ? devfreq->profile->down_differential
-   : DEVFREQ_DOWN_DIFFERENCTIAL;
+   down_differential = devfreq->profile->down_differential;
else
down_differential = 0;
mutex_unlock(>lock);
diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index 93f6061667d9..3e195b46554a 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -18,8 +18,8 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
int err;
struct devfreq_dev_status *stat;
unsigned long long a, b;
-   unsigned int dfso_upthreshold = DEVFREQ_UP_THRESHOLD;
-   unsigned int dfso_downdifferential = DEVFREQ_DOWN_DIFFERENCTIAL;
+   unsigned int dfso_upthreshold = df->profile->up_threshold;
+   unsigned int dfso_downdifferential = df->profile->down_differential;
 
err = devfreq_update_stats(df);
if (err)
@@ -27,15 +27,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
stat = >last_status;
 
-   if (df->profile->up_threshold)
-   dfso_upthreshold = df->profile->up_threshold;
-   if (df->profile->d

[PATCH V2 1/6] PM / devfreq: fix build error when DEVFREQ_GOV_PASSIVE enabled

2021-03-22 Thread Dong Aisheng
drivers/devfreq/devfreq.c: In function ‘devfreq_transitions_show’:
drivers/devfreq/devfreq.c:2188:25: error: ‘struct devfreq’ has no member named 
‘governor_name’; did you mean ‘governor’?
 2188 |   if (!strncmp(devfreq->governor_name,
  | ^
  | governor

Fixes: 5cc75e9252e9 ("PM / devfreq: Add devfreq_transitions debugfs file")
Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index d625b268adf2..107badfc6b2b 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -2185,7 +2185,7 @@ static int devfreq_transitions_show(struct seq_file *s, 
void *data)
continue;
 
 #if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
-   if (!strncmp(devfreq->governor_name,
+   if (!strncmp(devfreq->governor->name,
DEVFREQ_GOV_PASSIVE, DEVFREQ_NAME_LEN)) {
struct devfreq_passive_data *data = devfreq->data;
 
-- 
2.25.1



[PATCH V2 3/6] PM / devfreq: Remove the invalid description for get_target_freq

2021-03-22 Thread Dong Aisheng
First of all, no_central_polling was removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")
Secondly, get_target_freq() is not only called only with update_devfreq()
notified by OPP now, but also min/max freq qos notifier.

So remove this invalid description now to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 Documentation/ABI/testing/sysfs-class-devfreq | 5 +
 drivers/devfreq/governor.h| 2 --
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-devfreq 
b/Documentation/ABI/testing/sysfs-class-devfreq
index 22408cfa7ed2..e71595c84f22 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -97,10 +97,7 @@ Description:
object. The values are represented in ms. If the value is
less than 1 jiffy, it is considered to be 0, which means
no polling. This value is meaningless if the governor is
-   not polling; thus. If the governor is not using
-   devfreq-provided central polling
-   (/sys/class/devfreq/.../central_polling is 0), this value
-   may be useless.
+   not polling.
 
A list of governors that support the node:
- simple_ondmenad
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 48736a2ae970..9d72f5b66bfa 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -67,8 +67,6 @@
  * Basically, get_target_freq will run
  * devfreq_dev_profile.get_dev_status() to get the
  * status of the device (load = busy_time / total_time).
- * If no_central_polling is set, this callback is called
- * only with update_devfreq() notified by OPP.
  * @event_handler:  Callback for devfreq core framework to notify events
  *  to governors. Events include per device governor
  *  init and exit, opp changes out of devfreq, suspend
-- 
2.25.1



[PATCH V2 0/6] PM / devfreq: a few small fixes and improvements

2021-03-22 Thread Dong Aisheng
A few small fixes and improvements

ChangeLog:
v1->v2:
 * squash a few patches
 * rebase to devfreq-testing
 * drop two patches which are already in devfreq-next

Dong Aisheng (6):
  PM / devfreq: fix build error when DEVFREQ_GOV_PASSIVE enabled
  PM / devfreq: Use more accurate returned new_freq as resume_freq
  PM / devfreq: Remove the invalid description for get_target_freq
  PM / devfreq: bail out early if no freq changes in devfreq_set_target
  PM / devfreq: governor: optimize simpleondemand get_target_freq
  PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

 Documentation/ABI/testing/sysfs-class-devfreq |  5 +--
 drivers/devfreq/devfreq.c | 37 +++
 drivers/devfreq/governor.h|  2 -
 drivers/devfreq/governor_simpleondemand.c | 31 ++--
 drivers/devfreq/imx8m-ddrc.c  | 14 ---
 5 files changed, 35 insertions(+), 54 deletions(-)

-- 
2.25.1



[PATCH V2 2/6] PM / devfreq: Use more accurate returned new_freq as resume_freq

2021-03-22 Thread Dong Aisheng
Use the more accurate returned new_freq as resume_freq.
It's the same as how devfreq->previous_freq was updated.

Fixes: 83f8ca45afbf0 ("PM / devfreq: add support for suspend/resume of a
devfreq device")
Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 107badfc6b2b..b537fd9602cd 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -443,7 +443,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
devfreq->previous_freq = new_freq;
 
if (devfreq->suspend_freq)
-   devfreq->resume_freq = cur_freq;
+   devfreq->resume_freq = new_freq;
 
return err;
 }
-- 
2.25.1



[PATCH V2 4/6] PM / devfreq: bail out early if no freq changes in devfreq_set_target

2021-03-22 Thread Dong Aisheng
It's unnecessary to set the same freq again and run notifier calls.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index b537fd9602cd..cacda7d1f858 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -403,13 +403,16 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 {
struct devfreq_freqs freqs;
unsigned long cur_freq;
-   int err = 0;
+   int err;
 
if (devfreq->profile->get_cur_freq)
devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq);
else
cur_freq = devfreq->previous_freq;
 
+   if (new_freq == cur_freq)
+   return 0;
+
freqs.old = cur_freq;
freqs.new = new_freq;
devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);
@@ -426,7 +429,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 * and DEVFREQ_POSTCHANGE because for showing the correct frequency
 * change order of between devfreq device and passive devfreq device.
 */
-   if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
+   if (trace_devfreq_frequency_enabled())
trace_devfreq_frequency(devfreq, new_freq, cur_freq);
 
devfreq_update_transitions(devfreq, cur_freq, new_freq,
@@ -445,7 +448,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
if (devfreq->suspend_freq)
devfreq->resume_freq = new_freq;
 
-   return err;
+   return 0;
 }
 
 /**
-- 
2.25.1



Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-18 Thread Dong Aisheng
On Thu, Mar 18, 2021 at 5:42 PM Chanwoo Choi  wrote:
>
> On 3/18/21 6:54 PM, Chanwoo Choi wrote:
> > On 3/18/21 5:03 PM, Dong Aisheng wrote:
> >> Hi Chanwoo,
> >>
> >> On Sat, Mar 13, 2021 at 2:45 PM Dong Aisheng  wrote:
> >>>
> >>> On Sat, Mar 13, 2021 at 12:09 AM Chanwoo Choi  wrote:
> >>>>
> >>>> On 21. 3. 12. 오후 7:57, Dong Aisheng wrote:
> >>>>> On Thu, Mar 11, 2021 at 2:54 PM Chanwoo Choi  
> >>>>> wrote:
> >>>>>>
> >>>>>> On 3/10/21 1:56 PM, Dong Aisheng wrote:
> >>>>>>> On Wed, Mar 10, 2021 at 11:08 AM Chanwoo Choi  
> >>>>>>> wrote:
> >>>>>>>>
> >>>>>>>> On 3/10/21 11:56 AM, Dong Aisheng wrote:
> >>>>>>>>> On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  
> >>>>>>>>> wrote:
> >>>>>>>>>>
> >>>>>>>>>> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> >>>>>>>>>>> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >>>>>>>>>>>> The devfreq monitor depends on the device to provide load 
> >>>>>>>>>>>> information
> >>>>>>>>>>>> by .get_dev_status() to calculate the next target freq.
> >>>>>>>>>>>>
> >>>>>>>>>>>> And this will cause changing governor to simple ondemand fail
> >>>>>>>>>>>> if device can't support.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Signed-off-by: Dong Aisheng 
> >>>>>>>>>>>> ---
> >>>>>>>>>>>>drivers/devfreq/devfreq.c | 10 +++---
> >>>>>>>>>>>>drivers/devfreq/governor.h|  2 +-
> >>>>>>>>>>>>drivers/devfreq/governor_simpleondemand.c |  3 +--
> >>>>>>>>>>>>3 files changed, 9 insertions(+), 6 deletions(-)
> >>>>>>>>>>>>
> >>>>>>>>>>>> diff --git a/drivers/devfreq/devfreq.c 
> >>>>>>>>>>>> b/drivers/devfreq/devfreq.c
> >>>>>>>>>>>> index 7231fe6862a2..d1787b6c7d7c 100644
> >>>>>>>>>>>> --- a/drivers/devfreq/devfreq.c
> >>>>>>>>>>>> +++ b/drivers/devfreq/devfreq.c
> >>>>>>>>>>>> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct 
> >>>>>>>>>>>> work_struct
> >>>>>>>>>>>> *work)
> >>>>>>>>>>>> * to be called from governor in response to DEVFREQ_GOV_START
> >>>>>>>>>>>> * event when device is added to devfreq framework.
> >>>>>>>>>>>> */
> >>>>>>>>>>>> -void devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>>>>>>>> +int devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>>>>>>>>{
> >>>>>>>>>>>>if (IS_SUPPORTED_FLAG(devfreq->governor->flags, 
> >>>>>>>>>>>> IRQ_DRIVEN))
> >>>>>>>>>>>> -return;
> >>>>>>>>>>>> +return 0;
> >>>>>>>>>>>> +
> >>>>>>>>>>>> +if (!devfreq->profile->get_dev_status)
> >>>>>>>>>>>> +return -EINVAL;
> >>>>>>>>>>
> >>>>>>>>>> Again, I think that get_dev_status is not used for all governors.
> >>>>>>>>>> So that it cause the governor start fail. Don't check whether
> >>>>>>>>>> .get_dev_status is NULL or not.
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> I'm not quite understand your point.
> >>>>>>>>> it is used by governor_simpleondemand.c and tegra_devfreq_governor.
> >>>>>>>>> get_target_freq -> devfreq_update_stats ->

Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-18 Thread Dong Aisheng
Hi Chanwoo,

On Sat, Mar 13, 2021 at 2:45 PM Dong Aisheng  wrote:
>
> On Sat, Mar 13, 2021 at 12:09 AM Chanwoo Choi  wrote:
> >
> > On 21. 3. 12. 오후 7:57, Dong Aisheng wrote:
> > > On Thu, Mar 11, 2021 at 2:54 PM Chanwoo Choi  
> > > wrote:
> > >>
> > >> On 3/10/21 1:56 PM, Dong Aisheng wrote:
> > >>> On Wed, Mar 10, 2021 at 11:08 AM Chanwoo Choi  
> > >>> wrote:
> > >>>>
> > >>>> On 3/10/21 11:56 AM, Dong Aisheng wrote:
> > >>>>> On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  
> > >>>>> wrote:
> > >>>>>>
> > >>>>>> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> > >>>>>>> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > >>>>>>>> The devfreq monitor depends on the device to provide load 
> > >>>>>>>> information
> > >>>>>>>> by .get_dev_status() to calculate the next target freq.
> > >>>>>>>>
> > >>>>>>>> And this will cause changing governor to simple ondemand fail
> > >>>>>>>> if device can't support.
> > >>>>>>>>
> > >>>>>>>> Signed-off-by: Dong Aisheng 
> > >>>>>>>> ---
> > >>>>>>>>drivers/devfreq/devfreq.c | 10 +++---
> > >>>>>>>>drivers/devfreq/governor.h|  2 +-
> > >>>>>>>>drivers/devfreq/governor_simpleondemand.c |  3 +--
> > >>>>>>>>3 files changed, 9 insertions(+), 6 deletions(-)
> > >>>>>>>>
> > >>>>>>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > >>>>>>>> index 7231fe6862a2..d1787b6c7d7c 100644
> > >>>>>>>> --- a/drivers/devfreq/devfreq.c
> > >>>>>>>> +++ b/drivers/devfreq/devfreq.c
> > >>>>>>>> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct 
> > >>>>>>>> work_struct
> > >>>>>>>> *work)
> > >>>>>>>> * to be called from governor in response to DEVFREQ_GOV_START
> > >>>>>>>> * event when device is added to devfreq framework.
> > >>>>>>>> */
> > >>>>>>>> -void devfreq_monitor_start(struct devfreq *devfreq)
> > >>>>>>>> +int devfreq_monitor_start(struct devfreq *devfreq)
> > >>>>>>>>{
> > >>>>>>>>if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> > >>>>>>>> -return;
> > >>>>>>>> +return 0;
> > >>>>>>>> +
> > >>>>>>>> +if (!devfreq->profile->get_dev_status)
> > >>>>>>>> +return -EINVAL;
> > >>>>>>
> > >>>>>> Again, I think that get_dev_status is not used for all governors.
> > >>>>>> So that it cause the governor start fail. Don't check whether
> > >>>>>> .get_dev_status is NULL or not.
> > >>>>>>
> > >>>>>
> > >>>>> I'm not quite understand your point.
> > >>>>> it is used by governor_simpleondemand.c and tegra_devfreq_governor.
> > >>>>> get_target_freq -> devfreq_update_stats -> get_dev_status
> > >>>>
> > >>>> The devfreq can add the new governor by anyone.
> > >>>> So these functions like devfreq_monitor_* have to support
> > >>>> the governors and also must support the governor to be added
> > >>>> in the future.
> > >>>
> > >>> Yes, but devfreq_monitor_* is only used by polling mode, right?
> > >>> The governor using it has to implement get_dev_status unless
> > >>> there's an exception in the future.
> > >>>
> > >>> Currently this patch wants to address the issue that user can switch
> > >>> to ondemand governor (polling mode) by sysfs even devices does
> > >>> not support it (no get_dev_status implemented).
> > >>
> > >> As I commented, I'll fix this issue. If devfreq driver doesn't 

Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-12 Thread Dong Aisheng
On Sat, Mar 13, 2021 at 12:09 AM Chanwoo Choi  wrote:
>
> On 21. 3. 12. 오후 7:57, Dong Aisheng wrote:
> > On Thu, Mar 11, 2021 at 2:54 PM Chanwoo Choi  wrote:
> >>
> >> On 3/10/21 1:56 PM, Dong Aisheng wrote:
> >>> On Wed, Mar 10, 2021 at 11:08 AM Chanwoo Choi  
> >>> wrote:
> >>>>
> >>>> On 3/10/21 11:56 AM, Dong Aisheng wrote:
> >>>>> On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  
> >>>>> wrote:
> >>>>>>
> >>>>>> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> >>>>>>> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >>>>>>>> The devfreq monitor depends on the device to provide load information
> >>>>>>>> by .get_dev_status() to calculate the next target freq.
> >>>>>>>>
> >>>>>>>> And this will cause changing governor to simple ondemand fail
> >>>>>>>> if device can't support.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Dong Aisheng 
> >>>>>>>> ---
> >>>>>>>>drivers/devfreq/devfreq.c | 10 +++---
> >>>>>>>>drivers/devfreq/governor.h|  2 +-
> >>>>>>>>drivers/devfreq/governor_simpleondemand.c |  3 +--
> >>>>>>>>3 files changed, 9 insertions(+), 6 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> >>>>>>>> index 7231fe6862a2..d1787b6c7d7c 100644
> >>>>>>>> --- a/drivers/devfreq/devfreq.c
> >>>>>>>> +++ b/drivers/devfreq/devfreq.c
> >>>>>>>> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct
> >>>>>>>> *work)
> >>>>>>>> * to be called from governor in response to DEVFREQ_GOV_START
> >>>>>>>> * event when device is added to devfreq framework.
> >>>>>>>> */
> >>>>>>>> -void devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>>>> +int devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>>>>{
> >>>>>>>>if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> >>>>>>>> -return;
> >>>>>>>> +return 0;
> >>>>>>>> +
> >>>>>>>> +if (!devfreq->profile->get_dev_status)
> >>>>>>>> +return -EINVAL;
> >>>>>>
> >>>>>> Again, I think that get_dev_status is not used for all governors.
> >>>>>> So that it cause the governor start fail. Don't check whether
> >>>>>> .get_dev_status is NULL or not.
> >>>>>>
> >>>>>
> >>>>> I'm not quite understand your point.
> >>>>> it is used by governor_simpleondemand.c and tegra_devfreq_governor.
> >>>>> get_target_freq -> devfreq_update_stats -> get_dev_status
> >>>>
> >>>> The devfreq can add the new governor by anyone.
> >>>> So these functions like devfreq_monitor_* have to support
> >>>> the governors and also must support the governor to be added
> >>>> in the future.
> >>>
> >>> Yes, but devfreq_monitor_* is only used by polling mode, right?
> >>> The governor using it has to implement get_dev_status unless
> >>> there's an exception in the future.
> >>>
> >>> Currently this patch wants to address the issue that user can switch
> >>> to ondemand governor (polling mode) by sysfs even devices does
> >>> not support it (no get_dev_status implemented).
> >>
> >> As I commented, I'll fix this issue. If devfreq driver doesn't implement
> >> the .get_dev_status, don't show it via available_governors. I think that
> >> it is fundamental solution to fix this issue.
> >
> > Sounds good
> >
> >> So on this version,
> >> don't add the this conditional statement on this function
> >>
> >
> > Almost all this patch did is adding a checking for get_dev_status.
> > So do you mean drop this patch?
> > I wonder it's still a necessary checking to explicitly 

Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-12 Thread Dong Aisheng
On Thu, Mar 11, 2021 at 2:54 PM Chanwoo Choi  wrote:
>
> On 3/10/21 1:56 PM, Dong Aisheng wrote:
> > On Wed, Mar 10, 2021 at 11:08 AM Chanwoo Choi  wrote:
> >>
> >> On 3/10/21 11:56 AM, Dong Aisheng wrote:
> >>> On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  wrote:
> >>>>
> >>>> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> >>>>> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >>>>>> The devfreq monitor depends on the device to provide load information
> >>>>>> by .get_dev_status() to calculate the next target freq.
> >>>>>>
> >>>>>> And this will cause changing governor to simple ondemand fail
> >>>>>> if device can't support.
> >>>>>>
> >>>>>> Signed-off-by: Dong Aisheng 
> >>>>>> ---
> >>>>>>   drivers/devfreq/devfreq.c | 10 +++---
> >>>>>>   drivers/devfreq/governor.h|  2 +-
> >>>>>>   drivers/devfreq/governor_simpleondemand.c |  3 +--
> >>>>>>   3 files changed, 9 insertions(+), 6 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> >>>>>> index 7231fe6862a2..d1787b6c7d7c 100644
> >>>>>> --- a/drivers/devfreq/devfreq.c
> >>>>>> +++ b/drivers/devfreq/devfreq.c
> >>>>>> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct
> >>>>>> *work)
> >>>>>>* to be called from governor in response to DEVFREQ_GOV_START
> >>>>>>* event when device is added to devfreq framework.
> >>>>>>*/
> >>>>>> -void devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>> +int devfreq_monitor_start(struct devfreq *devfreq)
> >>>>>>   {
> >>>>>>   if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> >>>>>> -return;
> >>>>>> +return 0;
> >>>>>> +
> >>>>>> +if (!devfreq->profile->get_dev_status)
> >>>>>> +return -EINVAL;
> >>>>
> >>>> Again, I think that get_dev_status is not used for all governors.
> >>>> So that it cause the governor start fail. Don't check whether
> >>>> .get_dev_status is NULL or not.
> >>>>
> >>>
> >>> I'm not quite understand your point.
> >>> it is used by governor_simpleondemand.c and tegra_devfreq_governor.
> >>> get_target_freq -> devfreq_update_stats -> get_dev_status
> >>
> >> The devfreq can add the new governor by anyone.
> >> So these functions like devfreq_monitor_* have to support
> >> the governors and also must support the governor to be added
> >> in the future.
> >
> > Yes, but devfreq_monitor_* is only used by polling mode, right?
> > The governor using it has to implement get_dev_status unless
> > there's an exception in the future.
> >
> > Currently this patch wants to address the issue that user can switch
> > to ondemand governor (polling mode) by sysfs even devices does
> > not support it (no get_dev_status implemented).
>
> As I commented, I'll fix this issue. If devfreq driver doesn't implement
> the .get_dev_status, don't show it via available_governors. I think that
> it is fundamental solution to fix this issue.

Sounds good

> So on this version,
> don't add the this conditional statement on this function
>

Almost all this patch did is adding a checking for get_dev_status.
So do you mean drop this patch?
I wonder it's still a necessary checking to explicitly tell devfreq monitor
users that get_dev_status is needed during governor startup.

> And on next version, please use the capital letter for first character
> on patch title as following:
>
> - PM / devfreq: Check get_dev_status before start monitor
>

Okay to me.
Thanks for the suggestion.

Regards
Aisheng

> >
> > Regards
> > Aisheng
> >
> >>
> >>>
> >>> Without checking, device can switch to ondemand governor if it does not 
> >>> support.
> >>>
> >>> Am i missed something?
> >>>
> >>> Regards
> >>> Aisheng
> >>>
> >>>>>>   switch (devfreq->profile->timer) {
> >>>>>>   case DEVFREQ_TIMER_DEF

Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 11:08 AM Chanwoo Choi  wrote:
>
> On 3/10/21 11:56 AM, Dong Aisheng wrote:
> > On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  wrote:
> >>
> >> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> >>> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >>>> The devfreq monitor depends on the device to provide load information
> >>>> by .get_dev_status() to calculate the next target freq.
> >>>>
> >>>> And this will cause changing governor to simple ondemand fail
> >>>> if device can't support.
> >>>>
> >>>> Signed-off-by: Dong Aisheng 
> >>>> ---
> >>>>   drivers/devfreq/devfreq.c | 10 +++---
> >>>>   drivers/devfreq/governor.h|  2 +-
> >>>>   drivers/devfreq/governor_simpleondemand.c |  3 +--
> >>>>   3 files changed, 9 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> >>>> index 7231fe6862a2..d1787b6c7d7c 100644
> >>>> --- a/drivers/devfreq/devfreq.c
> >>>> +++ b/drivers/devfreq/devfreq.c
> >>>> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct
> >>>> *work)
> >>>>* to be called from governor in response to DEVFREQ_GOV_START
> >>>>* event when device is added to devfreq framework.
> >>>>*/
> >>>> -void devfreq_monitor_start(struct devfreq *devfreq)
> >>>> +int devfreq_monitor_start(struct devfreq *devfreq)
> >>>>   {
> >>>>   if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> >>>> -return;
> >>>> +return 0;
> >>>> +
> >>>> +if (!devfreq->profile->get_dev_status)
> >>>> +return -EINVAL;
> >>
> >> Again, I think that get_dev_status is not used for all governors.
> >> So that it cause the governor start fail. Don't check whether
> >> .get_dev_status is NULL or not.
> >>
> >
> > I'm not quite understand your point.
> > it is used by governor_simpleondemand.c and tegra_devfreq_governor.
> > get_target_freq -> devfreq_update_stats -> get_dev_status
>
> The devfreq can add the new governor by anyone.
> So these functions like devfreq_monitor_* have to support
> the governors and also must support the governor to be added
> in the future.

Yes, but devfreq_monitor_* is only used by polling mode, right?
The governor using it has to implement get_dev_status unless
there's an exception in the future.

Currently this patch wants to address the issue that user can switch
to ondemand governor (polling mode) by sysfs even devices does
not support it (no get_dev_status implemented).

Regards
Aisheng

>
> >
> > Without checking, device can switch to ondemand governor if it does not 
> > support.
> >
> > Am i missed something?
> >
> > Regards
> > Aisheng
> >
> >>>>   switch (devfreq->profile->timer) {
> >>>>   case DEVFREQ_TIMER_DEFERRABLE:
> >>>> @@ -495,12 +498,13 @@ void devfreq_monitor_start(struct devfreq *devfreq)
> >>>>   INIT_DELAYED_WORK(>work, devfreq_monitor);
> >>>>   break;
> >>>>   default:
> >>>> -return;
> >>>> +return -EINVAL;
> >>>>   }
> >>>>   if (devfreq->profile->polling_ms)
> >>>>   queue_delayed_work(devfreq_wq, >work,
> >>>>   msecs_to_jiffies(devfreq->profile->polling_ms));
> >>>> +return 0;
> >>>>   }
> >>>>   EXPORT_SYMBOL(devfreq_monitor_start);
> >>>> diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
> >>>> index 5cee3f64fe2b..31af6d072a10 100644
> >>>> --- a/drivers/devfreq/governor.h
> >>>> +++ b/drivers/devfreq/governor.h
> >>>> @@ -75,7 +75,7 @@ struct devfreq_governor {
> >>>>   unsigned int event, void *data);
> >>>>   };
> >>>> -void devfreq_monitor_start(struct devfreq *devfreq);
> >>>> +int devfreq_monitor_start(struct devfreq *devfreq);
> >>>>   void devfreq_monitor_stop(struct devfreq *devfreq);
> >>>>   void devfreq_monitor_suspend(struct devfreq *devfreq);
> >>>>   void devfreq_monitor_resume(struct devfre

Re: [PATCH 05/11] PM / devfreq: use more accurate returned new_freq as resume_freq

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 10:50 AM Chanwoo Choi  wrote:
>
> On 3/10/21 11:43 AM, Dong Aisheng wrote:
> > On Tue, Mar 9, 2021 at 11:53 PM Chanwoo Choi  wrote:
> >>
> >> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >>> Use the more accurate returned new_freq as resume_freq.
> >>> It's the same as how devfreq->previous_freq was updated.
> >>>
> >>> Signed-off-by: Dong Aisheng 
> >>> ---
> >>>   drivers/devfreq/devfreq.c | 2 +-
> >>>   1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> >>> index 6e80bf70e7b3..ce569bd9adfa 100644
> >>> --- a/drivers/devfreq/devfreq.c
> >>> +++ b/drivers/devfreq/devfreq.c
> >>> @@ -390,7 +390,7 @@ static int devfreq_set_target(struct devfreq 
> >>> *devfreq, unsigned long new_freq,
> >>>   devfreq->previous_freq = new_freq;
> >>>
> >>>   if (devfreq->suspend_freq)
> >>> - devfreq->resume_freq = cur_freq;
> >>> + devfreq->resume_freq = new_freq;
> >>>
> >>>   return err;
> >>>   }
> >>>
> >>
> >> This patch fixes the previous patch[1]. So that you need to
> >> add 'Fixes' tag as following:
> >>
> >> Fixes: 83f8ca45afbf0 ("PM / devfreq: add support for suspend/resume of a
> >> devfreq device")
> >>
> >
> > Will add Fixes tag in next version.
>
>
> On next version, recommend to place this patch at the first.

Yes, good practice as it's a fix.

Regards
Aisheng

>
> >
> >> commit 83f8ca45afbf041e312909f442128b99657d90b7
> >> Refs: v4.20-rc6-2-g83f8ca45afbf
> >> Author: Lukasz Luba 
> >> AuthorDate: Wed Dec 5 12:05:53 2018 +0100
> >> Commit: MyungJoo Ham 
> >> CommitDate: Tue Dec 11 11:09:47 2018 +0900
> >>
> >>  PM / devfreq: add support for suspend/resume of a devfreq device
> >>
> >>
> >> --
> >> Best Regards,
> >> Samsung Electronics
> >> Chanwoo Choi
> >
> >
>
>
> --
> Best Regards,
> Chanwoo Choi
> Samsung Electronics


Re: [PATCH 11/11] PM / devfreq: imx8m-ddrc: drop polling_ms

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 12:23 AM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > polling_ms is only used by simple ondemand governor which
> > this driver can't support. Drop it to avoid confusing.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/imx8m-ddrc.c | 1 -
> >   1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
> > index 0a6b7a1c829d..ecb9375aa877 100644
> > --- a/drivers/devfreq/imx8m-ddrc.c
> > +++ b/drivers/devfreq/imx8m-ddrc.c
> > @@ -417,7 +417,6 @@ static int imx8m_ddrc_probe(struct platform_device 
> > *pdev)
> >   if (ret < 0)
> >   goto err;
> >
> > - priv->profile.polling_ms = 1000;
> >   priv->profile.target = imx8m_ddrc_target;
> >   priv->profile.exit = imx8m_ddrc_exit;
> >   priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
> >
>
> You can squash this patch with patch10 because polling_ms
> is related to .get_dev_status.

Sure i can do it.

Regards
Aisheng

>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 09/11] PM / devfreq: governor: optimize simpleondemand get_target_freq

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 12:09 AM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > devfreq_simple_ondemand_data only needs to be initialized once when
> > calling devm_devfreq_add_device. It's unnecessary to put the data
> > check logic in the hot path (.get_target_freq()) where it will be
> > called all the time during polling. Instead, we only check and initialize
> > it one time during DEVFREQ_GOV_START.
> >
> > This also helps check data validability in advance during DEVFREQ_GOV_START
> > rather than checking it later when running .get_target_freq().
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/governor_simpleondemand.c | 50 +++
> >   1 file changed, 34 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/devfreq/governor_simpleondemand.c 
> > b/drivers/devfreq/governor_simpleondemand.c
> > index ea287b57cbf3..341eb7e9dc04 100644
> > --- a/drivers/devfreq/governor_simpleondemand.c
> > +++ b/drivers/devfreq/governor_simpleondemand.c
> > @@ -15,15 +15,19 @@
> >   /* Default constants for DevFreq-Simple-Ondemand (DFSO) */
> >   #define DFSO_UPTHRESHOLD(90)
> >   #define DFSO_DOWNDIFFERENCTIAL  (5)
> > +
> > +static struct devfreq_simple_ondemand_data od_default = {
> > + .upthreshold = DFSO_UPTHRESHOLD,
> > + .downdifferential = DFSO_DOWNDIFFERENCTIAL,
> > +};
> > +
> >   static int devfreq_simple_ondemand_func(struct devfreq *df,
> >   unsigned long *freq)
> >   {
> >   int err;
> >   struct devfreq_dev_status *stat;
> >   unsigned long long a, b;
> > - unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
> > - unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
> > - struct devfreq_simple_ondemand_data *data = df->data;
> > + struct devfreq_simple_ondemand_data *od = df->data;
> >
> >   err = devfreq_update_stats(df);
> >   if (err)
> > @@ -31,16 +35,6 @@ static int devfreq_simple_ondemand_func(struct devfreq 
> > *df,
> >
> >   stat = >last_status;
> >
> > - if (data) {
> > - if (data->upthreshold)
> > - dfso_upthreshold = data->upthreshold;
> > - if (data->downdifferential)
> > - dfso_downdifferential = data->downdifferential;
> > - }
> > - if (dfso_upthreshold > 100 ||
> > - dfso_upthreshold < dfso_downdifferential)
> > - return -EINVAL;
> > -
> >   /* Assume MAX if it is going to be divided by zero */
> >   if (stat->total_time == 0) {
> >   *freq = DEVFREQ_MAX_FREQ;
> > @@ -55,7 +49,7 @@ static int devfreq_simple_ondemand_func(struct devfreq 
> > *df,
> >
> >   /* Set MAX if it's busy enough */
> >   if (stat->busy_time * 100 >
> > - stat->total_time * dfso_upthreshold) {
> > + stat->total_time * od->upthreshold) {
> >   *freq = DEVFREQ_MAX_FREQ;
> >   return 0;
> >   }
> > @@ -68,7 +62,7 @@ static int devfreq_simple_ondemand_func(struct devfreq 
> > *df,
> >
> >   /* Keep the current frequency */
> >   if (stat->busy_time * 100 >
> > - stat->total_time * (dfso_upthreshold - dfso_downdifferential)) {
> > + stat->total_time * (od->upthreshold - od->downdifferential)) {
> >   *freq = stat->current_frequency;
> >   return 0;
> >   }
> > @@ -78,17 +72,41 @@ static int devfreq_simple_ondemand_func(struct devfreq 
> > *df,
> >   a *= stat->current_frequency;
> >   b = div_u64(a, stat->total_time);
> >   b *= 100;
> > - b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
> > + b = div_u64(b, (od->upthreshold - od->downdifferential / 2));
> >   *freq = (unsigned long) b;
> >
> >   return 0;
> >   }
> >
> > +static int devfreq_simple_ondemand_check_od(struct devfreq *devfreq)
> > +{
> > + struct devfreq_simple_ondemand_data *od = devfreq->data;
> > +
> > + if (od) {
> > + if (!od->upthreshold)
> > + od->upthreshold = DFSO_UPTHRESHOLD;
> > +
> > + if (!od->downdifferential)
> > + od->downdifferential = DFSO_DOWNDIFFERENCTIAL;
> > +
> > + if (od->upthreshold > 100 ||
> > +   

Re: [PATCH 08/11] PM / devfreq: check get_dev_status in devfreq_update_stats

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 12:20 AM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > Check .get_dev_status() in devfreq_update_stats in case it's abused
> > when a device does not provide it.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/governor.h | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
> > index 31af6d072a10..67a6dbdd5d23 100644
> > --- a/drivers/devfreq/governor.h
> > +++ b/drivers/devfreq/governor.h
> > @@ -89,6 +89,9 @@ int devfreq_update_target(struct devfreq *devfreq, 
> > unsigned long freq);
> >
> >   static inline int devfreq_update_stats(struct devfreq *df)
> >   {
> > + if (!df->profile->get_dev_status)
> > + return -EINVAL;
> > +
>
> I'm considering the following method instead of returning the error
> when .get_dev_status is NULL.
>
> if (!df->profile->get_dev_status) {
> df->last_status.total_time = 0;
> df->last_status.busy_time = 0;
> df->last_status.current_frequency = 0;
> return 0;
> }

I might  suggest not cause it's meaningless for ondemand governor but
introducing confusing. Simply return error could make the life a bit easier.
does it make sense to you?

Regards
Aisheng

>
> >   return df->profile->get_dev_status(df->dev.parent, >last_status);
> >   }
> >   #endif /* _GOVERNOR_H */
> >
>
>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-09 Thread Dong Aisheng
On Wed, Mar 10, 2021 at 12:12 AM Chanwoo Choi  wrote:
>
> On 21. 3. 10. 오전 12:58, Chanwoo Choi wrote:
> > On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> >> The devfreq monitor depends on the device to provide load information
> >> by .get_dev_status() to calculate the next target freq.
> >>
> >> And this will cause changing governor to simple ondemand fail
> >> if device can't support.
> >>
> >> Signed-off-by: Dong Aisheng 
> >> ---
> >>   drivers/devfreq/devfreq.c | 10 +++---
> >>   drivers/devfreq/governor.h|  2 +-
> >>   drivers/devfreq/governor_simpleondemand.c |  3 +--
> >>   3 files changed, 9 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> >> index 7231fe6862a2..d1787b6c7d7c 100644
> >> --- a/drivers/devfreq/devfreq.c
> >> +++ b/drivers/devfreq/devfreq.c
> >> @@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct
> >> *work)
> >>* to be called from governor in response to DEVFREQ_GOV_START
> >>* event when device is added to devfreq framework.
> >>*/
> >> -void devfreq_monitor_start(struct devfreq *devfreq)
> >> +int devfreq_monitor_start(struct devfreq *devfreq)
> >>   {
> >>   if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> >> -return;
> >> +return 0;
> >> +
> >> +if (!devfreq->profile->get_dev_status)
> >> +return -EINVAL;
>
> Again, I think that get_dev_status is not used for all governors.
> So that it cause the governor start fail. Don't check whether
> .get_dev_status is NULL or not.
>

I'm not quite understand your point.
it is used by governor_simpleondemand.c and tegra_devfreq_governor.
get_target_freq -> devfreq_update_stats -> get_dev_status

Without checking, device can switch to ondemand governor if it does not support.

Am i missed something?

Regards
Aisheng

> >>   switch (devfreq->profile->timer) {
> >>   case DEVFREQ_TIMER_DEFERRABLE:
> >> @@ -495,12 +498,13 @@ void devfreq_monitor_start(struct devfreq *devfreq)
> >>   INIT_DELAYED_WORK(>work, devfreq_monitor);
> >>   break;
> >>   default:
> >> -return;
> >> +return -EINVAL;
> >>   }
> >>   if (devfreq->profile->polling_ms)
> >>   queue_delayed_work(devfreq_wq, >work,
> >>   msecs_to_jiffies(devfreq->profile->polling_ms));
> >> +return 0;
> >>   }
> >>   EXPORT_SYMBOL(devfreq_monitor_start);
> >> diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
> >> index 5cee3f64fe2b..31af6d072a10 100644
> >> --- a/drivers/devfreq/governor.h
> >> +++ b/drivers/devfreq/governor.h
> >> @@ -75,7 +75,7 @@ struct devfreq_governor {
> >>   unsigned int event, void *data);
> >>   };
> >> -void devfreq_monitor_start(struct devfreq *devfreq);
> >> +int devfreq_monitor_start(struct devfreq *devfreq);
> >>   void devfreq_monitor_stop(struct devfreq *devfreq);
> >>   void devfreq_monitor_suspend(struct devfreq *devfreq);
> >>   void devfreq_monitor_resume(struct devfreq *devfreq);
> >> diff --git a/drivers/devfreq/governor_simpleondemand.c
> >> b/drivers/devfreq/governor_simpleondemand.c
> >> index d57b82a2b570..ea287b57cbf3 100644
> >> --- a/drivers/devfreq/governor_simpleondemand.c
> >> +++ b/drivers/devfreq/governor_simpleondemand.c
> >> @@ -89,8 +89,7 @@ static int devfreq_simple_ondemand_handler(struct
> >> devfreq *devfreq,
> >>   {
> >>   switch (event) {
> >>   case DEVFREQ_GOV_START:
> >> -devfreq_monitor_start(devfreq);
> >> -break;
> >> +return devfreq_monitor_start(devfreq);
> >>   case DEVFREQ_GOV_STOP:
> >>   devfreq_monitor_stop(devfreq);
> >>
> >
> > Need to handle the all points of devfreq_monitor_start() usage.
> > please check the tegra30-devfreq.c for this update.
> >
> > $ grep -rn "devfreq_monitor_start" drivers/
> > drivers/devfreq/governor_simpleondemand.c:92:
> > devfreq_monitor_start(devfreq);
> > drivers/devfreq/tegra30-devfreq.c:744:
> > devfreq_monitor_start(devfreq);
> > ..
> >
>
>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-09 Thread Dong Aisheng
On Tue, Mar 9, 2021 at 11:58 PM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > The devfreq monitor depends on the device to provide load information
> > by .get_dev_status() to calculate the next target freq.
> >
> > And this will cause changing governor to simple ondemand fail
> > if device can't support.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/devfreq.c | 10 +++---
> >   drivers/devfreq/governor.h|  2 +-
> >   drivers/devfreq/governor_simpleondemand.c |  3 +--
> >   3 files changed, 9 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > index 7231fe6862a2..d1787b6c7d7c 100644
> > --- a/drivers/devfreq/devfreq.c
> > +++ b/drivers/devfreq/devfreq.c
> > @@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct *work)
> >* to be called from governor in response to DEVFREQ_GOV_START
> >* event when device is added to devfreq framework.
> >*/
> > -void devfreq_monitor_start(struct devfreq *devfreq)
> > +int devfreq_monitor_start(struct devfreq *devfreq)
> >   {
> >   if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
> > - return;
> > + return 0;
> > +
> > + if (!devfreq->profile->get_dev_status)
> > + return -EINVAL;
> >
> >   switch (devfreq->profile->timer) {
> >   case DEVFREQ_TIMER_DEFERRABLE:
> > @@ -495,12 +498,13 @@ void devfreq_monitor_start(struct devfreq *devfreq)
> >   INIT_DELAYED_WORK(>work, devfreq_monitor);
> >   break;
> >   default:
> > - return;
> > + return -EINVAL;
> >   }
> >
> >   if (devfreq->profile->polling_ms)
> >   queue_delayed_work(devfreq_wq, >work,
> >   msecs_to_jiffies(devfreq->profile->polling_ms));
> > + return 0;
> >   }
> >   EXPORT_SYMBOL(devfreq_monitor_start);
> >
> > diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
> > index 5cee3f64fe2b..31af6d072a10 100644
> > --- a/drivers/devfreq/governor.h
> > +++ b/drivers/devfreq/governor.h
> > @@ -75,7 +75,7 @@ struct devfreq_governor {
> >   unsigned int event, void *data);
> >   };
> >
> > -void devfreq_monitor_start(struct devfreq *devfreq);
> > +int devfreq_monitor_start(struct devfreq *devfreq);
> >   void devfreq_monitor_stop(struct devfreq *devfreq);
> >   void devfreq_monitor_suspend(struct devfreq *devfreq);
> >   void devfreq_monitor_resume(struct devfreq *devfreq);
> > diff --git a/drivers/devfreq/governor_simpleondemand.c 
> > b/drivers/devfreq/governor_simpleondemand.c
> > index d57b82a2b570..ea287b57cbf3 100644
> > --- a/drivers/devfreq/governor_simpleondemand.c
> > +++ b/drivers/devfreq/governor_simpleondemand.c
> > @@ -89,8 +89,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq 
> > *devfreq,
> >   {
> >   switch (event) {
> >   case DEVFREQ_GOV_START:
> > - devfreq_monitor_start(devfreq);
> > - break;
> > + return devfreq_monitor_start(devfreq);
> >
> >   case DEVFREQ_GOV_STOP:
> >   devfreq_monitor_stop(devfreq);
> >
>
> Need to handle the all points of devfreq_monitor_start() usage.
> please check the tegra30-devfreq.c for this update.
>
> $ grep -rn "devfreq_monitor_start" drivers/
> drivers/devfreq/governor_simpleondemand.c:92:
> devfreq_monitor_start(devfreq);
> drivers/devfreq/tegra30-devfreq.c:744:  
> devfreq_monitor_start(devfreq);

I can add error check for tegra in the next versions.
Thanks

Regards
Aisheng

> ..
>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 05/11] PM / devfreq: use more accurate returned new_freq as resume_freq

2021-03-09 Thread Dong Aisheng
On Tue, Mar 9, 2021 at 11:53 PM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > Use the more accurate returned new_freq as resume_freq.
> > It's the same as how devfreq->previous_freq was updated.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/devfreq.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > index 6e80bf70e7b3..ce569bd9adfa 100644
> > --- a/drivers/devfreq/devfreq.c
> > +++ b/drivers/devfreq/devfreq.c
> > @@ -390,7 +390,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
> > unsigned long new_freq,
> >   devfreq->previous_freq = new_freq;
> >
> >   if (devfreq->suspend_freq)
> > - devfreq->resume_freq = cur_freq;
> > + devfreq->resume_freq = new_freq;
> >
> >   return err;
> >   }
> >
>
> This patch fixes the previous patch[1]. So that you need to
> add 'Fixes' tag as following:
>
> Fixes: 83f8ca45afbf0 ("PM / devfreq: add support for suspend/resume of a
> devfreq device")
>

Will add Fixes tag in next version.

> commit 83f8ca45afbf041e312909f442128b99657d90b7
> Refs: v4.20-rc6-2-g83f8ca45afbf
> Author: Lukasz Luba 
> AuthorDate: Wed Dec 5 12:05:53 2018 +0100
> Commit: MyungJoo Ham 
> CommitDate: Tue Dec 11 11:09:47 2018 +0900
>
>  PM / devfreq: add support for suspend/resume of a devfreq device
>
>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 04/11] PM / devfreq: bail out early if no freq changes in devfreq_set_target

2021-03-09 Thread Dong Aisheng
On Tue, Mar 9, 2021 at 11:47 PM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > It's unnecessary to set the same freq again and run notifier calls.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/devfreq.c | 5 -
> >   1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > index bf3047896e41..6e80bf70e7b3 100644
> > --- a/drivers/devfreq/devfreq.c
> > +++ b/drivers/devfreq/devfreq.c
> > @@ -358,6 +358,9 @@ static int devfreq_set_target(struct devfreq *devfreq, 
> > unsigned long new_freq,
> >   else
> >   cur_freq = devfreq->previous_freq;
> >
> > + if (new_freq == cur_freq)
> > + return 0;
> > +
> >   freqs.old = cur_freq;
> >   freqs.new = new_freq;
> >   devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);
> > @@ -374,7 +377,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
> > unsigned long new_freq,
> >* and DEVFREQ_POSTCHANGE because for showing the correct frequency
> >* change order of between devfreq device and passive devfreq device.
> >*/
> > - if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
> > + if (trace_devfreq_frequency_enabled())
> >   trace_devfreq_frequency(devfreq, new_freq, cur_freq);
> >
> >   freqs.new = new_freq;
> >
>
> I'd like you to squash patch4 with patch6 because actually patch6
> is too minor clean-up. I think it is possible.

Got it, will squash when re-send.

Regards
Aisheng

>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 03/11] PM / devfreq: fix the wrong set_freq path for userspace governor

2021-03-09 Thread Dong Aisheng
On Tue, Mar 9, 2021 at 11:13 PM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > Fix the wrong set_freq path for userspace governor.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/Kconfig | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> > index 00704efe6398..20373a893b44 100644
> > --- a/drivers/devfreq/Kconfig
> > +++ b/drivers/devfreq/Kconfig
> > @@ -62,7 +62,7 @@ config DEVFREQ_GOV_USERSPACE
> >   help
> > Sets the frequency at the user specified one.
> > This governor returns the user configured frequency if there
> > -   has been an input to /sys/devices/.../power/devfreq_set_freq.
> > +   has been an input to /sys/devices/.../userspace/set_freq.
> > Otherwise, the governor does not change the frequency
> > given at the initialization.
> >
> >
>
> Looks good. But this patch just fix the information in Kconfig
> instead of fixing the wrong operation. To clarify the commit message,
> I'll change the patch title and commit message as following:

Looks like more accurate. Thanks.

Regards
Aisheng

>
>  PM / devfreq: Fix the wrong set_freq path for userspace governor in
> Kconfig
>
>  Fix the wrong set_freq path for userspace governor in Kconfig.
>
>  Signed-off-by: Dong Aisheng 
>
>
> Applied it. But, if you have any other objection, please let me know.
>
>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [PATCH 02/11] PM / devfreq: remove the invalid description for get_target_freq

2021-03-09 Thread Dong Aisheng
On Tue, Mar 9, 2021 at 11:02 PM Chanwoo Choi  wrote:
>
> On 21. 3. 9. 오후 9:58, Dong Aisheng wrote:
> > First of all, no_central_polling was removed since
> > commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
> > which can idle")
> > Secondly, get_target_freq() is not only called only with update_devfreq()
> > notified by OPP now, but also min/max freq qos notifier.
> >
> > So remove this invalid description now to avoid confusing.
> >
> > Signed-off-by: Dong Aisheng 
> > ---
> >   drivers/devfreq/governor.h | 2 --
> >   1 file changed, 2 deletions(-)
> >
> > diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
> > index 70f44b3ca42e..5cee3f64fe2b 100644
> > --- a/drivers/devfreq/governor.h
> > +++ b/drivers/devfreq/governor.h
> > @@ -57,8 +57,6 @@
> >*  Basically, get_target_freq will run
> >*  devfreq_dev_profile.get_dev_status() to get the
> >*  status of the device (load = busy_time / total_time).
> > - *   If no_central_polling is set, this callback is called
> > - *   only with update_devfreq() notified by OPP.
> >* @event_handler:  Callback for devfreq core framework to notify 
> > events
> >*  to governors. Events include per device governor
> >*  init and exit, opp changes out of devfreq, suspend
> >
>
> As I replied from patch1, I recommend that squash it with patch1.

Got it, i will squash when sending the next version.
Thanks

Regards
Aisheng

>
> --
> Best Regards,
> Samsung Electronics
> Chanwoo Choi


Re: [RFC 05/19] devfreq: imx8m-ddrc: Change governor to powersave

2021-03-09 Thread Dong Aisheng
On Sat, Feb 20, 2021 at 12:03 AM Abel Vesa  wrote:
>
> By switching to powersave governor, we allow the imx8m-ddrc to always
> run at minimum rate needed by all the running masters.
>
> Signed-off-by: Abel Vesa 

Would you please help clarify a bit more why need use powersave by default?

Regards
Aisheng

> ---
>  drivers/devfreq/imx8m-ddrc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
> index bc82d3653bff..3a6c04ba4f2e 100644
> --- a/drivers/devfreq/imx8m-ddrc.c
> +++ b/drivers/devfreq/imx8m-ddrc.c
> @@ -379,7 +379,7 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
>  {
> struct device *dev = >dev;
> struct imx8m_ddrc *priv;
> -   const char *gov = DEVFREQ_GOV_USERSPACE;
> +   const char *gov = DEVFREQ_GOV_POWERSAVE;
> int ret;
>
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> --
> 2.29.2
>


[PATCH 11/11] PM / devfreq: imx8m-ddrc: drop polling_ms

2021-03-09 Thread Dong Aisheng
polling_ms is only used by simple ondemand governor which
this driver can't support. Drop it to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index 0a6b7a1c829d..ecb9375aa877 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -417,7 +417,6 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
 
-   priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
-- 
2.25.1



[PATCH 06/11] PM / devfreq: drop the unnecessary low variable initialization

2021-03-09 Thread Dong Aisheng
drop the unnecessary low variable initialization and make the return
more straightforward.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index ce569bd9adfa..7231fe6862a2 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -351,7 +351,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 {
struct devfreq_freqs freqs;
unsigned long cur_freq;
-   int err = 0;
+   int err;
 
if (devfreq->profile->get_cur_freq)
devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq);
@@ -392,7 +392,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
if (devfreq->suspend_freq)
devfreq->resume_freq = new_freq;
 
-   return err;
+   return 0;
 }
 
 /**
-- 
2.25.1



[PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-09 Thread Dong Aisheng
The devfreq monitor depends on the device to provide load information
by .get_dev_status() to calculate the next target freq.

And this will cause changing governor to simple ondemand fail
if device can't support.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 10 +++---
 drivers/devfreq/governor.h|  2 +-
 drivers/devfreq/governor_simpleondemand.c |  3 +--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 7231fe6862a2..d1787b6c7d7c 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct *work)
  * to be called from governor in response to DEVFREQ_GOV_START
  * event when device is added to devfreq framework.
  */
-void devfreq_monitor_start(struct devfreq *devfreq)
+int devfreq_monitor_start(struct devfreq *devfreq)
 {
if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
-   return;
+   return 0;
+
+   if (!devfreq->profile->get_dev_status)
+   return -EINVAL;
 
switch (devfreq->profile->timer) {
case DEVFREQ_TIMER_DEFERRABLE:
@@ -495,12 +498,13 @@ void devfreq_monitor_start(struct devfreq *devfreq)
INIT_DELAYED_WORK(>work, devfreq_monitor);
break;
default:
-   return;
+   return -EINVAL;
}
 
if (devfreq->profile->polling_ms)
queue_delayed_work(devfreq_wq, >work,
msecs_to_jiffies(devfreq->profile->polling_ms));
+   return 0;
 }
 EXPORT_SYMBOL(devfreq_monitor_start);
 
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 5cee3f64fe2b..31af6d072a10 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -75,7 +75,7 @@ struct devfreq_governor {
unsigned int event, void *data);
 };
 
-void devfreq_monitor_start(struct devfreq *devfreq);
+int devfreq_monitor_start(struct devfreq *devfreq);
 void devfreq_monitor_stop(struct devfreq *devfreq);
 void devfreq_monitor_suspend(struct devfreq *devfreq);
 void devfreq_monitor_resume(struct devfreq *devfreq);
diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index d57b82a2b570..ea287b57cbf3 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -89,8 +89,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq 
*devfreq,
 {
switch (event) {
case DEVFREQ_GOV_START:
-   devfreq_monitor_start(devfreq);
-   break;
+   return devfreq_monitor_start(devfreq);
 
case DEVFREQ_GOV_STOP:
devfreq_monitor_stop(devfreq);
-- 
2.25.1



[PATCH 08/11] PM / devfreq: check get_dev_status in devfreq_update_stats

2021-03-09 Thread Dong Aisheng
Check .get_dev_status() in devfreq_update_stats in case it's abused
when a device does not provide it.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 31af6d072a10..67a6dbdd5d23 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -89,6 +89,9 @@ int devfreq_update_target(struct devfreq *devfreq, unsigned 
long freq);
 
 static inline int devfreq_update_stats(struct devfreq *df)
 {
+   if (!df->profile->get_dev_status)
+   return -EINVAL;
+
return df->profile->get_dev_status(df->dev.parent, >last_status);
 }
 #endif /* _GOVERNOR_H */
-- 
2.25.1



[PATCH 09/11] PM / devfreq: governor: optimize simpleondemand get_target_freq

2021-03-09 Thread Dong Aisheng
devfreq_simple_ondemand_data only needs to be initialized once when
calling devm_devfreq_add_device. It's unnecessary to put the data
check logic in the hot path (.get_target_freq()) where it will be
called all the time during polling. Instead, we only check and initialize
it one time during DEVFREQ_GOV_START.

This also helps check data validability in advance during DEVFREQ_GOV_START
rather than checking it later when running .get_target_freq().

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor_simpleondemand.c | 50 +++
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index ea287b57cbf3..341eb7e9dc04 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -15,15 +15,19 @@
 /* Default constants for DevFreq-Simple-Ondemand (DFSO) */
 #define DFSO_UPTHRESHOLD   (90)
 #define DFSO_DOWNDIFFERENCTIAL (5)
+
+static struct devfreq_simple_ondemand_data od_default = {
+   .upthreshold = DFSO_UPTHRESHOLD,
+   .downdifferential = DFSO_DOWNDIFFERENCTIAL,
+};
+
 static int devfreq_simple_ondemand_func(struct devfreq *df,
unsigned long *freq)
 {
int err;
struct devfreq_dev_status *stat;
unsigned long long a, b;
-   unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
-   unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
-   struct devfreq_simple_ondemand_data *data = df->data;
+   struct devfreq_simple_ondemand_data *od = df->data;
 
err = devfreq_update_stats(df);
if (err)
@@ -31,16 +35,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
stat = >last_status;
 
-   if (data) {
-   if (data->upthreshold)
-   dfso_upthreshold = data->upthreshold;
-   if (data->downdifferential)
-   dfso_downdifferential = data->downdifferential;
-   }
-   if (dfso_upthreshold > 100 ||
-   dfso_upthreshold < dfso_downdifferential)
-   return -EINVAL;
-
/* Assume MAX if it is going to be divided by zero */
if (stat->total_time == 0) {
*freq = DEVFREQ_MAX_FREQ;
@@ -55,7 +49,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
/* Set MAX if it's busy enough */
if (stat->busy_time * 100 >
-   stat->total_time * dfso_upthreshold) {
+   stat->total_time * od->upthreshold) {
*freq = DEVFREQ_MAX_FREQ;
return 0;
}
@@ -68,7 +62,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
/* Keep the current frequency */
if (stat->busy_time * 100 >
-   stat->total_time * (dfso_upthreshold - dfso_downdifferential)) {
+   stat->total_time * (od->upthreshold - od->downdifferential)) {
*freq = stat->current_frequency;
return 0;
}
@@ -78,17 +72,41 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
a *= stat->current_frequency;
b = div_u64(a, stat->total_time);
b *= 100;
-   b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
+   b = div_u64(b, (od->upthreshold - od->downdifferential / 2));
*freq = (unsigned long) b;
 
return 0;
 }
 
+static int devfreq_simple_ondemand_check_od(struct devfreq *devfreq)
+{
+   struct devfreq_simple_ondemand_data *od = devfreq->data;
+
+   if (od) {
+   if (!od->upthreshold)
+   od->upthreshold = DFSO_UPTHRESHOLD;
+
+   if (!od->downdifferential)
+   od->downdifferential = DFSO_DOWNDIFFERENCTIAL;
+
+   if (od->upthreshold > 100 ||
+   od->upthreshold < od->downdifferential)
+   return -EINVAL;
+   } else {
+   od = _default;
+   }
+
+   return 0;
+}
+
 static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
unsigned int event, void *data)
 {
switch (event) {
case DEVFREQ_GOV_START:
+   if (devfreq_simple_ondemand_check_od(devfreq))
+   return -EINVAL;
+
return devfreq_monitor_start(devfreq);
 
case DEVFREQ_GOV_STOP:
-- 
2.25.1



[PATCH 10/11] PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

2021-03-09 Thread Dong Aisheng
Current driver actually does not support simple ondemand governor
as it's unable to provide device load information. So removing
the unnecessary callback to avoid confusing.
Right now the driver is using userspace governor by default.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index bc82d3653bff..0a6b7a1c829d 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -280,18 +280,6 @@ static int imx8m_ddrc_get_cur_freq(struct device *dev, 
unsigned long *freq)
return 0;
 }
 
-static int imx8m_ddrc_get_dev_status(struct device *dev,
-struct devfreq_dev_status *stat)
-{
-   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
-
-   stat->busy_time = 0;
-   stat->total_time = 0;
-   stat->current_frequency = clk_get_rate(priv->dram_core);
-
-   return 0;
-}
-
 static int imx8m_ddrc_init_freq_info(struct device *dev)
 {
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -431,7 +419,6 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
 
priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
-   priv->profile.get_dev_status = imx8m_ddrc_get_dev_status;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
priv->profile.initial_freq = clk_get_rate(priv->dram_core);
-- 
2.25.1



[PATCH 05/11] PM / devfreq: use more accurate returned new_freq as resume_freq

2021-03-09 Thread Dong Aisheng
Use the more accurate returned new_freq as resume_freq.
It's the same as how devfreq->previous_freq was updated.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 6e80bf70e7b3..ce569bd9adfa 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -390,7 +390,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
devfreq->previous_freq = new_freq;
 
if (devfreq->suspend_freq)
-   devfreq->resume_freq = cur_freq;
+   devfreq->resume_freq = new_freq;
 
return err;
 }
-- 
2.25.1



[PATCH 04/11] PM / devfreq: bail out early if no freq changes in devfreq_set_target

2021-03-09 Thread Dong Aisheng
It's unnecessary to set the same freq again and run notifier calls.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3047896e41..6e80bf70e7b3 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -358,6 +358,9 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
else
cur_freq = devfreq->previous_freq;
 
+   if (new_freq == cur_freq)
+   return 0;
+
freqs.old = cur_freq;
freqs.new = new_freq;
devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);
@@ -374,7 +377,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 * and DEVFREQ_POSTCHANGE because for showing the correct frequency
 * change order of between devfreq device and passive devfreq device.
 */
-   if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
+   if (trace_devfreq_frequency_enabled())
trace_devfreq_frequency(devfreq, new_freq, cur_freq);
 
freqs.new = new_freq;
-- 
2.25.1



[PATCH 11/11] PM / devfreq: imx8m-ddrc: drop polling_ms

2021-03-09 Thread Dong Aisheng
polling_ms is only used by simple ondemand governor which
this driver can't support. Drop it to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index 0a6b7a1c829d..ecb9375aa877 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -417,7 +417,6 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
 
-   priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
-- 
2.25.1



[PATCH 01/11] doc: ABI: devfreq: remove invalid central_polling description

2021-03-09 Thread Dong Aisheng
no_central_polling has been removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")

Signed-off-by: Dong Aisheng 
---
 Documentation/ABI/testing/sysfs-class-devfreq | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-devfreq 
b/Documentation/ABI/testing/sysfs-class-devfreq
index 386bc230a33d..5e6b74f30406 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -97,10 +97,7 @@ Description:
object. The values are represented in ms. If the value is
less than 1 jiffy, it is considered to be 0, which means
no polling. This value is meaningless if the governor is
-   not polling; thus. If the governor is not using
-   devfreq-provided central polling
-   (/sys/class/devfreq/.../central_polling is 0), this value
-   may be useless.
+   not polling.
 
A list of governors that support the node:
- simple_ondmenad
-- 
2.25.1



[PATCH 02/11] PM / devfreq: remove the invalid description for get_target_freq

2021-03-09 Thread Dong Aisheng
First of all, no_central_polling was removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")
Secondly, get_target_freq() is not only called only with update_devfreq()
notified by OPP now, but also min/max freq qos notifier.

So remove this invalid description now to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 70f44b3ca42e..5cee3f64fe2b 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -57,8 +57,6 @@
  * Basically, get_target_freq will run
  * devfreq_dev_profile.get_dev_status() to get the
  * status of the device (load = busy_time / total_time).
- * If no_central_polling is set, this callback is called
- * only with update_devfreq() notified by OPP.
  * @event_handler:  Callback for devfreq core framework to notify events
  *  to governors. Events include per device governor
  *  init and exit, opp changes out of devfreq, suspend
-- 
2.25.1



[PATCH 00/11] PM / devfreq: a few small fixes and improvements

2021-03-09 Thread Dong Aisheng
A few small fixes and improvements

Dong Aisheng (11):
  doc: ABI: devfreq: remove invalid central_polling description
  PM / devfreq: remove the invalid description for get_target_freq
  PM / devfreq: fix the wrong set_freq path for userspace governor
  PM / devfreq: bail out early if no freq changes in devfreq_set_target
  PM / devfreq: use more accurate returned new_freq as resume_freq
  PM / devfreq: drop the unnecessary low variable initialization
  PM / devfreq: check get_dev_status before start monitor
  PM / devfreq: check get_dev_status in devfreq_update_stats
  PM / devfreq: governor: optimize simpleondemand get_target_freq
  PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status
  PM / devfreq: imx8m-ddrc: drop polling_ms

 Documentation/ABI/testing/sysfs-class-devfreq |  5 +-
 drivers/devfreq/Kconfig   |  2 +-
 drivers/devfreq/devfreq.c | 21 +---
 drivers/devfreq/governor.h|  7 +--
 drivers/devfreq/governor_simpleondemand.c | 53 ---
 drivers/devfreq/imx8m-ddrc.c  | 14 -
 6 files changed, 55 insertions(+), 47 deletions(-)

-- 
2.25.1



[PATCH 03/11] PM / devfreq: fix the wrong set_freq path for userspace governor

2021-03-09 Thread Dong Aisheng
Fix the wrong set_freq path for userspace governor.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 00704efe6398..20373a893b44 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -62,7 +62,7 @@ config DEVFREQ_GOV_USERSPACE
help
  Sets the frequency at the user specified one.
  This governor returns the user configured frequency if there
- has been an input to /sys/devices/.../power/devfreq_set_freq.
+ has been an input to /sys/devices/.../userspace/set_freq.
  Otherwise, the governor does not change the frequency
  given at the initialization.
 
-- 
2.25.1



[PATCH 10/11] PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status

2021-03-09 Thread Dong Aisheng
Current driver actually does not support simple ondemand governor
as it's unable to provide device load information. So removing
the unnecessary callback to avoid confusing.
Right now the driver is using userspace governor by default.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/imx8m-ddrc.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index bc82d3653bff..0a6b7a1c829d 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -280,18 +280,6 @@ static int imx8m_ddrc_get_cur_freq(struct device *dev, 
unsigned long *freq)
return 0;
 }
 
-static int imx8m_ddrc_get_dev_status(struct device *dev,
-struct devfreq_dev_status *stat)
-{
-   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
-
-   stat->busy_time = 0;
-   stat->total_time = 0;
-   stat->current_frequency = clk_get_rate(priv->dram_core);
-
-   return 0;
-}
-
 static int imx8m_ddrc_init_freq_info(struct device *dev)
 {
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -431,7 +419,6 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
 
priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
-   priv->profile.get_dev_status = imx8m_ddrc_get_dev_status;
priv->profile.exit = imx8m_ddrc_exit;
priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
priv->profile.initial_freq = clk_get_rate(priv->dram_core);
-- 
2.25.1



[PATCH 08/11] PM / devfreq: check get_dev_status in devfreq_update_stats

2021-03-09 Thread Dong Aisheng
Check .get_dev_status() in devfreq_update_stats in case it's abused
when a device does not provide it.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 31af6d072a10..67a6dbdd5d23 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -89,6 +89,9 @@ int devfreq_update_target(struct devfreq *devfreq, unsigned 
long freq);
 
 static inline int devfreq_update_stats(struct devfreq *df)
 {
+   if (!df->profile->get_dev_status)
+   return -EINVAL;
+
return df->profile->get_dev_status(df->dev.parent, >last_status);
 }
 #endif /* _GOVERNOR_H */
-- 
2.25.1



[PATCH 07/11] PM / devfreq: check get_dev_status before start monitor

2021-03-09 Thread Dong Aisheng
The devfreq monitor depends on the device to provide load information
by .get_dev_status() to calculate the next target freq.

And this will cause changing governor to simple ondemand fail
if device can't support.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 10 +++---
 drivers/devfreq/governor.h|  2 +-
 drivers/devfreq/governor_simpleondemand.c |  3 +--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 7231fe6862a2..d1787b6c7d7c 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -482,10 +482,13 @@ static void devfreq_monitor(struct work_struct *work)
  * to be called from governor in response to DEVFREQ_GOV_START
  * event when device is added to devfreq framework.
  */
-void devfreq_monitor_start(struct devfreq *devfreq)
+int devfreq_monitor_start(struct devfreq *devfreq)
 {
if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
-   return;
+   return 0;
+
+   if (!devfreq->profile->get_dev_status)
+   return -EINVAL;
 
switch (devfreq->profile->timer) {
case DEVFREQ_TIMER_DEFERRABLE:
@@ -495,12 +498,13 @@ void devfreq_monitor_start(struct devfreq *devfreq)
INIT_DELAYED_WORK(>work, devfreq_monitor);
break;
default:
-   return;
+   return -EINVAL;
}
 
if (devfreq->profile->polling_ms)
queue_delayed_work(devfreq_wq, >work,
msecs_to_jiffies(devfreq->profile->polling_ms));
+   return 0;
 }
 EXPORT_SYMBOL(devfreq_monitor_start);
 
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 5cee3f64fe2b..31af6d072a10 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -75,7 +75,7 @@ struct devfreq_governor {
unsigned int event, void *data);
 };
 
-void devfreq_monitor_start(struct devfreq *devfreq);
+int devfreq_monitor_start(struct devfreq *devfreq);
 void devfreq_monitor_stop(struct devfreq *devfreq);
 void devfreq_monitor_suspend(struct devfreq *devfreq);
 void devfreq_monitor_resume(struct devfreq *devfreq);
diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index d57b82a2b570..ea287b57cbf3 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -89,8 +89,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq 
*devfreq,
 {
switch (event) {
case DEVFREQ_GOV_START:
-   devfreq_monitor_start(devfreq);
-   break;
+   return devfreq_monitor_start(devfreq);
 
case DEVFREQ_GOV_STOP:
devfreq_monitor_stop(devfreq);
-- 
2.25.1



[PATCH 09/11] PM / devfreq: governor: optimize simpleondemand get_target_freq

2021-03-09 Thread Dong Aisheng
devfreq_simple_ondemand_data only needs to be initialized once when
calling devm_devfreq_add_device. It's unnecessary to put the data
check logic in the hot path (.get_target_freq()) where it will be
called all the time during polling. Instead, we only check and initialize
it one time during DEVFREQ_GOV_START.

This also helps check data validability in advance during DEVFREQ_GOV_START
rather than checking it later when running .get_target_freq().

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor_simpleondemand.c | 50 +++
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index ea287b57cbf3..341eb7e9dc04 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -15,15 +15,19 @@
 /* Default constants for DevFreq-Simple-Ondemand (DFSO) */
 #define DFSO_UPTHRESHOLD   (90)
 #define DFSO_DOWNDIFFERENCTIAL (5)
+
+static struct devfreq_simple_ondemand_data od_default = {
+   .upthreshold = DFSO_UPTHRESHOLD,
+   .downdifferential = DFSO_DOWNDIFFERENCTIAL,
+};
+
 static int devfreq_simple_ondemand_func(struct devfreq *df,
unsigned long *freq)
 {
int err;
struct devfreq_dev_status *stat;
unsigned long long a, b;
-   unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
-   unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
-   struct devfreq_simple_ondemand_data *data = df->data;
+   struct devfreq_simple_ondemand_data *od = df->data;
 
err = devfreq_update_stats(df);
if (err)
@@ -31,16 +35,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
stat = >last_status;
 
-   if (data) {
-   if (data->upthreshold)
-   dfso_upthreshold = data->upthreshold;
-   if (data->downdifferential)
-   dfso_downdifferential = data->downdifferential;
-   }
-   if (dfso_upthreshold > 100 ||
-   dfso_upthreshold < dfso_downdifferential)
-   return -EINVAL;
-
/* Assume MAX if it is going to be divided by zero */
if (stat->total_time == 0) {
*freq = DEVFREQ_MAX_FREQ;
@@ -55,7 +49,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
/* Set MAX if it's busy enough */
if (stat->busy_time * 100 >
-   stat->total_time * dfso_upthreshold) {
+   stat->total_time * od->upthreshold) {
*freq = DEVFREQ_MAX_FREQ;
return 0;
}
@@ -68,7 +62,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
/* Keep the current frequency */
if (stat->busy_time * 100 >
-   stat->total_time * (dfso_upthreshold - dfso_downdifferential)) {
+   stat->total_time * (od->upthreshold - od->downdifferential)) {
*freq = stat->current_frequency;
return 0;
}
@@ -78,17 +72,41 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
a *= stat->current_frequency;
b = div_u64(a, stat->total_time);
b *= 100;
-   b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
+   b = div_u64(b, (od->upthreshold - od->downdifferential / 2));
*freq = (unsigned long) b;
 
return 0;
 }
 
+static int devfreq_simple_ondemand_check_od(struct devfreq *devfreq)
+{
+   struct devfreq_simple_ondemand_data *od = devfreq->data;
+
+   if (od) {
+   if (!od->upthreshold)
+   od->upthreshold = DFSO_UPTHRESHOLD;
+
+   if (!od->downdifferential)
+   od->downdifferential = DFSO_DOWNDIFFERENCTIAL;
+
+   if (od->upthreshold > 100 ||
+   od->upthreshold < od->downdifferential)
+   return -EINVAL;
+   } else {
+   od = _default;
+   }
+
+   return 0;
+}
+
 static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
unsigned int event, void *data)
 {
switch (event) {
case DEVFREQ_GOV_START:
+   if (devfreq_simple_ondemand_check_od(devfreq))
+   return -EINVAL;
+
return devfreq_monitor_start(devfreq);
 
case DEVFREQ_GOV_STOP:
-- 
2.25.1



[PATCH 06/11] PM / devfreq: drop the unnecessary low variable initialization

2021-03-09 Thread Dong Aisheng
drop the unnecessary low variable initialization and make the return
more straightforward.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index ce569bd9adfa..7231fe6862a2 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -351,7 +351,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 {
struct devfreq_freqs freqs;
unsigned long cur_freq;
-   int err = 0;
+   int err;
 
if (devfreq->profile->get_cur_freq)
devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq);
@@ -392,7 +392,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
if (devfreq->suspend_freq)
devfreq->resume_freq = new_freq;
 
-   return err;
+   return 0;
 }
 
 /**
-- 
2.25.1



[PATCH 04/11] PM / devfreq: bail out early if no freq changes in devfreq_set_target

2021-03-09 Thread Dong Aisheng
It's unnecessary to set the same freq again and run notifier calls.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3047896e41..6e80bf70e7b3 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -358,6 +358,9 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
else
cur_freq = devfreq->previous_freq;
 
+   if (new_freq == cur_freq)
+   return 0;
+
freqs.old = cur_freq;
freqs.new = new_freq;
devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);
@@ -374,7 +377,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
 * and DEVFREQ_POSTCHANGE because for showing the correct frequency
 * change order of between devfreq device and passive devfreq device.
 */
-   if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
+   if (trace_devfreq_frequency_enabled())
trace_devfreq_frequency(devfreq, new_freq, cur_freq);
 
freqs.new = new_freq;
-- 
2.25.1



[PATCH 05/11] PM / devfreq: use more accurate returned new_freq as resume_freq

2021-03-09 Thread Dong Aisheng
Use the more accurate returned new_freq as resume_freq.
It's the same as how devfreq->previous_freq was updated.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 6e80bf70e7b3..ce569bd9adfa 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -390,7 +390,7 @@ static int devfreq_set_target(struct devfreq *devfreq, 
unsigned long new_freq,
devfreq->previous_freq = new_freq;
 
if (devfreq->suspend_freq)
-   devfreq->resume_freq = cur_freq;
+   devfreq->resume_freq = new_freq;
 
return err;
 }
-- 
2.25.1



[PATCH 02/11] PM / devfreq: remove the invalid description for get_target_freq

2021-03-09 Thread Dong Aisheng
First of all, no_central_polling was removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")
Secondly, get_target_freq() is not only called only with update_devfreq()
notified by OPP now, but also min/max freq qos notifier.

So remove this invalid description now to avoid confusing.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/governor.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index 70f44b3ca42e..5cee3f64fe2b 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -57,8 +57,6 @@
  * Basically, get_target_freq will run
  * devfreq_dev_profile.get_dev_status() to get the
  * status of the device (load = busy_time / total_time).
- * If no_central_polling is set, this callback is called
- * only with update_devfreq() notified by OPP.
  * @event_handler:  Callback for devfreq core framework to notify events
  *  to governors. Events include per device governor
  *  init and exit, opp changes out of devfreq, suspend
-- 
2.25.1



[PATCH 03/11] PM / devfreq: fix the wrong set_freq path for userspace governor

2021-03-09 Thread Dong Aisheng
Fix the wrong set_freq path for userspace governor.

Signed-off-by: Dong Aisheng 
---
 drivers/devfreq/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 00704efe6398..20373a893b44 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -62,7 +62,7 @@ config DEVFREQ_GOV_USERSPACE
help
  Sets the frequency at the user specified one.
  This governor returns the user configured frequency if there
- has been an input to /sys/devices/.../power/devfreq_set_freq.
+ has been an input to /sys/devices/.../userspace/set_freq.
  Otherwise, the governor does not change the frequency
  given at the initialization.
 
-- 
2.25.1



[PATCH 01/11] doc: ABI: devfreq: remove invalid central_polling description

2021-03-09 Thread Dong Aisheng
no_central_polling has been removed since
commit 7e6fdd4bad03 ("PM / devfreq: Core updates to support devices
which can idle")

Signed-off-by: Dong Aisheng 
---
 Documentation/ABI/testing/sysfs-class-devfreq | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-devfreq 
b/Documentation/ABI/testing/sysfs-class-devfreq
index 386bc230a33d..5e6b74f30406 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -97,10 +97,7 @@ Description:
object. The values are represented in ms. If the value is
less than 1 jiffy, it is considered to be 0, which means
no polling. This value is meaningless if the governor is
-   not polling; thus. If the governor is not using
-   devfreq-provided central polling
-   (/sys/class/devfreq/.../central_polling is 0), this value
-   may be useless.
+   not polling.
 
A list of governors that support the node:
- simple_ondmenad
-- 
2.25.1



[PATCH 00/11] PM / devfreq: a few small fixes and improvements

2021-03-09 Thread Dong Aisheng
A few small fixes and improvements

Dong Aisheng (11):
  doc: ABI: devfreq: remove invalid central_polling description
  PM / devfreq: remove the invalid description for get_target_freq
  PM / devfreq: fix the wrong set_freq path for userspace governor
  PM / devfreq: bail out early if no freq changes in devfreq_set_target
  PM / devfreq: use more accurate returned new_freq as resume_freq
  PM / devfreq: drop the unnecessary low variable initialization
  PM / devfreq: check get_dev_status before start monitor
  PM / devfreq: check get_dev_status in devfreq_update_stats
  PM / devfreq: governor: optimize simpleondemand get_target_freq
  PM / devfreq: imx8m-ddrc: remove imx8m_ddrc_get_dev_status
  PM / devfreq: imx8m-ddrc: drop polling_ms

 Documentation/ABI/testing/sysfs-class-devfreq |  5 +-
 drivers/devfreq/Kconfig   |  2 +-
 drivers/devfreq/devfreq.c | 21 +---
 drivers/devfreq/governor.h|  7 +--
 drivers/devfreq/governor_simpleondemand.c | 53 ---
 drivers/devfreq/imx8m-ddrc.c  | 14 -
 6 files changed, 55 insertions(+), 47 deletions(-)

-- 
2.25.1



[PATCH 2/3] of: property: add debug info for supplier devices still unavailable

2020-11-19 Thread Dong Aisheng
It's normal that supplier devices may still unavaiable when parse DT to
create dependency. e.g. supplier devices populated by drivers.
Add debug info for this case.

Cc: devicet...@vger.kernel.org
Cc: Saravana Kannan 
Cc: Rob Herring 
Cc: Greg Kroah-Hartman 
Signed-off-by: Dong Aisheng 
---
 drivers/of/property.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 408a7b5f06a9..21a854e85234 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1150,6 +1150,8 @@ static int of_link_to_phandle(struct device *dev, struct 
device_node *sup_np,
 * Can't check for cycles or no cycles. So let's try
 * again later.
 */
+   dev_dbg(dev, "Not linking to %pOFP - device may still 
unavailable\n",
+   sup_np);
ret = -EAGAIN;
}
 
-- 
2.23.0



[PATCH 3/3] of: property: fix document of of_get_next_parent_dev

2020-11-19 Thread Dong Aisheng
Fix document of of_get_next_parent_dev.

Cc: devicet...@vger.kernel.org
Cc: Saravana Kannan 
Cc: Rob Herring 
Cc: Greg Kroah-Hartman 
Signed-off-by: Dong Aisheng 
---
 drivers/of/property.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 21a854e85234..5bd4a9bead47 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1038,7 +1038,7 @@ static bool of_is_ancestor_of(struct device_node 
*test_ancestor,
 }
 
 /**
- * of_get_next_parent_dev - Add device link to supplier from supplier phandle
+ * of_get_next_parent_dev - Get the closest ancestor device of a device node
  * @np: device tree node
  *
  * Given a device tree node (@np), this function finds its closest ancestor
-- 
2.23.0



[PATCH 1/3] driver core: simply go out if the same device_link is added again

2020-11-19 Thread Dong Aisheng
It's possible that the same device link may be added by parsing the
function dependecy in DT. e.g. clock/gpio/regulators.
Simply go out for this case.

Cc: Greg Kroah-Hartman 
Cc: "Rafael J. Wysocki" 
Cc: Saravana Kannan 
Signed-off-by: Dong Aisheng 
---
 drivers/base/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4c03bdd3a268..7d91d4074136 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -567,6 +567,9 @@ struct device_link *device_link_add(struct device *consumer,
if (link->consumer != consumer)
continue;
 
+   if (flags == link->flags)
+   goto out;
+
if (flags & DL_FLAG_PM_RUNTIME) {
if (!(link->flags & DL_FLAG_PM_RUNTIME)) {
pm_runtime_new_link(consumer);
-- 
2.23.0



Re: [PATCH v5 10/14] clk: imx: Add generic blk-ctl driver

2020-11-11 Thread Dong Aisheng
On Tue, Nov 3, 2020 at 7:22 PM Abel Vesa  wrote:
...
> +static int imx_blk_ctl_reset_set(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> +   struct imx_blk_ctl_drvdata *drvdata = container_of(rcdev,
> +   struct imx_blk_ctl_drvdata, rcdev);
> +   unsigned int offset = drvdata->rst_hws[id].offset;
> +   unsigned int shift = drvdata->rst_hws[id].shift;
> +   unsigned int mask = drvdata->rst_hws[id].mask;
> +   void __iomem *reg_addr = drvdata->base + offset;
> +   unsigned long flags;
> +   u32 reg;
> +
> +   if (!assert && !test_bit(1, >rst_hws[id].asserted))
> +   return -ENODEV;

What if consumers call deassert first in probe which seems common in kernel?
It seems will fail.
e.g.
probe() {
reset_control_get()
reset_control_deassert()
}

Regards
Aisheng

> +
> +   if (assert && !test_and_set_bit(1, >rst_hws[id].asserted))
> +   pm_runtime_get_sync(rcdev->dev)
> +
> +   spin_lock_irqsave(>lock, flags);
> +
> +   reg = readl(reg_addr);
> +   if (assert)
> +   writel(reg & ~(mask << shift), reg_addr);
> +   else
> +   writel(reg | (mask << shift), reg_addr);
> +
> +   spin_unlock_irqrestore(>lock, flags);
> +
> +   if (!assert && test_and_clear_bit(1, >rst_hws[id].asserted))
> +   pm_runtime_put(rcdev->dev)
> +
> +   return 0;
> +}
> +
> +static int imx_blk_ctl_reset_assert(struct reset_controller_dev *rcdev,
> +  unsigned long id)
> +{
> +   return imx_blk_ctl_reset_set(rcdev, id, true);
> +}
> +
> +static int imx_blk_ctl_reset_deassert(struct reset_controller_dev *rcdev,
> +unsigned long id)
> +{
> +   return imx_blk_ctl_reset_set(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops imx_blk_ctl_reset_ops = {
> +   .assert = imx_blk_ctl_reset_assert,
> +   .deassert   = imx_blk_ctl_reset_deassert,
> +};
> +
> +static int imx_blk_ctl_register_reset_controller(struct device *dev)
> +{
> +   const struct imx_blk_ctl_dev_data *dev_data = 
> of_device_get_match_data(dev);
> +   struct imx_blk_ctl_drvdata *drvdata = dev_get_drvdata(dev);
> +   int max = dev_data->resets_max;
> +   struct imx_reset_hw *hws;
> +   int i;
> +
> +   spin_lock_init(>lock);
> +
> +   drvdata->rcdev.owner = THIS_MODULE;
> +   drvdata->rcdev.nr_resets = max;
> +   drvdata->rcdev.ops   = _blk_ctl_reset_ops;
> +   drvdata->rcdev.of_node   = dev->of_node;
> +   drvdata->rcdev.dev   = dev;
> +
> +   drvdata->rst_hws = devm_kcalloc(dev, max, sizeof(struct imx_reset_hw),
> +   GFP_KERNEL);
> +   hws = drvdata->rst_hws;
> +
> +   for (i = 0; i < dev_data->hws_num; i++) {
> +   struct imx_blk_ctl_hw *hw = _data->hws[i];
> +
> +   if (hw->type != BLK_CTL_RESET)
> +   continue;
> +
> +   hws[hw->id].offset = hw->offset;
> +   hws[hw->id].shift = hw->shift;
> +   hws[hw->id].mask = hw->mask;
> +   }
> +
> +   return devm_reset_controller_register(dev, >rcdev);
> +}
> +static struct clk_hw *imx_blk_ctl_register_one_clock(struct device *dev,
> +   struct imx_blk_ctl_hw *hw)
> +{
> +   struct imx_blk_ctl_drvdata *drvdata = dev_get_drvdata(dev);
> +   void __iomem *base = drvdata->base;
> +   struct clk_hw *clk_hw = NULL;
> +
> +   switch (hw->type) {
> +   case BLK_CTL_CLK_MUX:
> +   clk_hw = imx_dev_clk_hw_mux_flags(dev, hw->name,
> + base + hw->offset,
> + hw->shift, hw->width,
> + hw->parents,
> + hw->parents_count,
> + hw->flags);
> +   break;
> +   case BLK_CTL_CLK_GATE:
> +   clk_hw = imx_dev_clk_hw_gate(dev, hw->name, hw->parents,
> +base + hw->offset, hw->shift);
> +   break;
> +   case BLK_CTL_CLK_SHARED_GATE:
> +   clk_hw = imx_dev_clk_hw_gate_shared(dev, hw->name,
> +   hw->parents,
> +   base + hw->offset,
> +   hw->shift,
> +   hw->shared_count);
> +   break;
> +   case BLK_CTL_CLK_PLL14XX:
> +   clk_hw = imx_dev_clk_hw_pll14xx(dev, hw->name, hw->parents,
> +   base + hw->offset, 
> hw->pll_tbl);
> +   break;
> +   };
> +
> +   

Re: [PATCH v3 10/14] clk: imx: Add generic blk-ctl driver

2020-09-11 Thread Dong Aisheng
On Tue, Sep 8, 2020 at 6:27 PM Abel Vesa  wrote:
>
> The i.MX8MP platform introduces a new type of IP which is called BLK_CTL in
> RM and usually is comprised of some GPRs that are considered too
> generic to be part of any dedicated IP from that specific subsystem.
>
> In general, some of the GPRs have some clock bits, some have reset bits,
> so in order to be able to use the imx clock API, this needs to be
> in a clock driver. From there it can use the reset controller API and
> leave the rest to the syscon.
>
> Signed-off-by: Abel Vesa 
> ---
>  drivers/clk/imx/Makefile  |   2 +-
>  drivers/clk/imx/clk-blk-ctl.c | 297 
> ++
>  drivers/clk/imx/clk-blk-ctl.h |  80 
>  3 files changed, 378 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/imx/clk-blk-ctl.c
>  create mode 100644 drivers/clk/imx/clk-blk-ctl.h
>
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 79e53f2..105c117 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -23,7 +23,7 @@ obj-$(CONFIG_MXC_CLK) += mxc-clk.o
>
>  obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
>  obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
> -obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
> +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o
>  obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
>
>  obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
> diff --git a/drivers/clk/imx/clk-blk-ctl.c b/drivers/clk/imx/clk-blk-ctl.c
> new file mode 100644
> index ..1a6f1eb
> --- /dev/null
> +++ b/drivers/clk/imx/clk-blk-ctl.c
> @@ -0,0 +1,297 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2020 NXP.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "clk.h"
> +#include "clk-blk-ctl.h"
> +
> +struct imx_reset_hw {
> +   u32 offset;
> +   u32 shift;
> +   u32 mask;
> +   volatile unsigned long asserted;

Could you clarify a bit why need 'volatile' here?

> +};
> +
> +struct imx_pm_safekeep_info {
> +   uint32_t *regs_values;
> +   uint32_t *regs_offsets;
> +   uint32_t regs_num;
> +};
> +
> +struct imx_blk_ctl_drvdata {
> +   void __iomem *base;
> +   struct reset_controller_dev rcdev;
> +   struct imx_reset_hw *rst_hws;
> +   struct imx_pm_safekeep_info pm_info;
> +
> +   spinlock_t lock;
> +};
> +
> +static void __maybe_unused imx_blk_ctl_read_write(struct device *dev,
> +   bool write)
> +{
> +   struct imx_blk_ctl_drvdata *drvdata = dev_get_drvdata(dev);
> +   struct imx_pm_safekeep_info *pm_info = >pm_info;
> +   void __iomem *base = drvdata->base;
> +   int i;
> +
> +   if (!pm_info->regs_num)
> +   return;
> +
> +   for (i = 0; i < pm_info->regs_num; i++) {
> +   u32 offset = pm_info->regs_offsets[i];
> +
> +   if (write)
> +   writel(pm_info->regs_values[i], base + offset);
> +   else
> +   pm_info->regs_values[i] = readl(base + offset);
> +   }
> +
> +}
> +
> +static int __maybe_unused imx_blk_ctl_runtime_suspend(struct device *dev)
> +{
> +   imx_blk_ctl_read_write(dev, false);
> +
> +   return 0;
> +}
> +
> +static int __maybe_unused imx_blk_ctl_runtime_resume(struct device *dev)
> +{
> +   imx_blk_ctl_read_write(dev, true);
> +
> +   return 0;
> +}
> +
> +const struct dev_pm_ops imx_blk_ctl_pm_ops = {
> +   SET_RUNTIME_PM_OPS(imx_blk_ctl_runtime_suspend,
> +  imx_blk_ctl_runtime_resume, NULL)
> +   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +  pm_runtime_force_resume)
> +};
> +EXPORT_SYMBOL_GPL(imx_blk_ctl_pm_ops);
> +
> +static int imx_blk_ctl_reset_set(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> +   struct imx_blk_ctl_drvdata *drvdata = container_of(rcdev,
> +   struct imx_blk_ctl_drvdata, rcdev);
> +   unsigned int offset = drvdata->rst_hws[id].offset;
> +   unsigned int shift = drvdata->rst_hws[id].shift;
> +   unsigned int mask = drvdata->rst_hws[id].mask;
> +   void __iomem *reg_addr = drvdata->base + offset;
> +   unsigned long flags;
> +   u32 reg;
> +
> +   if (assert && !test_and_set_bit(1, >rst_hws[id].asserted))
> +   pm_runtime_get_sync(rcdev->dev);
> +

i'm a bit confused because each reset hw has a field 'asserted' which means
you're doing bit operations on each separate private variable.
Is that what we want?

BTW, what if user calling deassert first?
Will that cause writing registers without enabling power domain?

> +   spin_lock_irqsave(>lock, flags);
> +
> +   reg = readl(reg_addr);
> +   if (assert)
> +   writel(reg & ~(mask << 

Re: [PATCH v1] driver core: Fix device_pm_lock() locking for device links

2020-09-01 Thread Dong Aisheng
Hi Saravana

On Tue, Sep 1, 2020 at 6:10 AM Saravana Kannan  wrote:
>
> This commit fixes two issues:
>
> 1. The lockdep warning reported by Dong Aisheng  [1].
>
> It is a warning about a cycle (dpm_list_mtx --> kn->active#3 --> fw_lock)
> that was introduced when device-link devices were added to expose device
> link information in sysfs.
>
> The patch that "introduced" this cycle can't be reverted because it's fixes
> a real SRCU issue and also ensures that the device-link device is deleted
> as soon as the device-link is deleted. This is important to avoid sysfs
> name collisions if the device-link is create again immediately (this can
> happen a lot with deferred probing).
>
> 2. device_link_drop_managed() is not grabbing device_pm_lock().
>
> When device_link_del() calls __device_link_del() (device_link_del() ->
> device_link_put_kref() kref_put() -> __device_link_del()) it grabs the
> device_pm_lock().
>
> However, when device_link_drop_managed() calls __device_link_del()
> (device_link_drop_managed() -> kref_put() -> __device_link_del()) it
> doesn't grab device_pm_lock(). There's nothing special about managed
> device-links that remove the need for grabbing device_pm_lock(). So, this
> patch makes sure device_pm_lock() is always held when deleting managed
> links.
>
> And thanks to Stephen Boyd for helping me understand the lockdep splat.
>
> Fixes: 843e600b8a2b ("driver core: Fix sleeping in invalid context during 
> device link deletion")
> Fixes: 515db266a9da ("driver core: Remove device link creation limitation")
> [1] - 
> https://lore.kernel.org/lkml/CAA+hA=S4eAreb7vo69LAXSk2t5=deknxhaiy1wspk4xtp9u...@mail.gmail.com/
> Reported-by: Dong Aisheng 
> Signed-off-by: Saravana Kannan 

Thanks a lot for the quick fix. It worked for me.

Tested-by: Dong Aisheng 

Regards
Aisheng

> ---
>
> Rafael,
>
> A bigger question I had is why we need to grab device_pm_lock() around
> device_link_del() in the first place. I understand the need to grab it
> during device_link_add() -- it's because we are checking the supplier is
> in the dpm_list and because we are reordering devices on the dpm_list.
>
> But during deletion, we don't need to do either one of those.  So, why
> do we even need to grab the device_pm_lock() in the first place. The
> device_links_write_lock() that we already grab before deleting a device
> link seems like it'd be sufficient. If you agree we don't need to grab
> device_pm_lock() during deletion, then I can change this patch to just
> delete that locking.
>
> -Saravana
>
>  drivers/base/core.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index f6f620aa9408..de1935e21d97 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -766,8 +766,10 @@ static void __device_link_del(struct kref *kref)
> if (link->flags & DL_FLAG_PM_RUNTIME)
> pm_runtime_drop_link(link->consumer);
>
> +   device_pm_lock();
> list_del_rcu(>s_node);
> list_del_rcu(>c_node);
> +   device_pm_unlock();
> device_unregister(>link_dev);
>  }
>  #else /* !CONFIG_SRCU */
> @@ -781,8 +783,10 @@ static void __device_link_del(struct kref *kref)
> if (link->flags & DL_FLAG_PM_RUNTIME)
> pm_runtime_drop_link(link->consumer);
>
> +   device_pm_lock();
> list_del(>s_node);
> list_del(>c_node);
> +   device_pm_unlock();
> device_unregister(>link_dev);
>  }
>  #endif /* !CONFIG_SRCU */
> @@ -807,9 +811,7 @@ static void device_link_put_kref(struct device_link *link)
>  void device_link_del(struct device_link *link)
>  {
> device_links_write_lock();
> -   device_pm_lock();
> device_link_put_kref(link);
> -   device_pm_unlock();
> device_links_write_unlock();
>  }
>  EXPORT_SYMBOL_GPL(device_link_del);
> @@ -830,7 +832,6 @@ void device_link_remove(void *consumer, struct device 
> *supplier)
> return;
>
> device_links_write_lock();
> -   device_pm_lock();
>
> list_for_each_entry(link, >links.consumers, s_node) {
> if (link->consumer == consumer) {
> @@ -839,7 +840,6 @@ void device_link_remove(void *consumer, struct device 
> *supplier)
> }
> }
>
> -   device_pm_unlock();
> device_links_write_unlock();
>  }
>  EXPORT_SYMBOL_GPL(device_link_remove);
> --
> 2.28.0.402.g5ffc5be6b7-goog
>


Re: [PATCH 21/22] arm64: dts: imx8qxp: Remove i.MX7 compatible from USDHC

2020-08-24 Thread Dong Aisheng
On Mon, Aug 24, 2020 at 6:32 PM Krzysztof Kozlowski  wrote:
>
> On Mon, Aug 24, 2020 at 10:31:31AM +, Bough Chen wrote:
> > > -Original Message-----
> > > From: Dong Aisheng [mailto:donga...@gmail.com]
> > > Sent: 2020年8月24日 17:45
> > > To: Krzysztof Kozlowski 
> > > Cc: Aisheng Dong ; devicet...@vger.kernel.org;
> > > linux-ser...@vger.kernel.org; Anson Huang ;
> > > linux-g...@vger.kernel.org; Fabio Estevam ; Linus
> > > Walleij ; linux...@vger.kernel.org;
> > > linux-...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > linux-...@vger.kernel.org; Bartosz Golaszewski
> > > ; Rob Herring ;
> > > linux-...@lists.infradead.org; dl-linux-imx ; 
> > > Pengutronix
> > > Kernel Team ; Thierry Reding
> > > ; Shawn Guo ; Sascha
> > > Hauer ; linux-arm-ker...@lists.infradead.org;
> > > linux-watch...@vger.kernel.org; Bough Chen 
> > > Subject: Re: [PATCH 21/22] arm64: dts: imx8qxp: Remove i.MX7 compatible
> > > from USDHC
> > >
> > > On Mon, Aug 24, 2020 at 5:15 PM Krzysztof Kozlowski 
> > > wrote:
> > > >
> > > > On Mon, Aug 24, 2020 at 09:00:19AM +, Aisheng Dong wrote:
> > > > > > From: Krzysztof Kozlowski 
> > > > > > Sent: Monday, August 24, 2020 12:16 AM
> > > > > >
> > > > > > The USDHC on i.MX 8QXP has its own compatible described in
> > > > > > bindings and used in the driver (with its own quirks).  Remove
> > > > > > additional fsl,imx7d-usdhc compatible to fix dtbs_check warnings 
> > > > > > like:
> > > > > >
> > > > > >   arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dt.yaml:
> > > mmc@5b01:
> > > > > > compatible: ['fsl,imx8qxp-usdhc', 'fsl,imx7d-usdhc'] is too long
> > > > > > From schema:
> > > > > > /ocumentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > > > > >
> > > > > >   arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dt.yaml:
> > > mmc@5b01:
> > > > > > compatible: Additional items are not allowed
> > > > > > ('fsl,imx7d-usdhc' was
> > > > > > unexpected)
> > > > > >
> > > > > > Signed-off-by: Krzysztof Kozlowski 
> > > > >
> > > > > For Patch 19-22, I think we should fix dt binding doc.
> > > >
> > > > Are you sure that these USDHC controllers are compatible with i.MX 7D?
> > > > Could they really run with fsl,imx7d-usdhc compatible?
> > >
> > > AFAIK uSDHC on QXP is derived from the former platforms with adding a few
> > > more new features. e.g. HS400ES/CMDQ.
> > > Let me loop in uSDHC driver owner Haibo Chen to double confirm.
> >
> > Yes, usdhc of imx8qxp can work by using the compatible "fsl, imx7d-usdhc", 
> > but will not support HS400ES/Command Queue any more. Also imx8qxp support 
> > Auto CMD23, but imx7d not.
> > And imx8qxp need to re-config the clock rate after system PM, imx7d do not 
> > need to do this.
>
> Then we can leave the compatible in DTS and I will correct the device
> tree schema.

Haibo,

As Krzysztof is helping fix uSDHC binding doc in Patch 12/22,
please double check with IC for the whole uSDHC derive relationships on i.MX
and feedback to Krzysztof if anything is wrong.

Regards
Aisheng

>
> Best regards,
> Krzysztof


Re: [PATCH 21/22] arm64: dts: imx8qxp: Remove i.MX7 compatible from USDHC

2020-08-24 Thread Dong Aisheng
On Mon, Aug 24, 2020 at 5:15 PM Krzysztof Kozlowski  wrote:
>
> On Mon, Aug 24, 2020 at 09:00:19AM +, Aisheng Dong wrote:
> > > From: Krzysztof Kozlowski 
> > > Sent: Monday, August 24, 2020 12:16 AM
> > >
> > > The USDHC on i.MX 8QXP has its own compatible described in bindings and
> > > used in the driver (with its own quirks).  Remove additional 
> > > fsl,imx7d-usdhc
> > > compatible to fix dtbs_check warnings like:
> > >
> > >   arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dt.yaml: mmc@5b01:
> > > compatible: ['fsl,imx8qxp-usdhc', 'fsl,imx7d-usdhc'] is too long
> > > From schema:
> > > /ocumentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > >
> > >   arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dt.yaml: mmc@5b01:
> > > compatible: Additional items are not allowed ('fsl,imx7d-usdhc' was
> > > unexpected)
> > >
> > > Signed-off-by: Krzysztof Kozlowski 
> >
> > For Patch 19-22, I think we should fix dt binding doc.
>
> Are you sure that these USDHC controllers are compatible with i.MX 7D?
> Could they really run with fsl,imx7d-usdhc compatible?

AFAIK uSDHC on QXP is derived from the former platforms with adding a few
more new features. e.g. HS400ES/CMDQ.
Let me loop in uSDHC driver owner Haibo Chen to double confirm.

Regards
Aisheng

> The implementation (Linux kernel driver) is different, I guess on
> purpose...
>
> Best regards,
> Krzysztof
>
> >
> > Regards
> > Aisheng
> >
> > > ---
> > >  arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 6 +++---
> > >  1 file changed, 3 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
> > > b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
> > > index 61bccb69f09e..26c4fcdfe290 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
> > > @@ -362,7 +362,7 @@
> > > };
> > >
> > > usdhc1: mmc@5b01 {
> > > -   compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> > > +   compatible = "fsl,imx8qxp-usdhc";
> > > interrupts = ;
> > > reg = <0x5b01 0x1>;
> > > clocks = <_lpcg IMX_CONN_LPCG_SDHC0_IPG_CLK>, @@
> > > -374,7 +374,7 @@
> > > };
> > >
> > > usdhc2: mmc@5b02 {
> > > -   compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> > > +   compatible = "fsl,imx8qxp-usdhc";
> > > interrupts = ;
> > > reg = <0x5b02 0x1>;
> > > clocks = <_lpcg IMX_CONN_LPCG_SDHC1_IPG_CLK>, @@
> > > -388,7 +388,7 @@
> > > };
> > >
> > > usdhc3: mmc@5b03 {
> > > -   compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> > > +   compatible = "fsl,imx8qxp-usdhc";
> > > interrupts = ;
> > > reg = <0x5b03 0x1>;
> > > clocks = <_lpcg IMX_CONN_LPCG_SDHC2_IPG_CLK>,
> > > --
> > > 2.17.1
> >
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Lockdep warning caused by "driver core: Fix sleeping in invalid context during device link deletion"

2020-08-20 Thread Dong Aisheng
Hi ALL,

We met the below WARNING during system suspend on an iMX6Q SDB board
with the latest linus/master branch (v5.9-rc1+) and next-20200820.
v5.8 kernel is ok. So i did bisect and finally found it's caused by
the patch below.
Reverting it can get rid of the warning, but I wonder if there may be
other potential issues.
Any ideas?

Defconfig used is: imx_v6_v7_defconfig

commit 843e600b8a2b01463c4d873a90b2c2ea8033f1f6
Author: Saravana Kannan 
Date:   Thu Jul 16 14:45:23 2020 -0700

driver core: Fix sleeping in invalid context during device link deletion

Marek and Guenter reported that commit 287905e68dd2 ("driver core:
Expose device link details in sysfs") caused sleeping/scheduling while
atomic warnings.

BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:935
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 12, name: kworker/0:1
2 locks held by kworker/0:1/12:
  #0: ee8074a8 ((wq_completion)rcu_gp){+.+.}-{0:0}, at:
process_one_work+0x174/0x7dc
  #1: ee921f20 ((work_completion)(>work)){+.+.}-{0:0}, at:
process_one_work+0x174/0x7dc
Preemption disabled at:
[] srcu_invoke_callbacks+0xc0/0x154
- 8< - SNIP
[] (device_del) from [] (device_unregister+0x24/0x64)
[] (device_unregister) from []
(srcu_invoke_callbacks+0xcc/0x154)
[] (srcu_invoke_callbacks) from []
(process_one_work+0x234/0x7dc)
[] (process_one_work) from [] (worker_thread+0x44/0x51c)
[] (worker_thread) from [] (kthread+0x158/0x1a0)
[] (kthread) from [] (ret_from_fork+0x14/0x20)
Exception stack(0xee921fb0 to 0xee921ff8)

This was caused by the device link device being released in the context
of srcu_invoke_callbacks().  There is no need to wait till the RCU
callback to release the device link device.  So release the device
earlier and move the call_srcu() into the device release code. That way,
the memory will get freed only after the device is released AND the RCU
callback is called.

Fixes: 287905e68dd2 ("driver core: Expose device link details in sysfs")
Reported-by: Marek Szyprowski 
Reported-by: Guenter Roeck 
Reported-by: Naresh Kamboju 
Signed-off-by: Saravana Kannan 
Tested-by: Marek Szyprowski 
Tested-by: Guenter Roeck 
Link: 
https://lore.kernel.org/r/20200716214523.2924704-1-sarava...@google.com
Signed-off-by: Greg Kroah-Hartman 

Error log:
# echo mem > /sys/power/state
[   39.111865] PM: suspend entry (deep)
[   39.148650] Filesystems sync: 0.032 seconds
[   39.154034]
[   39.155537] ==
[   39.161723] WARNING: possible circular locking dependency detected
[   39.167911] 5.9.0-rc1-00103-g7eac66d0456f #37 Not tainted
[   39.173315] --
[   39.179500] sh/647 is trying to acquire lock:
[   39.183862] c15a310c (dpm_list_mtx){+.+.}-{3:3}, at:
dpm_for_each_dev+0x20/0x5c
[   39.191200]
[   39.191200] but task is already holding lock:
[   39.197036] c15a37e4 (fw_lock){+.+.}-{3:3}, at: fw_pm_notify+0x90/0xd4
[   39.203582]
[   39.203582] which lock already depends on the new lock.
[   39.203582]
[   39.211763]
[   39.211763] the existing dependency chain (in reverse order) is:
[   39.219249]
[   39.219249] -> #2 (fw_lock){+.+.}-{3:3}:
[   39.224673]mutex_lock_nested+0x1c/0x24
[   39.229126]firmware_uevent+0x18/0xa0
[   39.233411]dev_uevent+0xc4/0x1f8
[   39.237343]uevent_show+0x98/0x114
[   39.241362]dev_attr_show+0x18/0x48
[   39.245472]sysfs_kf_seq_show+0x84/0xec
[   39.249927]seq_read+0x138/0x550
[   39.253774]vfs_read+0x94/0x164
[   39.257529]ksys_read+0x60/0xe8
[   39.261288]ret_fast_syscall+0x0/0x28
[   39.265564]0xbed7c808
[   39.268538]
[   39.268538] -> #1 (kn->active#3){}-{0:0}:
[   39.274391]kernfs_remove_by_name_ns+0x40/0x94
[   39.279450]device_del+0x144/0x3fc
[   39.283467]__device_link_del+0x4c/0x70
[   39.287919]device_link_remove+0x5c/0x8c
[   39.292464]_regulator_put.part.0+0x104/0x1dc
[   39.297436]regulator_put+0x2c/0x3c
[   39.299731] regulator regulator.5: Failed to increase supply voltage: -110
[   39.301544]release_nodes+0x1b4/0x204
[   39.301553]really_probe+0x104/0x3b4
[   39.316881]driver_probe_device+0x58/0xb4
[   39.321506]device_driver_attach+0x58/0x60
[   39.326217]__driver_attach+0x58/0xd0
[   39.330499]bus_for_each_dev+0x74/0xbc
[   39.334863]bus_add_driver+0x150/0x1dc
[   39.339227]driver_register+0x74/0x108
[   39.343599]i2c_register_driver+0x38/0x8c
[   39.348227]do_one_initcall+0x84/0x3b4
[   39.352598]kernel_init_freeable+0x154/0x1e4
[   39.357485]kernel_init+0x8/0x118
[   39.361415]ret_from_fork+0x14/0x20
[   39.365518]0x0
[   39.367883]
[   39.367883] -> #0 (dpm_list_mtx){+.+.}-{3:3}:

Re: [PATCH v2 11/17] clk: imx: Add blk_ctrl combo driver

2020-08-19 Thread Dong Aisheng
On Thu, Aug 20, 2020 at 4:31 AM Abel Vesa  wrote:

> > > +extern const struct imx_blk_ctrl_dev_data imx8mp_audio_blk_ctrl_dev_data 
> > > __initconst;
> > > +extern const struct imx_blk_ctrl_dev_data imx8mp_media_blk_ctrl_dev_data 
> > > __initconst;
> > > +extern const struct imx_blk_ctrl_dev_data imx8mp_hdmi_blk_ctrl_dev_data 
> > > __initconst;
> > > +
> >
> > If no special reasons, i may prefer to put those data in either
> > clk-blk-ctrl.c or separate clk-blk-ctrl-data.c
> > because there seems to be no code level dependency on the CCM
> > driver(clk-imx8mq.c) for clk_blk_ctrl drivers.
> > Then we can save those extern variables.
> >
>
> The rationale here is to have the SoC specific definitions in the SoC specific
> clock provider driver. Otherwise with every new SoC that will use the blk_ctl
> IPs we will increase the size of clk-blk-ctrl driver. Plus the kernel names of
> the clocks used by each blk_ctl IP as parents are also defined in the SoC
> specific clock provider driver.
>
> I'll find a way, though, to move those so that they would not be shared 
> between
> all the clock drivers that needs a blk_ctl implementation.
>

Please refer to pinctrl-imx.c to see if we can do similar things for blk-ctrl.

Regards
Aisheng

> > Regards
> > Aisheng
> >
> > > +#endif
> > > +
> > > --
> > > 2.7.4
> > >


Re: [PATCH v2 16/17] arm64: dts: imx8mp: Add media_blk_ctrl node

2020-08-19 Thread Dong Aisheng
Hi Rob, Stephen,

On Thu, Aug 20, 2020 at 4:37 AM Abel Vesa  wrote:
>
> On 20-08-18 19:34:14, Dong Aisheng wrote:
> > On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
> > >
> > > Some of the features of the media_ctrl will be used by some
> > > different drivers in a way those drivers will know best, so adding the
> > > syscon compatible we allow those to do just that. Only the resets
> > > and the clocks are registered bit the clk-blk-ctrl driver.
> > >
> > > Signed-off-by: Abel Vesa 
> > > ---
> > >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 
> > >  1 file changed, 16 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
> > > b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > index dede0ae..2d6d213 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > @@ -736,6 +736,22 @@
> > > };
> > > };
> > >
> > > +   aips4: bus@32c0 {
> > > +   compatible = "simple-bus";
> > > +   reg = <0x32c0 0x40>;
> > > +   #address-cells = <1>;
> > > +   #size-cells = <1>;
> > > +   ranges;
> > > +
> > > +   media_blk_ctrl: clock-controller@32ec {
> >
> > For this combo device, maybe we can directly name it as blk-ctrl@32ec.
> > Rob, do you think if we can do that?
> >
>
> I think it was Stephen who suggested we change it to clock-controller in the
> last's version thread.
>
> TBH, I agree with you here, since it makes more sense to be called blk-ctrl
> provided that this is not really just a clock controller.
>

How do you think?

Regards
Aisheng

> > > +   compatible = "fsl,imx8mp-media-blk-ctrl", 
> > > "syscon";
> > > +   reg = <0x32ec 0x1>;
> > > +
> >
> > Remove unnecessary blank line
> >
>
> Will do.
>
> > Otherwise:
> > Reviewed-by: Dong Aisheng 
> >
> > Regards
> > Aisheng
> >
> > > +   #clock-cells = <1>;
> > > +   #reset-cells = <1>;
> > > +   };
> > > +   };
> > > +
> > > aips5: bus@30c0 {
> > > compatible = "fsl,aips-bus", "simple-bus";
> > > reg = <0x30c0 0x40>;
> > > --
> > > 2.7.4
> > >


Re: [PATCH v2 16/17] arm64: dts: imx8mp: Add media_blk_ctrl node

2020-08-18 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
>
> Some of the features of the media_ctrl will be used by some
> different drivers in a way those drivers will know best, so adding the
> syscon compatible we allow those to do just that. Only the resets
> and the clocks are registered bit the clk-blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index dede0ae..2d6d213 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -736,6 +736,22 @@
> };
> };
>
> +   aips4: bus@32c0 {
> +   compatible = "simple-bus";
> +   reg = <0x32c0 0x40>;
> +   #address-cells = <1>;
> +   #size-cells = <1>;
> +   ranges;
> +
> +   media_blk_ctrl: clock-controller@32ec {

For this combo device, maybe we can directly name it as blk-ctrl@32ec.
Rob, do you think if we can do that?

> +   compatible = "fsl,imx8mp-media-blk-ctrl", 
> "syscon";
> +   reg = <0x32ec 0x1>;
> +

Remove unnecessary blank line

Otherwise:
Reviewed-by: Dong Aisheng 

Regards
Aisheng

> +   #clock-cells = <1>;
> +   #reset-cells = <1>;
> +   };
> +   };
> +
> aips5: bus@30c0 {
> compatible = "fsl,aips-bus", "simple-bus";
> reg = <0x30c0 0x40>;
> --
> 2.7.4
>


Re: [PATCH v2 15/17] arm64: dts: imx8mp: Add audio_blk_ctrl node

2020-08-18 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
>
> Some of the features of the audio_ctrl will be used by some
> different drivers in a way those drivers will know best, so adding the
> syscon compatible we allow those to do just that. Only the resets
> and the clocks are registered bit the clk-blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index daa1769..dede0ae 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -736,6 +736,22 @@
> };
> };
>
> +   aips5: bus@30c0 {
> +   compatible = "fsl,aips-bus", "simple-bus";
> +   reg = <0x30c0 0x40>;
> +   #address-cells = <1>;
> +   #size-cells = <1>;
> +   ranges;
> +
> +   audio_blk_ctrl: clock-controller@30e2 {
> +   compatible = "fsl,imx8mp-audio-blk-ctrl", 
> "syscon";
> +   reg = <0x30e2 0x50C>;

0x50c

> +

remove unnecessary blank line

Otherwise:
Reviewed-by: Dong Aisheng 

Regards
Aisheng

> +   #clock-cells = <1>;
> +   #reset-cells = <1>;
> +   };
> +   };
> +
> gic: interrupt-controller@3880 {
> compatible = "arm,gic-v3";
> reg = <0x3880 0x1>,
> --
> 2.7.4
>


Re: [PATCH v2 12/17] clk: imx8mp: Add audio blk_ctrl clocks and resets

2020-08-18 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
>
> Add audio blk_ctrl clocks and resets in the i.MX8MP clock
> driver to be picked up by the clk-blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> ---
>  drivers/clk/imx/clk-blk-ctrl.c |   4 ++
>  drivers/clk/imx/clk-imx8mp.c   | 138 
> +

As i mentioned in Patch 11, I wonder we probably better to put blk
ctrl clk data in blk ctrl driver.
Otherwise, i'm okay with the code.

Regards
Aisheng

>  2 files changed, 142 insertions(+)
>
> diff --git a/drivers/clk/imx/clk-blk-ctrl.c b/drivers/clk/imx/clk-blk-ctrl.c
> index 1672646..1c2991c 100644
> --- a/drivers/clk/imx/clk-blk-ctrl.c
> +++ b/drivers/clk/imx/clk-blk-ctrl.c
> @@ -312,6 +312,10 @@ static const struct dev_pm_ops imx_blk_ctrl_pm_ops = {
>  };
>
>  static const struct of_device_id imx_blk_ctrl_of_match[] = {
> +   {
> +   .compatible = "fsl,imx8mp-audio-blk-ctrl",
> +   .data = _audio_blk_ctrl_dev_data
> +   },
> { /* Sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, imx_blk_ctrl_of_match);
> diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
> index 462c558..00e7f5e 100644
> --- a/drivers/clk/imx/clk-imx8mp.c
> +++ b/drivers/clk/imx/clk-imx8mp.c
> @@ -4,6 +4,7 @@
>   */
>
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -14,11 +15,148 @@
>  #include 
>
>  #include "clk.h"
> +#include "clk-blk-ctrl.h"
> +
> +#defineIMX_AUDIO_BLK_CTRL_CLKEN0   0x0
> +#defineIMX_AUDIO_BLK_CTRL_CLKEN1   0x4
> +#defineIMX_AUDIO_BLK_CTRL_EARC 0x200
> +#defineIMX_AUDIO_BLK_CTRL_SAI1_MCLK_SEL0x300
> +#defineIMX_AUDIO_BLK_CTRL_SAI2_MCLK_SEL0x304
> +#defineIMX_AUDIO_BLK_CTRL_SAI3_MCLK_SEL0x308
> +#defineIMX_AUDIO_BLK_CTRL_SAI5_MCLK_SEL0x30C
> +#defineIMX_AUDIO_BLK_CTRL_SAI6_MCLK_SEL0x310
> +#defineIMX_AUDIO_BLK_CTRL_SAI7_MCLK_SEL0x314
> +#defineIMX_AUDIO_BLK_CTRL_PDM_CLK  0x318
> +#defineIMX_AUDIO_BLK_CTRL_SAI_PLL_GNRL_CTL 0x400
> +#defineIMX_AUDIO_BLK_CTRL_SAI_PLL_FDIVL_CTL0   0x404
> +#defineIMX_AUDIO_BLK_CTRL_SAI_PLL_FDIVL_CTL1   0x408
> +#defineIMX_AUDIO_BLK_CTRL_SAI_PLL_SSCG_CTL 0x40C
> +#defineIMX_AUDIO_BLK_CTRL_SAI_PLL_MNIT_CTL 0x410
> +#defineIMX_AUDIO_BLK_CTRL_IPG_LP_CTRL  0x504
> +
> +#define IMX_MEDIA_BLK_CTRL_SFT_RSTN0x0
> +#define IMX_MEDIA_BLK_CTRL_CLK_EN  0x4
>
>  static u32 share_count_nand;
>  static u32 share_count_media;
>  static u32 share_count_audio;
>
> +static int shared_count_pdm;
> +
> +static const struct imx_pll14xx_rate_table imx_blk_ctrl_sai_pll_tbl[] = {
> +   PLL_1443X_RATE(65000U, 325, 3, 2, 0),
> +};
> +
> +static const struct imx_pll14xx_clk imx_blk_ctrl_sai_pll = {
> +   .type = PLL_1443X,
> +   .rate_table = imx_blk_ctrl_sai_pll_tbl,
> +};
> +
> +static const char * const imx_sai_mclk2_sels[] = {"sai1_root", "sai2_root", 
> "sai3_root", "dummy",
> +  "sai5_root", "sai6_root", 
> "sai7_root", "sai1_mclk",
> +  "sai2_mclk", "sai3_mclk", "dummy",
> +  "sai5_mclk", "sai6_mclk", 
> "sai7_mclk", "spdif1_ext_clk"};
> +static const char * const imx_sai1_mclk1_sels[] = {"sai1_root", "sai1_mclk", 
> };
> +static const char * const imx_sai2_mclk1_sels[] = {"sai2_root", "sai2_mclk", 
> };
> +static const char * const imx_sai3_mclk1_sels[] = {"sai3_root", "sai3_mclk", 
> };
> +static const char * const imx_sai5_mclk1_sels[] = {"sai5_root", "sai5_mclk", 
> };
> +static const char * const imx_sai6_mclk1_sels[] = {"sai6_root", "sai6_mclk", 
> };
> +static const char * const imx_sai7_mclk1_sels[] = {"sai7_root", "sai7_mclk", 
> };
> +static const char * const imx_pdm_sels[] = {"pdm_root", "sai_pll_div2", 
> "dummy", "dummy" };
> +static const char * const imx_sai_pll_ref_sels[] = {"osc_24m", "dummy", 
> "dummy", "dummy", };
> +static const char * const imx_sai_pll_bypass_sels[] = {"sai_pll", 
> "sai_pll_ref_sel", };
> +
> +static struct imx_blk_ctrl_hw imx8mp_audio_blk_ctrl_hws[] = {
> +   /* clocks */
> +   IMX_BLK_CTRL_CLK_MUX("sai_pll_ref_sel", 
> IMX8MP_CLK_AUDIO_BLK_CTRL_SAI_PLL_REF_SEL, 0x400, 0, 2, imx_sai_pll_ref_sels),
> +   IMX_BLK_CTRL_CLK_PLL14XX("sai_pll", 
> IMX8MP_CLK_AUDIO_BLK_CTRL_SAI_PLL, 0x400, "sai_pll_ref_sel", 
> _blk_ctrl_sai_pll),
> +   IMX_BLK_CTRL_CLK_MUX_FLAGS("sai_pll_bypass", 
> IMX8MP_CLK_AUDIO_BLK_CTRL_SAI_PLL_BYPASS, 0x400, 4, 1, 
> imx_sai_pll_bypass_sels, CLK_SET_RATE_PARENT),
> +   IMX_BLK_CTRL_CLK_GATE("sai_pll_out", 
> IMX8MP_CLK_AUDIO_BLK_CTRL_SAI_PLL_OUT, 0x400, 13, "sai_pll_bypass"),
> +   IMX_BLK_CTRL_CLK_MUX_FLAGS("sai1_mclk1_sel", 
> IMX8MP_CLK_AUDIO_BLK_CTRL_SAI1_MCLK1_SEL, 0x300, 0, 1, imx_sai1_mclk1_sels, 
> 

Re: [PATCH v2 11/17] clk: imx: Add blk_ctrl combo driver

2020-08-18 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
>
> On i.MX8MP, there is a new type of IP which is called BLK_CTRL in
> RM and usually is comprised of some GPRs that are considered too
> generic to be part of any dedicated IP from that specific subsystem.
>
> In general, some of the GPRs have some clock bits, some have reset bits,
> so in order to be able to use the imx clock API, this needs to be
> in a clock driver. From there it can use the reset controller API and
> leave the rest to the syscon.
>
> This driver is intended to work with the following BLK_CTRL IPs found in
> i.MX8MP (but it might be reused by the future i.MX platforms that
> have this kind of IP in their design):
>  - Audio
>  - Media
>  - HDMI
>
> Signed-off-by: Abel Vesa 

The code mostly looks good to me.
Only a few minor comments.

> ---
>  drivers/clk/imx/Makefile   |   2 +-
>  drivers/clk/imx/clk-blk-ctrl.c | 327 
> +
>  drivers/clk/imx/clk-blk-ctrl.h |  81 ++
>  3 files changed, 409 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/imx/clk-blk-ctrl.c
>  create mode 100644 drivers/clk/imx/clk-blk-ctrl.h
>
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 928f874c..7afe1df 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -27,7 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
>
>  obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
>  obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
> -obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
> +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctrl.o
>  obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
>  obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
>
> diff --git a/drivers/clk/imx/clk-blk-ctrl.c b/drivers/clk/imx/clk-blk-ctrl.c
> new file mode 100644
> index ..1672646
> --- /dev/null
> +++ b/drivers/clk/imx/clk-blk-ctrl.c
> @@ -0,0 +1,327 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2020 NXP.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "clk.h"
> +#include "clk-blk-ctrl.h"
> +
> +struct reset_hw {

s/reset_hw/imx_reset_hw
It helps the reader to quickly understand it's not core structure

> +   u32 offset;
> +   u32 shift;
> +   u32 mask;
> +   bool asserted;
> +};
> +
> +struct pm_safekeep_info {

imx_pm_safekeep_info

> +   uint32_t *regs_values;
> +   uint32_t *regs_offsets;
> +   uint32_t regs_num;
> +};
> +
> +struct imx_blk_ctrl_drvdata {
> +   void __iomem *base;
> +   struct reset_controller_dev rcdev;
> +   struct reset_hw *rst_hws;
> +   struct pm_safekeep_info pm_info;
> +
> +   spinlock_t lock;
> +};
> +
> +static int imx_blk_ctrl_reset_set(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> +   struct imx_blk_ctrl_drvdata *drvdata = container_of(rcdev,
> +   struct imx_blk_ctrl_drvdata, rcdev);
> +   unsigned int offset = drvdata->rst_hws[id].offset;
> +   unsigned int shift = drvdata->rst_hws[id].shift;
> +   unsigned int mask = drvdata->rst_hws[id].mask;
> +   void __iomem *reg_addr = drvdata->base + offset;
> +   unsigned long flags;
> +   unsigned int asserted_before = 0, asserted_after = 0;

swap above two lines from long to short

> +   u32 reg;
> +   int i;
> +
> +   spin_lock_irqsave(>lock, flags);
> +
> +   for (i = 0; i < drvdata->rcdev.nr_resets; i++)
> +   if (drvdata->rst_hws[i].asserted)
> +   asserted_before++;
> +
> +   if (asserted_before == 0 && assert)
> +   pm_runtime_get(rcdev->dev);
> +
> +   if (assert) {
> +   reg = readl(reg_addr);
> +   writel(reg & ~(mask << shift), reg_addr);
> +   drvdata->rst_hws[id].asserted = true;
> +   } else {
> +   reg = readl(reg_addr);
> +   writel(reg | (mask << shift), reg_addr);
> +   drvdata->rst_hws[id].asserted = false;
> +   }
> +
> +   for (i = 0; i < drvdata->rcdev.nr_resets; i++)
> +   if (drvdata->rst_hws[i].asserted)
> +   asserted_after++;

I guess the logic may be able to be simplified.
For example, put assert ref count in the private structure.
Then
call pm_runtime_get when ref count is 0 and assert is true.
call pm_runtime_put when ref ount is 0 and assert is false.
No need to go through twice for loop each time.

> +
> +   if (asserted_before == 1 && asserted_after == 0)
> +   pm_runtime_put(rcdev->dev);
> +
> +   spin_unlock_irqrestore(>lock, flags);
> +
> +   return 0;
> +}
> +
> +static int imx_blk_ctrl_reset_assert(struct reset_controller_dev *rcdev,
> +  unsigned long id)
> +{
> +   return imx_blk_ctrl_reset_set(rcdev, id, true);
> +}

Re: [PATCH v2 10/17] Documentation: bindings: clk: Add bindings for i.MX BLK_CTRL

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:14 PM Abel Vesa  wrote:
>
> Document the i.MX BLK_CTRL with its devicetree properties.
>
> Signed-off-by: Abel Vesa 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 09/17] arm64: dts: Remove imx-hdmimix-reset header file

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:13 PM Abel Vesa  wrote:
>
> The hdmi BLK_CTRL ids have been moved to imx8mp-reset.h
>
> Signed-off-by: Abel Vesa 

The change seems do not comply with the patch title?

Regards
Aisheng

> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 9de2aa1..daa1769 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -4,6 +4,7 @@
>   */
>
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> --
> 2.7.4
>


Re: [PATCH v2 08/17] clk: imx8mp: Add audio shared gate

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:12 PM Abel Vesa  wrote:
>
> According to the RM, the CCGR101 is shared for the following root clocks:
> - AUDIO_AHB_CLK_ROOT
> - AUDIO_AXI_CLK_ROOT
> - SAI2_CLK_ROOT
> - SAI3_CLK_ROOT
> - SAI5_CLK_ROOT
> - SAI6_CLK_ROOT
> - SAI7_CLK_ROOT
> - PDM_CLK_ROOT
>
> Signed-off-by: Abel Vesa 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 07/17] dt-bindings: reset: imx8mp: Add hdmi blk_ctrl reset IDs

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:13 PM Abel Vesa  wrote:
>
> These will be used imx8mp for blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> Acked-by: Rob Herring 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 05/17] dt-bindings: reset: imx8mp: Add media blk_ctrl reset IDs

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:13 PM Abel Vesa  wrote:
>
> These will be used by the imx8mp for blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> Acked-by: Rob Herring 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 04/17] dt-bindings: clock: imx8mp: Add media blk_ctrl clock IDs

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:14 PM Abel Vesa  wrote:
>
> These will be used by the imx8mp for blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 
> Acked-by: Rob Herring 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 03/17] dt-bindings: clock: imx8mp: Add ids for the audio shared gate

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:13 PM Abel Vesa  wrote:
>
> All these IDs are for one single HW gate (CCGR101) that is shared
> between these root clocks.
>
> Signed-off-by: Abel Vesa 
> Acked-by: Rob Herring 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 02/17] dt-bindings: reset: imx8mp: Add audio blk_ctrl reset IDs

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:13 PM Abel Vesa  wrote:
>
> These will be used by the imx8mp for blk-ctrl driver.
>
> Signed-off-by: Abel Vesa 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [PATCH v2 01/17] dt-bindings: clocks: imx8mp: Rename audiomix ids clocks to audio_blk_ctrl

2020-08-17 Thread Dong Aisheng
On Fri, Aug 14, 2020 at 8:14 PM Abel Vesa  wrote:
>
> In the reference manual the actual name is Audio BLK_CTRL.
> Lets make it more obvious here by renaming from audiomix to audio_blk_ctrl.
>
> Signed-off-by: Abel Vesa 

As there's still no users of the old definitions, it's okay for me to
change it now.
Reviewed-by: Dong Aisheng 

Regards
Aisheng

> ---
>  include/dt-bindings/clock/imx8mp-clock.h | 120 
> +++
>  1 file changed, 60 insertions(+), 60 deletions(-)
>
> diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
> b/include/dt-bindings/clock/imx8mp-clock.h
> index 7a23f28..6008f32 100644
> --- a/include/dt-bindings/clock/imx8mp-clock.h
> +++ b/include/dt-bindings/clock/imx8mp-clock.h
> @@ -324,66 +324,66 @@
>
>  #define IMX8MP_CLK_END 313
>
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG   0
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2 2
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3 3
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_IPG   4
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1 5
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2 6
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3 7
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_IPG   8
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1 9
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2 10
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3 11
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_IPG   12
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1 13
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2 14
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3 15
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_IPG   16
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1 17
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2 18
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3 19
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_IPG   20
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1 21
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2 22
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3 23
> -#define IMX8MP_CLK_AUDIOMIX_ASRC_IPG   24
> -#define IMX8MP_CLK_AUDIOMIX_PDM_IPG25
> -#define IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT 26
> -#define IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT 27
> -#define IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT 28
> -#define IMX8MP_CLK_AUDIOMIX_DSP_ROOT   29
> -#define IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT30
> -#define IMX8MP_CLK_AUDIOMIX_EARC_IPG   31
> -#define IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG 32
> -#define IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG33
> -#define IMX8MP_CLK_AUDIOMIX_EDMA_ROOT  34
> -#define IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT35
> -#define IMX8MP_CLK_AUDIOMIX_MU2_ROOT   36
> -#define IMX8MP_CLK_AUDIOMIX_MU3_ROOT   37
> -#define IMX8MP_CLK_AUDIOMIX_EARC_PHY   38
> -#define IMX8MP_CLK_AUDIOMIX_PDM_ROOT   39
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL 40
> -#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL 41
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL 42
> -#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL 43
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL 44
> -#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL 45
> -#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK1_SEL 46
> -#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK2_SEL 47
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL 48
> -#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL 49
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL 50
> -#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL 51
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL 52
> -#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL 53
> -#define IMX8MP_CLK_AUDIOMIX_PDM_SEL54
> -#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL55
> -#define IMX8MP_CLK_AUDIOMIX_SAI_PLL56
> -#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS 57
> -#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT58
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI1_IPG 0
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI1_MCLK1   1
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI1_MCLK2   2
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI1_MCLK3   3
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_IPG 4
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_MCLK1   5
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_MCLK2   6
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_MCLK3   7
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_IPG 8
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1   9
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK2   10
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK3   11
> +#define IMX8MP_CLK_AUDIO_BLK_CTRL_SAI5_

Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock driver as module

2020-07-02 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 2:11 PM Anson Huang  wrote:
>
> > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock
> > driver as module
> >
> > On Thu, Jul 2, 2020 at 11:26 AM Anson Huang 
> > wrote:
> > [...]
> > > > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val)  static int
> > > > > imx_keep_uart_clocks;  static struct clk ** const
> > > > > *imx_uart_clocks;
> > > > >
> > > > > -static int __init imx_keep_uart_clocks_param(char *str)
> > > > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str)
> > > > >  {
> > > > > imx_keep_uart_clocks = 1;
> > > > >
> > > > > return 0;
> > > > >  }
> > > > > +#ifndef MODULE
> > > > >  __setup_param("earlycon", imx_keep_uart_earlycon,
> > > > >   imx_keep_uart_clocks_param, 0);
> > > > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk,
> > > > >   imx_keep_uart_clocks_param, 0);
> > > >
> > > > I feel not only the __setup_param, the whole logic of
> > > > keep_uart_clocks are not needed for Module case. Is it true?
> > >
> > > Yes, but the 'keep_uart_clocks' is false by default and the function
> > > imx_keep_uart_clocks_param() already has '__maybe_unused', it does NOT
> > > impact anything if it is for module build, so I did NOT add the #ifndef 
> > > check
> > for them, just to keep code easy and clean.
> > >
> >
> > IMHO do not compile them is a more easy and clean way. Then users don't
> > have to look into the code logic which is meaingless for Module case.
> >
> > BTW, it really does not make any sense to only condionally compile
> > __setup_parm() but left
> > the param functions definition to be handled by __maybe_unnused.
> > They're together part of code, aren't they?
>
> I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() and 
> imx_keep_uart_clocks_param()
> as well in next patch series. Others like ' imx_keep_uart_clocks ' and 
> imx_register_uart_clocks() need to
> be kept always built, since they are used by each clock driver no matter 
> built-in or module build.
>
> So that means I have to add another 'ifndef MODULE' or I need to adjust some 
> code sequence to make
> those code can be built-out in same block and just use single 'ifndef 
> MODULE', I think adjust the code
> sequence should be better, will go with this way.

What if we  condionally compile it in clk.h? Will that be easiser?

Regards
Aisheng

>
> Anson


Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock driver as module

2020-07-01 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 11:26 AM Anson Huang  wrote:
[...]
> > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val)
> > >  static int imx_keep_uart_clocks;
> > >  static struct clk ** const *imx_uart_clocks;
> > >
> > > -static int __init imx_keep_uart_clocks_param(char *str)
> > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str)
> > >  {
> > > imx_keep_uart_clocks = 1;
> > >
> > > return 0;
> > >  }
> > > +#ifndef MODULE
> > >  __setup_param("earlycon", imx_keep_uart_earlycon,
> > >   imx_keep_uart_clocks_param, 0);
> > >  __setup_param("earlyprintk", imx_keep_uart_earlyprintk,
> > >   imx_keep_uart_clocks_param, 0);
> >
> > I feel not only the __setup_param, the whole logic of keep_uart_clocks
> > are not needed for Module case. Is it true?
>
> Yes, but the 'keep_uart_clocks' is false by default and the function 
> imx_keep_uart_clocks_param()
> already has '__maybe_unused', it does NOT impact anything if it is for module 
> build, so I did NOT
> add the #ifndef check for them, just to keep code easy and clean.
>

IMHO do not compile them is a more easy and clean way. Then users
don't have to look into the code logic
which is meaingless for Module case.

BTW, it really does not make any sense to only condionally compile
__setup_parm() but left
the param functions definition to be handled by __maybe_unnused.
They're together part of code, aren't they?

Regards
Aisheng

Regards
Aisheng

> Thanks,
> Anson
>


Re: [PATCH V4 5/5] clk: imx8qxp: Support building i.MX8QXP clock driver as module

2020-07-01 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 11:55 AM Anson Huang  wrote:
[...]
> > > +{
> > > +   return platform_driver_register(_lpcg_clk_driver);
> > > +}
> > > +device_initcall(imx8qxp_lpcg_clk_init);
> >
> > Any reason to change to device_initcall which looks a bit strange?
> > Is it because the following line?
> > +obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
> > But it looks to me they're still two modules. Aren't they?
>
> It is suggested by Arnd to NOT use builtin_platform_driver(), in order to 
> support module
> unload, although the clock driver normally does NOT support remove, but it is 
> better to
> follow the right way.
>

By expanding builtin_platform_driver() marcro, you will find your
patch is exactly doing the same thing
as buildin_platform_driver() which obivously is unneccesary.

#define builtin_platform_driver(__platform_driver) \
builtin_driver(__platform_driver, platform_driver_register)
#define builtin_driver(__driver, __register, ...) \

static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
device_initcall(__driver##_init);

If we want to support unload, we need a .remove() callback as current
clocks are not allocated by devm_().
If don't support,  we probably can use builtin_platform_driver() first
and switch to module_platform_driver()
in the future once the driver supports release resource properly.

Regards
Aisheng

> The change in Makefile is just to link scu/lpcg library to i.MX8QXP clk 
> driver, so that we can
> get rid of exports and below 2 .ko are needed for all i.MX SoCs with SCU 
> inside as per your
> saying of i.MX8QXP clock driver can be extended for future SoCs with SCU.
>
> clk-imx-lpcg-scu.ko
> clk-imx-scu.ko
>
> Thanks,
> Anson


Re: [PATCH V4 5/5] clk: imx8qxp: Support building i.MX8QXP clock driver as module

2020-07-01 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 10:20 AM Anson Huang  wrote:
>
> Change configuration to "tristate", use device_initcall() instead
> of builtin_platform_driver(), add module author, description and
> license to support building i.MX8QXP clock drivers as module.
>
> Signed-off-by: Anson Huang 
> ---
> Changes since V3:
> - use device_initcall() instead of builtin_platform_driver();
> - add module author/description;
> - link common scu/lpcg clock driver to i.MX8QXP clock driver, then
>   no need to have exports.
> ---
>  drivers/clk/imx/Kconfig|  6 +++---
>  drivers/clk/imx/Makefile   |  9 -
>  drivers/clk/imx/clk-imx8qxp-lpcg.c | 10 +-
>  drivers/clk/imx/clk-imx8qxp.c  | 11 ++-
>  4 files changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index 1867111..8340dfe 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -5,8 +5,8 @@ config MXC_CLK
> depends on ARCH_MXC
>
>  config MXC_CLK_SCU
> -   bool
> -   depends on IMX_SCU
> +   tristate "IMX SCU clock"
> +   depends on ARCH_MXC && IMX_SCU
>
>  config CLK_IMX1
>   bool "IMX1 CCM Clock Driver"
> @@ -127,7 +127,7 @@ config CLK_IMX8MQ
> Build the driver for i.MX8MQ CCM Clock Driver
>
>  config CLK_IMX8QXP
> -   bool "IMX8QXP SCU Clock"
> +   tristate "IMX8QXP SCU Clock"
> depends on ARCH_MXC && IMX_SCU && ARM64
> select MXC_CLK_SCU
> help
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 17f5d12..79e53f2 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -21,15 +21,14 @@ mxc-clk-objs += clk-pll14xx.o
>  mxc-clk-objs += clk-sscg-pll.o
>  obj-$(CONFIG_MXC_CLK) += mxc-clk.o
>
> -obj-$(CONFIG_MXC_CLK_SCU) += \
> -   clk-scu.o \
> -   clk-lpcg-scu.o
> -
>  obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
>  obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
>  obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
>  obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
> -obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
> +
> +obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
> +clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o
> +clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
>
>  obj-$(CONFIG_CLK_IMX1)   += clk-imx1.o
>  obj-$(CONFIG_CLK_IMX21)  += clk-imx21.o
> diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c 
> b/drivers/clk/imx/clk-imx8qxp-lpcg.c
> index 04c8ee3..5b6648e 100644
> --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
> +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
> @@ -231,4 +231,12 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = {
> .probe = imx8qxp_lpcg_clk_probe,
>  };
>
> -builtin_platform_driver(imx8qxp_lpcg_clk_driver);
> +static int __init imx8qxp_lpcg_clk_init(void)

Does __init work for module?

> +{
> +   return platform_driver_register(_lpcg_clk_driver);
> +}
> +device_initcall(imx8qxp_lpcg_clk_init);

Any reason to change to device_initcall which looks a bit strange?
Is it because the following line?
+obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
But it looks to me they're still two modules. Aren't they?

Regards
Aisheng

> +
> +MODULE_AUTHOR("Aisheng Dong ");
> +MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
> index 5e2903e..9bcf0d1 100644
> --- a/drivers/clk/imx/clk-imx8qxp.c
> +++ b/drivers/clk/imx/clk-imx8qxp.c
> @@ -151,4 +151,13 @@ static struct platform_driver imx8qxp_clk_driver = {
> },
> .probe = imx8qxp_clk_probe,
>  };
> -builtin_platform_driver(imx8qxp_clk_driver);
> +
> +static int __init imx8qxp_clk_init(void)
> +{
> +   return platform_driver_register(_clk_driver);
> +}
> +device_initcall(imx8qxp_clk_init);
> +
> +MODULE_AUTHOR("Aisheng Dong ");
> +MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.7.4
>


Re: [PATCH V4 4/5] clk: imx8m: Support module build

2020-07-01 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 10:18 AM Anson Huang  wrote:
>
> Change configuration to "tristate", add module author, description
> and license to support building i.MX8M SoCs clock driver as module.
>
> Signed-off-by: Anson Huang 

Reviewed-by: Dong Aisheng 

Regards
Aisheng

> ---
> Changes since V3:
> - add module author/description, and merge all i.MX8M SoCs patch into
>   one patch.
> ---
>  drivers/clk/imx/Kconfig  | 8 
>  drivers/clk/imx/clk-imx8mm.c | 4 
>  drivers/clk/imx/clk-imx8mn.c | 4 
>  drivers/clk/imx/clk-imx8mp.c | 4 
>  drivers/clk/imx/clk-imx8mq.c | 4 
>  5 files changed, 20 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index f6ddf76..1867111 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -99,28 +99,28 @@ config CLK_VF610
>   select MXC_CLK
>
>  config CLK_IMX8MM
> -   bool "IMX8MM CCM Clock Driver"
> +   tristate "IMX8MM CCM Clock Driver"
> depends on ARCH_MXC
> select MXC_CLK
> help
> Build the driver for i.MX8MM CCM Clock Driver
>
>  config CLK_IMX8MN
> -   bool "IMX8MN CCM Clock Driver"
> +   tristate "IMX8MN CCM Clock Driver"
> depends on ARCH_MXC
> select MXC_CLK
> help
> Build the driver for i.MX8MN CCM Clock Driver
>
>  config CLK_IMX8MP
> -   bool "IMX8MP CCM Clock Driver"
> +   tristate "IMX8MP CCM Clock Driver"
> depends on ARCH_MXC
> select MXC_CLK
> help
> Build the driver for i.MX8MP CCM Clock Driver
>
>  config CLK_IMX8MQ
> -   bool "IMX8MQ CCM Clock Driver"
> +   tristate "IMX8MQ CCM Clock Driver"
> depends on ARCH_MXC
> select MXC_CLK
> help
> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
> index b793264..0de0be0 100644
> --- a/drivers/clk/imx/clk-imx8mm.c
> +++ b/drivers/clk/imx/clk-imx8mm.c
> @@ -657,3 +657,7 @@ static struct platform_driver imx8mm_clk_driver = {
> },
>  };
>  module_platform_driver(imx8mm_clk_driver);
> +
> +MODULE_AUTHOR("Bai Ping ");
> +MODULE_DESCRIPTION("NXP i.MX8MM clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> index 213cc37..e984de5 100644
> --- a/drivers/clk/imx/clk-imx8mn.c
> +++ b/drivers/clk/imx/clk-imx8mn.c
> @@ -608,3 +608,7 @@ static struct platform_driver imx8mn_clk_driver = {
> },
>  };
>  module_platform_driver(imx8mn_clk_driver);
> +
> +MODULE_AUTHOR("Anson Huang ");
> +MODULE_DESCRIPTION("NXP i.MX8MN clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
> index ca74771..f3cedf2 100644
> --- a/drivers/clk/imx/clk-imx8mp.c
> +++ b/drivers/clk/imx/clk-imx8mp.c
> @@ -773,3 +773,7 @@ static struct platform_driver imx8mp_clk_driver = {
> },
>  };
>  module_platform_driver(imx8mp_clk_driver);
> +
> +MODULE_AUTHOR("Anson Huang ");
> +MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index a64aace..a06cc21 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -643,3 +643,7 @@ static struct platform_driver imx8mq_clk_driver = {
> },
>  };
>  module_platform_driver(imx8mq_clk_driver);
> +
> +MODULE_AUTHOR("Abel Vesa ");
> +MODULE_DESCRIPTION("NXP i.MX8MQ clock driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.7.4
>


Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock driver as module

2020-07-01 Thread Dong Aisheng
On Thu, Jul 2, 2020 at 10:19 AM Anson Huang  wrote:
>
> There are more and more requirements of building SoC specific drivers
> as modules, add support for building i.MX common clock driver as module
> to meet the requirement.
>
> Signed-off-by: Anson Huang 
> ---
> Changes since V3:
> - ONLY include __setup_param() build for built-in, module build no 
> need
>   to have it.
> ---
>  drivers/clk/imx/Kconfig|  8 ++--
>  drivers/clk/imx/Makefile   | 40 
> +++---
>  drivers/clk/imx/clk-composite-8m.c |  2 ++
>  drivers/clk/imx/clk-cpu.c  |  2 ++
>  drivers/clk/imx/clk-frac-pll.c |  2 ++
>  drivers/clk/imx/clk-gate2.c|  2 ++
>  drivers/clk/imx/clk-pll14xx.c  |  5 +
>  drivers/clk/imx/clk-sscg-pll.c |  2 ++
>  drivers/clk/imx/clk.c  | 22 +++--
>  9 files changed, 57 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index 09fc8ad..f6ddf76 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -1,8 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
>  # common clock support for NXP i.MX SoC family.
>  config MXC_CLK
> -   bool
> -   def_bool ARCH_MXC
> +   tristate "IMX clock"
> +   depends on ARCH_MXC
>
>  config MXC_CLK_SCU
> bool
> @@ -101,24 +101,28 @@ config CLK_VF610
>  config CLK_IMX8MM
> bool "IMX8MM CCM Clock Driver"
> depends on ARCH_MXC
> +   select MXC_CLK
> help
> Build the driver for i.MX8MM CCM Clock Driver
>
>  config CLK_IMX8MN
> bool "IMX8MN CCM Clock Driver"
> depends on ARCH_MXC
> +   select MXC_CLK
> help
> Build the driver for i.MX8MN CCM Clock Driver
>
>  config CLK_IMX8MP
> bool "IMX8MP CCM Clock Driver"
> depends on ARCH_MXC
> +   select MXC_CLK
> help
> Build the driver for i.MX8MP CCM Clock Driver
>
>  config CLK_IMX8MQ
> bool "IMX8MQ CCM Clock Driver"
> depends on ARCH_MXC
> +   select MXC_CLK
> help
> Build the driver for i.MX8MQ CCM Clock Driver
>
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 394ade7..17f5d12 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -1,25 +1,25 @@
>  # SPDX-License-Identifier: GPL-2.0
>
> -obj-$(CONFIG_MXC_CLK) += \
> -   clk.o \
> -   clk-busy.o \
> -   clk-composite-8m.o \
> -   clk-cpu.o \
> -   clk-composite-7ulp.o \
> -   clk-divider-gate.o \
> -   clk-fixup-div.o \
> -   clk-fixup-mux.o \
> -   clk-frac-pll.o \
> -   clk-gate-exclusive.o \
> -   clk-gate2.o \
> -   clk-pfd.o \
> -   clk-pfdv2.o \
> -   clk-pllv1.o \
> -   clk-pllv2.o \
> -   clk-pllv3.o \
> -   clk-pllv4.o \
> -   clk-sscg-pll.o \
> -   clk-pll14xx.o
> +mxc-clk-objs += clk.o
> +mxc-clk-objs += clk-busy.o
> +mxc-clk-objs += clk-composite-7ulp.o
> +mxc-clk-objs += clk-composite-8m.o
> +mxc-clk-objs += clk-cpu.o
> +mxc-clk-objs += clk-divider-gate.o
> +mxc-clk-objs += clk-fixup-div.o
> +mxc-clk-objs += clk-fixup-mux.o
> +mxc-clk-objs += clk-frac-pll.o
> +mxc-clk-objs += clk-gate2.o
> +mxc-clk-objs += clk-gate-exclusive.o
> +mxc-clk-objs += clk-pfd.o
> +mxc-clk-objs += clk-pfdv2.o
> +mxc-clk-objs += clk-pllv1.o
> +mxc-clk-objs += clk-pllv2.o
> +mxc-clk-objs += clk-pllv3.o
> +mxc-clk-objs += clk-pllv4.o
> +mxc-clk-objs += clk-pll14xx.o
> +mxc-clk-objs += clk-sscg-pll.o
> +obj-$(CONFIG_MXC_CLK) += mxc-clk.o
>
>  obj-$(CONFIG_MXC_CLK_SCU) += \
> clk-scu.o \
> diff --git a/drivers/clk/imx/clk-composite-8m.c 
> b/drivers/clk/imx/clk-composite-8m.c
> index d2b5af8..78fb7e5 100644
> --- a/drivers/clk/imx/clk-composite-8m.c
> +++ b/drivers/clk/imx/clk-composite-8m.c
> @@ -5,6 +5,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -243,3 +244,4 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char 
> *name,
> kfree(mux);
> return ERR_CAST(hw);
>  }
> +EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags);
> diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c
> index cb182be..cb6ca4c 100644
> --- a/drivers/clk/imx/clk-cpu.c
> +++ b/drivers/clk/imx/clk-cpu.c
> @@ -5,6 +5,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include "clk.h"
>
> @@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const 
> char *parent_name,
>
> return hw;
>  }
> +EXPORT_SYMBOL_GPL(imx_clk_hw_cpu);
> diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c
> index 101e0a3..c703056 100644
> --- a/drivers/clk/imx/clk-frac-pll.c
> +++ b/drivers/clk/imx/clk-frac-pll.c
> @@ -10,6 +10,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name,
>
> return hw;
>  }
> 

Re: [PATCH V3 04/10] clk: imx: Support building SCU clock driver as module

2020-06-29 Thread Dong Aisheng
On Tue, Jun 30, 2020 at 5:16 AM Anson Huang  wrote:
>
> Hi, Arnd
>
>
> > Subject: Re: [PATCH V3 04/10] clk: imx: Support building SCU clock driver as
> > module
> >
> > On Mon, Jun 29, 2020 at 4:52 PM Anson Huang 
> > wrote:
> > > > Subject: Re: [PATCH V3 04/10] clk: imx: Support building SCU clock
> > > > driver as module On Mon, Jun 29, 2020 at 2:53 PM Anson Huang
> >  wrote:
> > > >
> > > > Sorry, I misread the patch in multiple ways. First of all, you
> > > > already put clk-scu.o and clk-lpcg-scu.o files into a combined
> > > > loadable module, and I had only looked at clk-scu.c.
> > > >
> > > > What I actually meant here was to link clk-scu.o together with
> > > > clk-imx8qxp.o (and possibly future chip-specific files) into a
> > > > loadable module and drop the export.
> > >
> > > Sorry, could you please advise more details about how to do it in 
> > > Makefile?
> > > I tried below but it looks like NOT working. multiple definition of
> > module_init() error reported.
> > >
> > > obj-$(CONFIG_MXC_CLK_SCU) := clk-imx.o clk-imx-y += clk-scu.o
> > > clk-lpcg-scu.o
> > > clk-imx-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
> >
> > Right, you can't have multiple module_init() in a module, so what I 
> > suggested
> > earlier won't work any more as soon as you add a second chip that uses the
> > clk-scu driver, and then you have to use separate modules, or some hack that
> > calls the init functions one at a time, which is probably worse.
> >
> > If it's only imx8qxp, you can do it like this:
> >
> > obj-$(CONFIG_MXC_CLK_SCU) := clk-imx-scu.o clk-imx-lpcg.o
> > clk-imx-scu-y += clk-scu.o clk-imx8qxp.o
> > clk-imx-lpcq-scu-y += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
> >
> > If you already know that the scu driver is going to be used in future 
> > chips, then
> > just stay with what you have now, using a separate module per file, 
> > exporting
> > the symbols as needed.
> >
>
> Thanks, and yes, I know that scu clk driver will be used for future i.MX8X 
> chips with
> SCU inside, the current i.MX8QXP clock driver can NOT cover all i.MX8X chips, 
> so
> I will stay with the exporting symbols.
>

SCU clock driver is a common driver for all SCU based platforms.
Current i.MX8QXP SCU clock driver will be extended to support all
future SCU based platforms.
So theoretically clk-scu.o and clk-imx8qxp.o can be combined. LPCG  is similar.
Maybe you can give a try as Arnd suggested.

Regards
Aisheng

> Thanks,
> Anson


Re: [PATCH V3 04/10] clk: imx: Support building SCU clock driver as module

2020-06-29 Thread Dong Aisheng
On Tue, Jun 30, 2020 at 3:36 AM Arnd Bergmann  wrote:
>
> On Mon, Jun 29, 2020 at 2:53 PM Anson Huang  wrote:
> > > Subject: Re: [PATCH V3 04/10] clk: imx: Support building SCU clock driver 
> > > as
> > > module
> > >
> > > On Mon, Jun 29, 2020 at 8:06 AM Anson Huang 
> > > wrote:
> > >
> > > > --- a/drivers/clk/imx/Makefile
> > > > +++ b/drivers/clk/imx/Makefile
> > > > @@ -21,9 +21,9 @@ obj-$(CONFIG_MXC_CLK) += \
> > > > clk-sscg-pll.o \
> > > > clk-pll14xx.o
> > > >
> > > > -obj-$(CONFIG_MXC_CLK_SCU) += \
> > > > -   clk-scu.o \
> > > > -   clk-lpcg-scu.o
> > > > +mxc-clk-scu-objs += clk-lpcg-scu.o
> > > > +mxc-clk-scu-objs += clk-scu.o
> > > > +obj-$(CONFIG_MXC_CLK_SCU) += mxc-clk-scu.o
> > >
> > > It looks like the two modules are tightly connected, one is useless 
> > > without the
> > > other. How about linking them into a combined module and dropping the
> > > export statement?
> > >
> >
> > From HW perspective, the SCU clock driver and LPCG SCU clock driver are 
> > different,
> > SCU clock driver is for those clocks controlled by system controller (M4 
> > which runs a firmware),
> > while LPCG SCU clock is for those clock gates inside module, which means AP 
> > core can
> > control it directly via register access, no need to via SCU API.
>
> Sorry, I misread the patch in multiple ways. First of all, you already put
> clk-scu.o and clk-lpcg-scu.o files into a combined loadable module, and
> I had only looked at clk-scu.c.
>
> What I actually meant here was to link clk-scu.o together with clk-imx8qxp.o
> (and possibly future chip-specific files) into a loadable module and drop
> the export.

It sounds like a good idea to me.
Actually I planned to combine them into one driver in the future.

Regards
Aisheng

>
> > So, I think it is NOT that tightly connected, it is because they are both 
> > for i.MX8 SoCs with SCU
> > inside, so they are put together in the Makefile.
> >
> > If the export statement is acceptable, I think it is better to just keep 
> > it, make sense?
>
> There is nothing wrong with the export as such, this was just an
> idea to simplify the logic.
>
>   Arnd


Re: [PATCH V2 3/9] clk: imx: Support building SCU clock driver as module

2020-06-29 Thread Dong Aisheng
On Thu, Jun 25, 2020 at 6:43 AM Stephen Boyd  wrote:
>
> Quoting Aisheng Dong (2020-06-23 19:59:09)
> > > > > > -   bool
> > > > > > -   def_bool ARCH_MXC
> > > > > > +   tristate "IMX clock"
> > > > > > +   depends on ARCH_MXC
> > > > > >
> > > > > > But user can still set MXC_CLK to be m, either via make menuconfig
> > > > > > or
> > > > > defconfig.
> > > > >
> > > > > Isn't that what we want?
> > > >
> > > > No, if user set MXC_CLK to m, the build will break for i.MX6&7.
> > > >
> > > > > Why does ARCH_MXC being enabled mandate that it is builtin? Is some
> > > > > architecture level code calling into the clk driver?
> > > >
> > > >
> > > > It's mainly because there's no Kconfig options for i.MX6 &7 clock 
> > > > drivers.
> > > > It just reuses ARCH config CONFIG_SOC_XXX which can only be y.
> > > > e.g.
> > > > obj-$(CONFIG_SOC_IMX6Q)  += clk-imx6q.o
> > > > obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
> > > > obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o
> > > > obj-$(CONFIG_SOC_VF610)  += clk-vf610.o ..
> > > >
> > > > If setting MXC_CLK to m, the platform clock drivers will fail to build
> > > > due to miss to find symbols defined in the common clock library by
> > > > CONFIG_MXC_CLK.
> > > > So we have to avoid users to be able to config MXC_CLK to m for i.MX6&7.
> > > > Only depends on ARCH_MXC mean user still can set it to m.
> > >
> > > I think for i.MX6/7, although MXC_CLK is tristate, but it is selected by
> > > ARCH_MXC which is always "y", so MXC_CLK can ONLY be "y" even it is 
> > > explicitly
> > > set to "m" in imx_v6_v7_defconfig file. So that means MXC_CLK can ONLY
> > > support built-in for i.MX6/7 SoCs, and that is what we want?
> > >
> >
> > Yes, I'm trying to explain to Stephen why we have to select MXC_CLK in 
> > ARCH_MXC
> > And what issues we will met if not select it.
> >
>
> Why aren't there options to enable clk-imx6q and clk-imx6sl in the
> clk/imx/Kconfig file? Those can be bool or tristate depending on if the
> SoC drivers use CLK_OF_DECLARE or not and depend on the mxc-clk library
> and SoC config we have in the makefile today.

Yes, we can do that in clk/imx/Kconfig as follows theoretically.
config CLK_IMX6Q
bool
def_bool ARCH_MXC && ARM
select MXC_CLK

But we have totally 15 platforms that need to change.
e.g.
drivers/clk/imx/Makefile
obj-$(CONFIG_SOC_IMX1)   += clk-imx1.o
obj-$(CONFIG_SOC_IMX21)  += clk-imx21.o
obj-$(CONFIG_SOC_IMX25)  += clk-imx25.o
obj-$(CONFIG_SOC_IMX27)  += clk-imx27.o
obj-$(CONFIG_SOC_IMX31)  += clk-imx31.o
obj-$(CONFIG_SOC_IMX35)  += clk-imx35.o
obj-$(CONFIG_SOC_IMX5)   += clk-imx5.o
obj-$(CONFIG_SOC_IMX6Q)  += clk-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_SOC_IMX7D)  += clk-imx7d.o
obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o
obj-$(CONFIG_SOC_VF610)  += clk-vf610.o

Not sure if it's really worth to do that.
The easiest way to address this issue is just select it in
arch/arm/mach-imx/Kconfig,
then no need to change those 15 clock config options or just builtin
clk libraries.

Stephen,
which one do you prefer?

Regards
Aisheng


Re: [PATCH] clk: imx: lpcg: write twice when writing lpcg regs

2019-09-09 Thread Dong Aisheng
On Sat, Sep 7, 2019 at 9:47 PM Stephen Boyd  wrote:
>
> Quoting Peng Fan (2019-08-27 01:17:50)
> > From: Peng Fan 
> >
> > There is hardware issue that:
> > The output clock the LPCG cell will not turn back on as expected,
> > even though a read of the IPG registers in the LPCG indicates that
> > the clock should be enabled.
> >
> > The software workaround is to write twice to enable the LPCG clock
> > output.
> >
> > Signed-off-by: Peng Fan 
>
> Does this need a Fixes tag?

Not sure as it's not code logic issue but a hardware bug.
And 4.19 LTS still have not this driver support.

Regards
Aisheng

>


Re: [PATCH] clk: imx: lpcg: write twice when writing lpcg regs

2019-09-09 Thread Dong Aisheng
On Tue, Aug 27, 2019 at 4:19 PM Peng Fan  wrote:
>
> From: Peng Fan 
>
> There is hardware issue that:
> The output clock the LPCG cell will not turn back on as expected,
> even though a read of the IPG registers in the LPCG indicates that
> the clock should be enabled.
>
> The software workaround is to write twice to enable the LPCG clock
> output.
>
> Signed-off-by: Peng Fan 

Reviewed-by: Dong Aisheng 

Regards
Aisheng


Re: [EXT] Re: [PATCH] mailbox: imx: add support for imx v1 mu

2019-07-28 Thread Dong Aisheng
On Mon, Jul 29, 2019 at 11:03 AM Richard Zhu  wrote:
>
> Hi Aisheng:
> Thanks for your comments.
>
> > -Original Message-----
> > From: Dong Aisheng 
> > Sent: 2019年7月29日 10:35
> > To: Richard Zhu 
> > Cc: jassisinghb...@gmail.com; Oleksij Rempel ;
> > Aisheng Dong ; open list
> > ; moderated list:ARM/FREESCALE IMX / MXC
> > ARM ARCHITECTURE 
> > Subject: [EXT] Re: [PATCH] mailbox: imx: add support for imx v1 mu
> >
> > On Mon, Jul 29, 2019 at 10:36 AM Richard Zhu 
> > wrote:
> > >
> > > There is a version1.0 MU on i.MX7ULP platform.
> > > One new version ID register is added, and it's offset is 0.
> > > TRn registers are defined at the offset 0x20 ~ 0x2C.
> > > RRn registers are defined at the offset 0x40 ~ 0x4C.
> > > SR/CR registers are defined at 0x60/0x64.
> > > Extend this driver to support it.
> > >
> >
> > If only the register base offset is different, there's probably a more 
> > simple way.
> > Please refer to:
> >
> [Richard Zhu] TRx, RRx and the CR/SR have the different offset addresses.
> That means three different offset addresses should be manipulated if the 
> solution listed above is used.
> It seems that it's a little complex, and maybe introduce bugs when different 
> offset address is manipulated.
> According, the current method suggested by Oleksij is much clear, and easy to 
> extend for future extension.
>

I missed that.
Maybe the patch title should be V2 and add Suggested-by: tag to
reminder reviewer
it's a new version?

If there're multiple offset differences. I'm fine with this way.
Feel free to add my tag.
Reviewed-by: Dong Aisheng 

Regards
Aisheng

> Hi Olekiji:
> How do you think about?
>
> Best Regards
> Richard Zhu
>
> > Regards
> > Aisheng
> >
> > > Signed-off-by: Richard Zhu 
> > > ---
> > >  drivers/mailbox/imx-mailbox.c | 67
> > > ---
> > >  1 file changed, 50 insertions(+), 17 deletions(-)
> > >
> > > diff --git a/drivers/mailbox/imx-mailbox.c
> > > b/drivers/mailbox/imx-mailbox.c index 25be8bb..8423a38 100644
> > > --- a/drivers/mailbox/imx-mailbox.c
> > > +++ b/drivers/mailbox/imx-mailbox.c
> > > @@ -12,19 +12,11 @@
> > >  #include 
> > >  #include 
> > >
> > > -/* Transmit Register */
> > > -#define IMX_MU_xTRn(x) (0x00 + 4 * (x))
> > > -/* Receive Register */
> > > -#define IMX_MU_xRRn(x) (0x10 + 4 * (x))
> > > -/* Status Register */
> > > -#define IMX_MU_xSR 0x20
> > >  #define IMX_MU_xSR_GIPn(x) BIT(28 + (3 - (x)))
> > >  #define IMX_MU_xSR_RFn(x)  BIT(24 + (3 - (x)))
> > >  #define IMX_MU_xSR_TEn(x)  BIT(20 + (3 - (x)))
> > >  #define IMX_MU_xSR_BRDIP   BIT(9)
> > >
> > > -/* Control Register */
> > > -#define IMX_MU_xCR 0x24
> > >  /* General Purpose Interrupt Enable */
> > >  #define IMX_MU_xCR_GIEn(x) BIT(28 + (3 - (x)))
> > >  /* Receive Interrupt Enable */
> > > @@ -44,6 +36,13 @@ enum imx_mu_chan_type {
> > > IMX_MU_TYPE_RXDB,   /* Rx doorbell */
> > >  };
> > >
> > > +struct imx_mu_dcfg {
> > > +   u32 xTR[4]; /* Transmit Registers */
> > > +   u32 xRR[4]; /* Receive Registers */
> > > +   u32 xSR;/* Status Register */
> > > +   u32 xCR;/* Control Register */
> > > +};
> > > +
> > >  struct imx_mu_con_priv {
> > > unsigned intidx;
> > > char
> > irq_desc[IMX_MU_CHAN_NAME_SIZE];
> > > @@ -61,12 +60,39 @@ struct imx_mu_priv {
> > > struct mbox_chanmbox_chans[IMX_MU_CHANS];
> > >
> > > struct imx_mu_con_priv  con_priv[IMX_MU_CHANS];
> > > +   const struct imx_mu_dcfg*dcfg;
> > > struct clk  *clk;
> > > int irq;
> > >
> > > boolside_b;
> > >  };
> > >
> > > +static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
> > > +   .xTR[0] = 0x0,
> > > +   .xTR[1] = 0x4,
> > > +   .xTR[2] = 0x8,
> > > +   .xTR[3] = 0xC,
> > > +   .xRR[0] = 0x10,
> > > +   .xRR[1] = 0x14,
> > > +   .xRR[2] = 0x18,
> > > +   .xRR[3] = 0x1C,
> > > +   .xSR= 0x20,
> > > +   .xCR

Re: [PATCH] mailbox: imx: add support for imx v1 mu

2019-07-28 Thread Dong Aisheng
On Mon, Jul 29, 2019 at 10:36 AM Richard Zhu  wrote:
>
> There is a version1.0 MU on i.MX7ULP platform.
> One new version ID register is added, and it's offset is 0.
> TRn registers are defined at the offset 0x20 ~ 0x2C.
> RRn registers are defined at the offset 0x40 ~ 0x4C.
> SR/CR registers are defined at 0x60/0x64.
> Extend this driver to support it.
>

If only the register base offset is different, there's probably a more
simple way.
Please refer to:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/tty/serial/fsl_lpuart.c?id=24b1e5f0e83c2aced8096473d20c4cf6c1355f30

Regards
Aisheng

> Signed-off-by: Richard Zhu 
> ---
>  drivers/mailbox/imx-mailbox.c | 67 
> ---
>  1 file changed, 50 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
> index 25be8bb..8423a38 100644
> --- a/drivers/mailbox/imx-mailbox.c
> +++ b/drivers/mailbox/imx-mailbox.c
> @@ -12,19 +12,11 @@
>  #include 
>  #include 
>
> -/* Transmit Register */
> -#define IMX_MU_xTRn(x) (0x00 + 4 * (x))
> -/* Receive Register */
> -#define IMX_MU_xRRn(x) (0x10 + 4 * (x))
> -/* Status Register */
> -#define IMX_MU_xSR 0x20
>  #define IMX_MU_xSR_GIPn(x) BIT(28 + (3 - (x)))
>  #define IMX_MU_xSR_RFn(x)  BIT(24 + (3 - (x)))
>  #define IMX_MU_xSR_TEn(x)  BIT(20 + (3 - (x)))
>  #define IMX_MU_xSR_BRDIP   BIT(9)
>
> -/* Control Register */
> -#define IMX_MU_xCR 0x24
>  /* General Purpose Interrupt Enable */
>  #define IMX_MU_xCR_GIEn(x) BIT(28 + (3 - (x)))
>  /* Receive Interrupt Enable */
> @@ -44,6 +36,13 @@ enum imx_mu_chan_type {
> IMX_MU_TYPE_RXDB,   /* Rx doorbell */
>  };
>
> +struct imx_mu_dcfg {
> +   u32 xTR[4]; /* Transmit Registers */
> +   u32 xRR[4]; /* Receive Registers */
> +   u32 xSR;/* Status Register */
> +   u32 xCR;/* Control Register */
> +};
> +
>  struct imx_mu_con_priv {
> unsigned intidx;
> charirq_desc[IMX_MU_CHAN_NAME_SIZE];
> @@ -61,12 +60,39 @@ struct imx_mu_priv {
> struct mbox_chanmbox_chans[IMX_MU_CHANS];
>
> struct imx_mu_con_priv  con_priv[IMX_MU_CHANS];
> +   const struct imx_mu_dcfg*dcfg;
> struct clk  *clk;
> int irq;
>
> boolside_b;
>  };
>
> +static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
> +   .xTR[0] = 0x0,
> +   .xTR[1] = 0x4,
> +   .xTR[2] = 0x8,
> +   .xTR[3] = 0xC,
> +   .xRR[0] = 0x10,
> +   .xRR[1] = 0x14,
> +   .xRR[2] = 0x18,
> +   .xRR[3] = 0x1C,
> +   .xSR= 0x20,
> +   .xCR= 0x24,
> +};
> +
> +static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
> +   .xTR[0] = 0x20,
> +   .xTR[1] = 0x24,
> +   .xTR[2] = 0x28,
> +   .xTR[3] = 0x2C,
> +   .xRR[0] = 0x40,
> +   .xRR[1] = 0x44,
> +   .xRR[2] = 0x48,
> +   .xRR[3] = 0x4C,
> +   .xSR= 0x60,
> +   .xCR= 0x64,
> +};
> +
>  static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
>  {
> return container_of(mbox, struct imx_mu_priv, mbox);
> @@ -88,10 +114,10 @@ static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, u32 
> set, u32 clr)
> u32 val;
>
> spin_lock_irqsave(>xcr_lock, flags);
> -   val = imx_mu_read(priv, IMX_MU_xCR);
> +   val = imx_mu_read(priv, priv->dcfg->xCR);
> val &= ~clr;
> val |= set;
> -   imx_mu_write(priv, val, IMX_MU_xCR);
> +   imx_mu_write(priv, val, priv->dcfg->xCR);
> spin_unlock_irqrestore(>xcr_lock, flags);
>
> return val;
> @@ -111,8 +137,8 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
> struct imx_mu_con_priv *cp = chan->con_priv;
> u32 val, ctrl, dat;
>
> -   ctrl = imx_mu_read(priv, IMX_MU_xCR);
> -   val = imx_mu_read(priv, IMX_MU_xSR);
> +   ctrl = imx_mu_read(priv, priv->dcfg->xCR);
> +   val = imx_mu_read(priv, priv->dcfg->xSR);
>
> switch (cp->type) {
> case IMX_MU_TYPE_TX:
> @@ -138,10 +164,10 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
> imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx));
> mbox_chan_txdone(chan, 0);
> } else if (val == IMX_MU_xSR_RFn(cp->idx)) {
> -   dat = imx_mu_read(priv, IMX_MU_xRRn(cp->idx));
> +   dat = imx_mu_read(priv, priv->dcfg->xRR[cp->idx]);
> mbox_chan_received_data(chan, (void *));
> } else if (val == IMX_MU_xSR_GIPn(cp->idx)) {
> -   imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), IMX_MU_xSR);
> +   imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), priv->dcfg->xSR);
> mbox_chan_received_data(chan, NULL);
> } else {
> dev_warn_ratelimited(priv->dev, "Not handled 

Re: [PATCH V2 3/4] irq: imx-irqsteer: change to use reg_num instead of irq_group

2019-01-30 Thread Dong Aisheng
On Wed, Jan 30, 2019 at 9:23 PM Lucas Stach  wrote:
[...]
> > > +   /* one register bit map represents 32 input interrupts */
> > > +   data->reg_num /= 32;
> > +
> > > if (IS_ENABLED(CONFIG_PM_SLEEP)) {
> > > data->saved_reg = devm_kzalloc(>dev,
> > > -   sizeof(u32) * data->irq_groups * 2,
> > > +   sizeof(u32) * data->reg_num,
> >   GFP_KERNEL);
>
> Does this last parameter now fit on the line above?
>

No, 81 now. :)

Regards
Dong Aisheng


Re: [PATCH V2 4/4] irq: imx: irqsteer: add multi output interrupts support

2019-01-30 Thread Dong Aisheng
On Wed, Jan 30, 2019 at 9:33 PM Lucas Stach  wrote:
>
> Am Mittwoch, den 30.01.2019, 13:06 + schrieb Aisheng Dong:
> > One irqsteer channel can support up to 8 output interrupts.
> >
> > > Cc: Marc Zyngier 
> > > Cc: Lucas Stach 
> > > Cc: Shawn Guo 
> > > Signed-off-by: Dong Aisheng 
> > ---
> > ChangeLog:
> > v1->v2:
> >  * calculate irq_count by fsl,num-irqs instead of parsing interrupts
> >property from devicetree to match the input interrupts and outputs
> >  * improve output interrupt handler by searching only two registers
> >withint the same group
> > ---
> >  drivers/irqchip/irq-imx-irqsteer.c | 76 
> > +-
> >  1 file changed, 59 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-imx-irqsteer.c 
> > b/drivers/irqchip/irq-imx-irqsteer.c
> > index 67ed862..cc40039 100644
> > --- a/drivers/irqchip/irq-imx-irqsteer.c
> > +++ b/drivers/irqchip/irq-imx-irqsteer.c
> > @@ -10,6 +10,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -21,10 +22,13 @@
> > >  #define CHAN_MINTDIS(t)(CTRL_STRIDE_OFF(t, 3) + 0x4)
> > >  #define CHAN_MASTRSTAT(t)  (CTRL_STRIDE_OFF(t, 3) + 0x8)
> >
> > > +#define CHAN_MAX_OUTPUT_INT0x8
> > +
> >  struct irqsteer_data {
> > > >   void __iomem*regs;
> > > >   struct clk  *ipg_clk;
> > > > - int irq;
> > > > + int irq[CHAN_MAX_OUTPUT_INT];
> > > > + int irq_count;
> > > >   raw_spinlock_t  lock;
> > > >   int reg_num;
> > > >   int channel;
> > @@ -87,26 +91,45 @@ static const struct irq_domain_ops 
> > imx_irqsteer_domain_ops = {
> > > >   .xlate  = irq_domain_xlate_onecell,
> >  };
> >
> > +static int imx_irqsteer_get_hwirq_base(struct irqsteer_data *data, u32 irq)
> > +{
> > > +   int i;
> > +
> > > +   for (i = 0; i < data->irq_count; i++) {
> > > +   if (data->irq[i] == irq)
> > + break;
>
> return i * 64; here...
> > + }
> > +
> > + return i * 64;
>
> ... and -EINVAL or something here, so we don't return a out of bounds
> hwirq base if the loop ever doesn't match something?
>

Good suggestion, will add it.

> > +}
> > +
> >  static void imx_irqsteer_irq_handler(struct irq_desc *desc)
> >  {
> > > struct irqsteer_data *data = irq_desc_get_handler_data(desc);
> > > +   int hwirq;
> > > int i;
> >
> > > chained_irq_enter(irq_desc_get_chip(desc), desc);
> >
> > > -   for (i = 0; i < data->reg_num * 32; i += 32) {
> > > -   int idx = imx_irqsteer_get_reg_index(data, i);
> > > +   hwirq = imx_irqsteer_get_hwirq_base(data, irq_desc_get_irq(desc));
> > +
> > > +   for (i = 0; i < 2; i++) {
> > > +   int idx = imx_irqsteer_get_reg_index(data, hwirq);
> > > unsigned long irqmap;
> > > int pos, virq;
> >
> > > +   if (hwirq >= data->reg_num * 32)
> > > +   break;
> > +
> > > irqmap = readl_relaxed(data->regs +
> > >CHANSTATUS(idx, data->reg_num));
> >
> > > for_each_set_bit(pos, , 32) {
> > > -   virq = irq_find_mapping(data->domain, pos + i);
> > + virq = irq_find_mapping(data->domain, pos + hwirq);
>
> The irq index calculation need to be "pos + i * 32 + hwirq", otherwise
> this will map to the wrong virqs for the second register in each group.
>

For second register map, hwirq will plus 32 in next round.
So i can't see this will map a wrong virqs.
And it looks to me ""pos + i * 32 + hwirq" is equal to "hwirq + 32".
Am i missed something?

> >   if (virq)
> > > generic_handle_irq(virq);
> > > }
> > + hwirq += 32;
>
> Could be folded into the loop head.
>

You mean “for (i = 0; i < 2; i++, hwirq +=32)” ?
I feel that's not quite necessary.

> >   }
> >
> > > chained_irq_exit(irq_desc_get_chip(desc), desc);
> > @@ -117,7 +140,8 @@ static int imx_irqsteer_probe(struct platform_device 
> > *

Re: [PATCH V2 2/4] dt-bindings: irq: imx-irqsteer: add multi output interrupts support

2019-01-30 Thread Dong Aisheng
On Wed, Jan 30, 2019 at 9:21 PM Lucas Stach  wrote:
>
> Am Mittwoch, den 30.01.2019, 13:05 + schrieb Aisheng Dong:
> > One irqsteer channel can support up to 8 output interrupts.
> >
> > > Cc: Marc Zyngier 
> > > Cc: Rob Herring 
> > > Cc: Lucas Stach 
> > > Cc: Shawn Guo 
> > Cc: devicet...@vger.kernel.org
> > > Signed-off-by: Dong Aisheng 
> > ---
> > ChangeLog:
> > v1->v2:
> >  * remove one unnecessary note.
> > ---
> >  .../devicetree/bindings/interrupt-controller/fsl,irqsteer.txt| 5 
> > +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt 
> > b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > index 6d0a41b..984ab92 100644
> > --- 
> > a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > +++ 
> > b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > @@ -6,8 +6,9 @@ Required properties:
> > > - "fsl,imx8m-irqsteer"
> > > - "fsl,imx-irqsteer"
> >  - reg: Physical base address and size of registers.
> > -- interrupts: Should contain the parent interrupt line used to multiplex 
> > the
> > -  input interrupts.
> > +- interrupts: Should contain the up to 8 parent interrupt lines used to
> > +  multiplex the input interrupts. They should be sepcified seqencially
>
> Typos here, should be: "specified sequentially"
>

Nice catch. Will update in new version.
Thanks

Regards
Dong Aisheng

> > +  from output 0 to 7.
> >  - clocks: Should contain one clock for entry in clock-names
> >see Documentation/devicetree/bindings/clock/clock-bindings.txt
> >  - clock-names:


Re: [PATCH v2] firmware: imx: Add support to start/stop a CPU

2019-01-30 Thread Dong Aisheng
On Wed, Jan 30, 2019 at 9:12 PM Daniel Baluta  wrote:
>
> Thanks Aisheng for the comments!
>
> 
>
> +int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
> > > +   bool enable, u64 address)
> > > +{
> > > +   struct imx_sc_msg_req_cpu_start msg;
> > > +   struct imx_sc_rpc_msg *hdr = 
> > > +
> > > +   hdr->ver = IMX_SC_RPC_VERSION;
> > > +   hdr->svc = (uint8_t)IMX_SC_RPC_SVC_PM;
> > > +   hdr->func = (uint8_t)IMX_SC_PM_FUNC_CPU_START;
> >
> > pls drop the unneccesary unit8_t
>
> Ok, I can do that. I had borrowed it from the already existing
> functions imx_sc_misc_get_control / imx_sc_misc_set_control
>

Yes, i know, we need remove them later to avoid confusing.

Regards
Dong Aisheng

> >
> > > +   hdr->size = 4;
> > > +
> > > +   msg.address_hi = address >> 32;
> > > +   msg.address_lo = address;
> > > +   msg.resource = resource;
> > > +   msg.enable = enable;
> > > +
> > > +   return imx_scu_call_rpc(ipc, , false);
> >
> > s/false/true
>
> Nice catch!
>
> Inded, the old API had a different semantic for this parameter.
> >
> > > +}
> > > +EXPORT_SYMBOL(imx_sc_pm_cpu_start);
> > > diff --git a/include/linux/firmware/imx/svc/misc.h
> > > b/include/linux/firmware/imx/svc/misc.h
> > > index e21c49aba92f..c03bf2a23add 100644
> > > --- a/include/linux/firmware/imx/svc/misc.h
> > > +++ b/include/linux/firmware/imx/svc/misc.h
> > > @@ -52,4 +52,7 @@ int imx_sc_misc_set_control(struct imx_sc_ipc
> > > *ipc, u32 resource,
> > >  int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
> > > u8 ctrl, u32 *val);
> > >
> > > +int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
> > > +   bool enable, u64 address);
> >
> > Nitpick: phy_addr
>
> Ok, will fix.
>
>


Re: [PATCH v2] firmware: imx: Add support to start/stop a CPU

2019-01-30 Thread Dong Aisheng
On Wed, Jan 30, 2019 at 5:59 PM Daniel Baluta  wrote:
>
> This is done via RPC call to SCU.
>
> Signed-off-by: Daniel Baluta 
> ---
> Changes since v1:
> - remove unused variable ret
> - add documentation for imx_sc_pm_cpu_start function
>
>  drivers/firmware/imx/misc.c   | 38 +++
>  include/linux/firmware/imx/svc/misc.h |  3 +++
>  2 files changed, 41 insertions(+)
>
> diff --git a/drivers/firmware/imx/misc.c b/drivers/firmware/imx/misc.c
> index 97f5424dbac9..f511d6f624fd 100644
> --- a/drivers/firmware/imx/misc.c
> +++ b/drivers/firmware/imx/misc.c
> @@ -18,6 +18,14 @@ struct imx_sc_msg_req_misc_set_ctrl {
> u16 resource;
>  } __packed;
>
> +struct imx_sc_msg_req_cpu_start {
> +   struct imx_sc_rpc_msg hdr;
> +   u32 address_hi;
> +   u32 address_lo;
> +   u16 resource;
> +   u8 enable;
> +} __packed;
> +
>  struct imx_sc_msg_req_misc_get_ctrl {
> struct imx_sc_rpc_msg hdr;
> u32 ctrl;
> @@ -97,3 +105,33 @@ int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 
> resource,
> return 0;
>  }
>  EXPORT_SYMBOL(imx_sc_misc_get_control);
> +
> +/*
> + * This function starts/stops a CPU identified by @resource
> + *
> + * @param[in] ipc IPC handle
> + * @param[in] resourceresource the control is associated with
> + * @param[in] enable  true for start, false for stop
> + * @param[out]address initial instruction address to be executed
> + *
> + * @return Returns 0 for success and < 0 for errors.
> + */
> +int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
> +   bool enable, u64 address)
> +{
> +   struct imx_sc_msg_req_cpu_start msg;
> +   struct imx_sc_rpc_msg *hdr = 
> +
> +   hdr->ver = IMX_SC_RPC_VERSION;
> +   hdr->svc = (uint8_t)IMX_SC_RPC_SVC_PM;
> +   hdr->func = (uint8_t)IMX_SC_PM_FUNC_CPU_START;

pls drop the unneccesary unit8_t

> +   hdr->size = 4;
> +
> +   msg.address_hi = address >> 32;
> +   msg.address_lo = address;
> +   msg.resource = resource;
> +   msg.enable = enable;
> +
> +   return imx_scu_call_rpc(ipc, , false);

s/false/true

> +}
> +EXPORT_SYMBOL(imx_sc_pm_cpu_start);
> diff --git a/include/linux/firmware/imx/svc/misc.h 
> b/include/linux/firmware/imx/svc/misc.h
> index e21c49aba92f..c03bf2a23add 100644
> --- a/include/linux/firmware/imx/svc/misc.h
> +++ b/include/linux/firmware/imx/svc/misc.h
> @@ -52,4 +52,7 @@ int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 
> resource,
>  int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
> u8 ctrl, u32 *val);
>
> +int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
> +   bool enable, u64 address);

Nitpick: phy_addr

Otherwise, looks good to me.

Regards
Dong Aisheng

> +
>  #endif /* _SC_MISC_API_H */
> --
> 2.17.1
>


Re: [PATCH 2/4] dt-bindings: irq: imx-irqsteer: add multi output interrupts support

2019-01-27 Thread Dong Aisheng
On Fri, Jan 25, 2019 at 6:47 PM Lucas Stach  wrote:
>
> Am Freitag, den 18.01.2019, 07:53 + schrieb Aisheng Dong:
> > One irqsteer channel can support up to 8 output interrupts.
> >
> > > Cc: Marc Zyngier 
> > > Cc: Rob Herring 
> > > Cc: Lucas Stach 
> > > Cc: Shawn Guo 
> > Cc: devicet...@vger.kernel.org
> > > Signed-off-by: Dong Aisheng 
> > ---
> >  .../devicetree/bindings/interrupt-controller/fsl,irqsteer.txt| 5 
> > +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt 
> > b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > index eaabcda..beeed4a 100644
> > --- 
> > a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > +++ 
> > b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.txt
> > @@ -6,8 +6,9 @@ Required properties:
> > > - "fsl,imx8m-irqsteer"
> > > - "fsl,imx-irqsteer"
> >  - reg: Physical base address and size of registers.
> > -- interrupts: Should contain the parent interrupt line used to multiplex 
> > the
> > -  input interrupts.
> > +- interrupts: Should contain the up to 8 parent interrupt lines used to
> > +  multiplex the input interrupts. They should be sepcified seqencially
> > +  from output 0 to 7. NOTE at least one output interrupt has to be 
> > specified.
>
> I don't think the note clarifies anything. Given that the thing is a
> irq multiplexer I don't think anyone expects that you could get away
> with no output irq.
>

Sound reasonable to me.
I will remove the note and keep other as it is.

Regards
Dong Aisheng


Re: [PATCH 4/4] irq: imx: irqsteer: add multi output interrupts support

2019-01-27 Thread Dong Aisheng
On Fri, Jan 25, 2019 at 6:55 PM Lucas Stach  wrote:
>
> Am Freitag, den 18.01.2019, 07:53 + schrieb Aisheng Dong:
> > One irqsteer channel can support up to 8 output interrupts.
> >
> > > Cc: Marc Zyngier 
> > > Cc: Lucas Stach 
> > > Cc: Shawn Guo 
> > > Signed-off-by: Dong Aisheng 
> > ---
> >  drivers/irqchip/irq-imx-irqsteer.c | 39 
> > +++---
> >  1 file changed, 28 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-imx-irqsteer.c 
> > b/drivers/irqchip/irq-imx-irqsteer.c
> > index 1bebf0a..54802fa 100644
> > --- a/drivers/irqchip/irq-imx-irqsteer.c
> > +++ b/drivers/irqchip/irq-imx-irqsteer.c
> > @@ -10,6 +10,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -21,10 +22,13 @@
> > >  #define CHAN_MINTDIS(t)(CTRL_STRIDE_OFF(t, 3) + 0x4)
> > >  #define CHAN_MASTRSTAT(t)  (CTRL_STRIDE_OFF(t, 3) + 0x8)
> >
> > > +#define CHAN_MAX_OUTPUT_INT0x8
> > +
> >  struct irqsteer_data {
> > > >   void __iomem*regs;
> > > >   struct clk  *ipg_clk;
> > > > - int irq;
> > > > + int irq[CHAN_MAX_OUTPUT_INT];
> > > > + int irq_count;
> > > >   raw_spinlock_t  lock;
> > > >   int reg_num;
> > > >   int channel;
> > @@ -117,7 +121,7 @@ static int imx_irqsteer_probe(struct platform_device 
> > *pdev)
> > > struct device_node *np = pdev->dev.of_node;
> > > struct irqsteer_data *data;
> > > struct resource *res;
> > > -   int ret;
> > > +   int i, ret;
> >
> > > data = devm_kzalloc(>dev, sizeof(*data), GFP_KERNEL);
> > > if (!data)
> > @@ -130,12 +134,6 @@ static int imx_irqsteer_probe(struct platform_device 
> > *pdev)
> > > return PTR_ERR(data->regs);
> > > }
> >
> > > -   data->irq = platform_get_irq(pdev, 0);
> > > -   if (data->irq <= 0) {
> > > -   dev_err(>dev, "failed to get irq\n");
> > > -   return -ENODEV;
> > > -   }
> > -
> > > data->ipg_clk = devm_clk_get(>dev, "ipg");
> > > if (IS_ERR(data->ipg_clk)) {
> > > ret = PTR_ERR(data->ipg_clk);
> > @@ -177,8 +175,23 @@ static int imx_irqsteer_probe(struct platform_device 
> > *pdev)
> > > return -ENOMEM;
> > > }
> >
> > > -   irq_set_chained_handler_and_data(data->irq, imx_irqsteer_irq_handler,
> > > -data);
> > + data->irq_count = of_irq_count(np);
>
> We normally don't validate stuff that comes from the DT, but I guess it
> might be helpful to validate that the number of output irqs specified
> matches what the number of input irqs, i.e. there is one output irqs
> specified for each group of 64 inputs.
>

Sound like a good idea.
I think we can calculate the irq_count from irqs number instead of of_irq_count.
Then the following irq_of_parse_and_map() will validate them automatically.

However, i think we'd better to keep the irq_count range check as well.

> > + if (!data->irq_count || data->irq_count > CHAN_MAX_OUTPUT_INT) {
> > > +   clk_disable_unprepare(data->ipg_clk);
> > > +   return -EINVAL;
> > > +   }
> > +
> > > +   for (i = 0; i < data->irq_count; i++) {
> > > +   data->irq[i] = irq_of_parse_and_map(np, i);
> > > +   if (!data->irq[i]) {
> > > +   clk_disable_unprepare(data->ipg_clk);
> > > +   return -EINVAL;
> > > +   }
> > +
> > > +   irq_set_chained_handler_and_data(data->irq[i],
> > > +imx_irqsteer_irq_handler,
> > +  data);
>
> We really want some data about the output irq being passed here, so we
> can cut down the number of register reads in the irq handler to the
> maximum of 2 status registers per group.
>

Will implement it and resend.

Regards
Dong Aisheng

> Regards,
> Lucas


Re: [PATCH 4/4] irq: imx: irqsteer: add multi output interrupts support

2019-01-27 Thread Dong Aisheng
Hi Lucas,

[...]

> > > The fsl,irq-groups property is exactly your NINT32 parameter above. I just
> > > wrongly assumed that it's always in multiples of 64, as that's what the
> > > i.MX8MQ DCSS irqsteer module looks like. We should fix this and be done 
> > > with
> > > it.
> > >
> >
> > No, not exactly the same thing. Using group will confuse people that the 
> > group is 32.
> > However, internally Group is fixed 64 interrupts although it may not use 
> > all the
> > 64 interrupts. E.g. 32 interrupts.
> > See CHn_MINTDIS register which is also defined fixed to 64.
> >
> > The two HW parameter for integration is already very clear. We should use 
> > interrupts
> > Number for the channel. Not group.
>
> Okay, I see that the name irq-groups is confusing for you. But then I
> find the -per-chan naming confusing.
>
> So given that we seem to agree to split each channel into it's own DT
> node, there is no need to name the property "something-per-chan", as
> it's implied by the split DT nodes that all properties in one node are
> referencing a channel.
>

Double checked with IP module owner by looking into the RTL code,
writes to CHANnCTL registers have no effect.
This register is reserved and the doc will be updated.
Verified on both MX8QXP and MX8MQ.

All channels are isolated and have independent programming model.
So it will be okay to define them separately in device tree.

> May I suggest to name the property "fsl,num-irqs"?

Sounds good to me.

Regards
Dong Aisheng

>
> Regards,
> Lucas
>


[PATCH V2 1/1] MAINTAINERS: imx: include drivers/firmware/imx path

2018-10-08 Thread Dong Aisheng
Due to newly added IMX SCU firmware support, let's add
drivers/firmware/imx into maintainership.

Cc: Shawn Guo 
Cc: Arnd Bergmann 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Dong Aisheng 
---
v2:
 * add missing include/linux/firmware/imx
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad052a..eee17f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1462,7 +1462,9 @@ F:arch/arm/mach-mxs/
 F: arch/arm/boot/dts/imx*
 F: arch/arm/configs/imx*_defconfig
 F: drivers/clk/imx/
+F: drivers/firmware/imx/
 F: drivers/soc/imx/
+F: include/linux/firmware/imx/
 F: include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
-- 
2.7.4



[PATCH V2 1/1] MAINTAINERS: imx: include drivers/firmware/imx path

2018-10-08 Thread Dong Aisheng
Due to newly added IMX SCU firmware support, let's add
drivers/firmware/imx into maintainership.

Cc: Shawn Guo 
Cc: Arnd Bergmann 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Dong Aisheng 
---
v2:
 * add missing include/linux/firmware/imx
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad052a..eee17f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1462,7 +1462,9 @@ F:arch/arm/mach-mxs/
 F: arch/arm/boot/dts/imx*
 F: arch/arm/configs/imx*_defconfig
 F: drivers/clk/imx/
+F: drivers/firmware/imx/
 F: drivers/soc/imx/
+F: include/linux/firmware/imx/
 F: include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
-- 
2.7.4



  1   2   3   4   5   6   7   8   9   10   >