* [PATCH] sound: usb: pcm: fix incorrect power state when playing sound after PM_AUTO suspend
From: Macpaul Lin @ 2020-06-02 11:53 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai, Matthias Brugger, Alexander Tsoy,
Johan Hovold, Hui Wang, Szabolcs Szőke, Macpaul Lin,
alsa-devel, linux-usb
Cc: linux-arm-kernel, Macpaul Lin, linux-mediatek, linux-kernel,
Mediatek WSD Upstream
In-Reply-To: <linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org>
This patch fix incorrect power state changed by usb_audio_suspend()
when CONFIG_PM is enabled.
After receiving suspend PM message with auto flag, usb_audio_suspend()
change card's power state to SNDRV_CTL_POWER_D3hot. Only when the other
resume PM message with auto flag can change power state to
SNDRV_CTL_POWER_D0 in __usb_audio_resume().
However, when system is not under auto suspend, resume PM message with
auto flag might not be able to receive on time which cause the power
state was incorrect. At this time, if a player starts to play sound,
will cause snd_usb_pcm_open() to access the card and setup_hw_info() will
resume the card.
But even the card is back to work and all function normal, the power
state is still in SNDRV_CTL_POWER_D3hot. Which cause the infinite loop
happened in snd_power_wait() to check the power state. Thus the
successive setting ioctl cannot be passed to card.
Hence we suggest to change power state to SNDRV_CTL_POWER_D0 when card
has been resumed successfully.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
sound/usb/pcm.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index a4e4064..d667ecb 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1322,6 +1322,17 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
if (err < 0)
return err;
+ /* fix incorrect power state when resuming by open and later ioctls */
+ if (IS_ENABLED(CONFIG_PM) &&
+ snd_power_get_state(subs->stream->chip->card)
+ == SNDRV_CTL_POWER_D3hot) {
+ /* set these variables for power state correction */
+ subs->stream->chip->autosuspended = 0;
+ subs->stream->chip->num_suspended_intf = 1;
+ dev_info(&subs->dev->dev,
+ "change power state from D3hot to D0\n");
+ }
+
return snd_usb_autoresume(subs->stream->chip);
}
--
1.7.9.5
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH 06/12] PM / devfreq: Add cpu based scaling support to passive_governor
From: andrew-sh.cheng @ 2020-06-02 11:43 UTC (permalink / raw)
To: Chanwoo Choi
Cc: Mark Rutland, Nishanth Menon, srv_heupstream, devicetree,
Stephen Boyd, Viresh Kumar, Mark Brown, linux-pm,
Rafael J . Wysocki, Liam Girdwood, Rob Herring, linux-kernel,
Kyungmin Park, MyungJoo Ham, linux-mediatek, Sibi Sankar,
Matthias Brugger, linux-arm-kernel
In-Reply-To: <64b81eea-641c-811d-9830-718b28db4188@samsung.com>
On Thu, 2020-05-28 at 15:14 +0900, Chanwoo Choi wrote:
> Hi Andrew-sh.Cheng,
>
> Thanks for your posting. I like this approach absolutely.
> I think that it is necessary. When I developed the embedded product,
> I needed this feature always.
>
> I add the comments on below.
>
>
> And the following email is not valid. So, I dropped this email
> from Cc list.
> Saravana Kannan <skannan@codeaurora.org>
>
>
> On 5/20/20 12:43 PM, Andrew-sh.Cheng wrote:
> > From: Saravana Kannan <skannan@codeaurora.org>
> >
> > Many CPU architectures have caches that can scale independent of the
> > CPUs. Frequency scaling of the caches is necessary to make sure that the
> > cache is not a performance bottleneck that leads to poor performance and
> > power. The same idea applies for RAM/DDR.
> >
> > To achieve this, this patch adds support for cpu based scaling to the
> > passive governor. This is accomplished by taking the current frequency
> > of each CPU frequency domain and then adjust the frequency of the cache
> > (or any devfreq device) based on the frequency of the CPUs. It listens
> > to CPU frequency transition notifiers to keep itself up to date on the
> > current CPU frequency.
> >
> > To decide the frequency of the device, the governor does one of the
> > following:
> > * Derives the optimal devfreq device opp from required-opps property of
> > the parent cpu opp_table.
> >
> > * Scales the device frequency in proportion to the CPU frequency. So, if
> > the CPUs are running at their max frequency, the device runs at its
> > max frequency. If the CPUs are running at their min frequency, the
> > device runs at its min frequency. It is interpolated for frequencies
> > in between.
> >
> > Andrew-sh.Cheng change
> > dev_pm_opp_xlate_opp to dev_pm_opp_xlate_required_opp devfreq->max_freq
> > to devfreq->user_min_freq_req.data.freq.qos->min_freq.target_value
> > for kernel-5.7
> >
> > Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
> > [Sibi: Integrated cpu-freqmap governor into passive_governor]
> > Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> > Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
> > ---
> > drivers/devfreq/Kconfig | 2 +
> > drivers/devfreq/governor_passive.c | 278 ++++++++++++++++++++++++++++++++++---
> > include/linux/devfreq.h | 40 +++++-
> > 3 files changed, 299 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> > index 0b1df12e0f21..d9067950af6a 100644
> > --- a/drivers/devfreq/Kconfig
> > +++ b/drivers/devfreq/Kconfig
> > @@ -73,6 +73,8 @@ config DEVFREQ_GOV_PASSIVE
> > device. This governor does not change the frequency by itself
> > through sysfs entries. The passive governor recommends that
> > devfreq device uses the OPP table to get the frequency/voltage.
> > + Alternatively the governor can also be chosen to scale based on
> > + the online CPUs current frequency.
> >
> > comment "DEVFREQ Drivers"
> >
> > diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
> > index 2d67d6c12dce..7dcda02a5bb7 100644
> > --- a/drivers/devfreq/governor_passive.c
> > +++ b/drivers/devfreq/governor_passive.c
> > @@ -8,11 +8,89 @@
> > */
> >
> > #include <linux/module.h>
> > +#include <linux/cpu.h>
> > +#include <linux/cpufreq.h>
> > +#include <linux/cpumask.h>
> > #include <linux/device.h>
> > #include <linux/devfreq.h>
> > +#include <linux/slab.h>
> > #include "governor.h"
> >
> > -static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
> > +static unsigned int xlate_cpufreq_to_devfreq(struct devfreq_passive_data *data,
>
> Need to change 'unsigned int' to 'unsigned long'
Get it.
> .
>
> > + unsigned int cpu)
> > +{
> > + unsigned int cpu_min, cpu_max, dev_min, dev_max, cpu_percent, max_state;
>
> Better to define them separately as following and then need to rename
> the variable. Usually, use the 'min_freq' and 'max_freq' word for
> the minimum/maximum frequency.
>
> unsigned int cpu_min_freq, cpu_max_freq, cpu_curr_freq, cpu_percent;
> unsigned long dev_min_freq, dev_max_freq, dev_max_state,
>
> The devfreq used 'unsigned long'. The cpufreq used 'unsigned long'
> and 'unsigned int'. You need to handle them properly.
Get it.
For cpu_freq, I separate it into "unsigned long cpu_curr_freq" and
"unsigned int cpu_curr_freq_khz"
>
>
> > + struct devfreq_cpu_state *cpu_state = data->cpu_state[cpu];
> > + struct devfreq *devfreq = (struct devfreq *)data->this;
> > + unsigned long *freq_table = devfreq->profile->freq_table;
>
> In this function, use 'cpu' work for cpufreq and use 'dev' for devfreq.
> So, I think 'dev_freq_table' is proper name instead of 'freq_table'
> for the readability.
>
> freq_table -> dev_freq_table
>
> > + struct dev_pm_opp *opp = NULL, *cpu_opp = NULL;
>
> In the get_target_freq_with_devfreq(), use 'p_opp' indicating
> the OPP of parent device. For the consistency, I think that
> use 'p_opp' instead of 'cpu_opp'.
>
> > + unsigned long cpu_freq, freq;
>
> Define the 'cpu_freq' on above with cpu_min_freq/cpu_max_freq definition.
> cpu_freq -> cpu_curr_freq.
Get it.
Will modify them for readability.
>
> > +
> > + if (!cpu_state || cpu_state->first_cpu != cpu ||
> > + !cpu_state->opp_table || !devfreq->opp_table)
> > + return 0;
> > +
> > + cpu_freq = cpu_state->freq * 1000;
> > + cpu_opp = devfreq_recommended_opp(cpu_state->dev, &cpu_freq, 0);
> > + if (IS_ERR(cpu_opp))
> > + return 0;
> > +
> > + opp = dev_pm_opp_xlate_required_opp(cpu_state->opp_table,
> > + devfreq->opp_table, cpu_opp);
> > + dev_pm_opp_put(cpu_opp);
> > +
> > + if (!IS_ERR(opp)) {
> > + freq = dev_pm_opp_get_freq(opp);
> > + dev_pm_opp_put(opp);
>
> Better to add the 'out' goto statement.
> If you use 'goto out', you can reduce the one indentation
> without 'else' statement.
Get it.
>
>
> > + } else {
>
> As I commented, when dev_pm_opp_xlate_required_opp() return successfully
> , use 'goto out'. We can remove 'else' and then reduce the unneeded indentation.
>
>
> > + /* Use Interpolation if required opps is not available */
> > + cpu_min = cpu_state->min_freq;
> > + cpu_max = cpu_state->max_freq;
> > + cpu_freq = cpu_state->freq;
> > +
> > + if (freq_table) {
> > + /* Get minimum frequency according to sorting order */
> > + max_state = freq_table[devfreq->profile->max_state - 1];
> > + if (freq_table[0] < max_state) {
> > + dev_min = freq_table[0];
> > + dev_max = max_state;
> > + } else {
> > + dev_min = max_state;
> > + dev_max = freq_table[0];
> > + }
> > + } else {
> > + if (devfreq->user_max_freq_req.data.freq.qos->max_freq.target_value
> > + <= devfreq->user_min_freq_req.data.freq.qos->min_freq.target_value)
> > + return 0;
> > + dev_min =
> > + devfreq->user_min_freq_req.data.freq.qos->min_freq.target_value;
> > + dev_max =
> > + devfreq->user_max_freq_req.data.freq.qos->max_freq.target_value;
>
> I think it is not proper to access the variable of pm_qos structure directly.
> Instead of direct access, you have to use the exported PM QoS function such as
> - pm_qos_read_value(devfreq->dev.parent, DEV_PM_QOS_MIN_FREQUENCY);
> - pm_qos_read_value(devfreq->dev.parent, DEV_PM_QOS_MAX_FREQUENCY);
Get it.
>
> > + }
> > + cpu_percent = ((cpu_freq - cpu_min) * 100) / cpu_max - cpu_min;
> > + freq = dev_min + mult_frac(dev_max - dev_min, cpu_percent, 100);
> > + }
>
>
> I think that you better to add 'out' jump label as following:
>
> out:
>
> > +
> > + return freq;
> > +}
> > +
> > +static int get_target_freq_with_cpufreq(struct devfreq *devfreq,
> > + unsigned long *freq)
> > +{
> > + struct devfreq_passive_data *p_data =
> > + (struct devfreq_passive_data *)devfreq->data;
> > + unsigned int cpu, target_freq = 0;
>
> Need to define 'target_freq' with 'unsigned long' type.
Get it.
>
> > +
> > + for_each_online_cpu(cpu)
> > + target_freq = max(target_freq,
> > + xlate_cpufreq_to_devfreq(p_data, cpu));
> > +
> > + *freq = target_freq;
> > +
> > + return 0;
> > +}
> > +
> > +static int get_target_freq_with_devfreq(struct devfreq *devfreq,
> > unsigned long *freq)
> > {
> > struct devfreq_passive_data *p_data
> > @@ -23,16 +101,6 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
> > int i, count, ret = 0;
> >
> > /*
> > - * If the devfreq device with passive governor has the specific method
> > - * to determine the next frequency, should use the get_target_freq()
> > - * of struct devfreq_passive_data.
> > - */
> > - if (p_data->get_target_freq) {
> > - ret = p_data->get_target_freq(devfreq, freq);
> > - goto out;
> > - }
> > -
> > - /*
> > * If the parent and passive devfreq device uses the OPP table,
> > * get the next frequency by using the OPP table.
> > */
> > @@ -102,6 +170,37 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
> > return ret;
> > }
> >
> > +static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
> > + unsigned long *freq)
> > +{
> > + struct devfreq_passive_data *p_data =
> > + (struct devfreq_passive_data *)devfreq->data;
> > + int ret;
> > +
> > + /*
> > + * If the devfreq device with passive governor has the specific method
> > + * to determine the next frequency, should use the get_target_freq()
> > + * of struct devfreq_passive_data.
> > + */
> > + if (p_data->get_target_freq)
> > + return p_data->get_target_freq(devfreq, freq);
> > +
> > + switch (p_data->parent_type) {
> > + case DEVFREQ_PARENT_DEV:
> > + ret = get_target_freq_with_devfreq(devfreq, freq);
> > + break;
> > + case CPUFREQ_PARENT_DEV:
> > + ret = get_target_freq_with_cpufreq(devfreq, freq);
> > + break;
> > + default:
> > + ret = -EINVAL;
> > + dev_err(&devfreq->dev, "Invalid parent type\n");
> > + break;
> > + }
> > +
> > + return ret;
> > +}
> > +
> > static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
> > {
> > int ret;
> > @@ -156,6 +255,140 @@ static int devfreq_passive_notifier_call(struct notifier_block *nb,
> > return NOTIFY_DONE;
> > }
> >
> > +static int cpufreq_passive_notifier_call(struct notifier_block *nb,
> > + unsigned long event, void *ptr)
> > +{
> > + struct devfreq_passive_data *data =
> > + container_of(nb, struct devfreq_passive_data, nb);
> > + struct devfreq *devfreq = (struct devfreq *)data->this;
> > + struct devfreq_cpu_state *cpu_state;
> > + struct cpufreq_freqs *freq = ptr;
>
> How about changing 'freq' to 'cpu_freqs'?
>
> In the drivers/cpufreq/cpufreq.c, use 'freqs' name indicating
> the instance of 'struct cpufreq_freqs'. And in order to
> identfy, how about adding 'cpu_' prefix for variable name?
>
> > + unsigned int current_freq;
>
> Need to define curr_freq with 'unsigned long' type
> and better to use 'curr_freq' variable name.
It is good to change current_freq to curr_freq, but why should it us
'unsigned long'?
I think it is 'unsigned int'.
>
> > + int ret;
> > +
> > + if (event != CPUFREQ_POSTCHANGE || !freq ||
> > + !data->cpu_state[freq->policy->cpu])
> > + return 0;
> > +
> > + cpu_state = data->cpu_state[freq->policy->cpu];
> > + if (cpu_state->freq == freq->new)
> > + return 0;
> > +
> > + /* Backup current freq and pre-update cpu state freq*/
> > + current_freq = cpu_state->freq;
> > + cpu_state->freq = freq->new;
> > +
> > + mutex_lock(&devfreq->lock);
> > + ret = update_devfreq(devfreq);
> > + mutex_unlock(&devfreq->lock);
> > + if (ret) {
> > + cpu_state->freq = current_freq;
> > + dev_err(&devfreq->dev, "Couldn't update the frequency.\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int cpufreq_passive_register(struct devfreq_passive_data **p_data)
> > +{
> > + struct devfreq_passive_data *data = *p_data;
> > + struct devfreq *devfreq = (struct devfreq *)data->this;
> > + struct device *dev = devfreq->dev.parent;
> > + struct opp_table *opp_table = NULL;
> > + struct devfreq_cpu_state *state;
>
> For the readability, I thinkt 'cpu_state' is proper instead of 'state'.
Get it.
>
> > + struct cpufreq_policy *policy;
> > + struct device *cpu_dev;
> > + unsigned int cpu;
> > + int ret;
> > +
> > + get_online_cpus();
>
> Add blank line.
Get it.
>
> > + data->nb.notifier_call = cpufreq_passive_notifier_call;
> > + ret = cpufreq_register_notifier(&data->nb,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > + if (ret) {
> > + dev_err(dev, "Couldn't register cpufreq notifier.\n");
> > + data->nb.notifier_call = NULL;
> > + goto out;
> > + }
> > +
> > + /* Populate devfreq_cpu_state */
> > + for_each_online_cpu(cpu) {
> > + if (data->cpu_state[cpu])
> > + continue;
> > +
> > + policy = cpufreq_cpu_get(cpu);
>
> cpufreq_cpu_get() might return 'NULL'. I think you need to handle
> return value as following:
>
> if (!policy) {
> ret = -EINVAL;
> goto out;
> } else if (PTR_ERR(policy) == -EPROBE_DEFER) {
> goto out;
> } else if (IS_ERR(policy) {
> ret = PTR_ERR(policy);
> dev_err(dev, "Couldn't get the cpufreq_poliy.\n");
> goto out;
> }
>
> If cpufreq_cpu_get() return successfully, to do next.
> It reduces the one indentaion.
>
>
Get it.
>
> > + if (policy) {
> > + state = kzalloc(sizeof(*state), GFP_KERNEL);
> > + if (!state) {
> > + ret = -ENOMEM;
> > + goto out;
> > + }
> > +
> > + cpu_dev = get_cpu_device(cpu);
> > + if (!cpu_dev) {
> > + dev_err(dev, "Couldn't get cpu device.\n");
> > + ret = -ENODEV;
> > + goto out;
> > + }
> > +
> > + opp_table = dev_pm_opp_get_opp_table(cpu_dev);
> > + if (IS_ERR(devfreq->opp_table)) {
> > + ret = PTR_ERR(opp_table);
> > + goto out;
> > + }
> > +
> > + state->dev = cpu_dev;
> > + state->opp_table = opp_table;
> > + state->first_cpu = cpumask_first(policy->related_cpus);
> > + state->freq = policy->cur;
> > + state->min_freq = policy->cpuinfo.min_freq;
> > + state->max_freq = policy->cpuinfo.max_freq;
> > + data->cpu_state[cpu] = state;
>
> Add blank line.
>
> > + cpufreq_cpu_put(policy);
> > + } else {
> > + ret = -EPROBE_DEFER;
> > + goto out;
> > + }
> > + }
>
> Add blank line.
Get it.
> > +out:
> > + put_online_cpus();
> > + if (ret)
> > + return ret;
> > +
> > + /* Update devfreq */
> > + mutex_lock(&devfreq->lock);
> > + ret = update_devfreq(devfreq);
> > + mutex_unlock(&devfreq->lock);
> > + if (ret)
> > + dev_err(dev, "Couldn't update the frequency.\n");
> > +
> > + return ret;
> > +}
> > +
> > +static int cpufreq_passive_unregister(struct devfreq_passive_data **p_data)
> > +{
> > + struct devfreq_passive_data *data = *p_data;
> > + struct devfreq_cpu_state *cpu_state;
> > + int cpu;
> > +
> > + if (data->nb.notifier_call)
> > + cpufreq_unregister_notifier(&data->nb,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > +
> > + for_each_possible_cpu(cpu) {
> > + cpu_state = data->cpu_state[cpu];
> > + if (cpu_state) {
> > + if (cpu_state->opp_table)
> > + dev_pm_opp_put_opp_table(cpu_state->opp_table);
> > + kfree(cpu_state);
> > + cpu_state = NULL;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > static int devfreq_passive_event_handler(struct devfreq *devfreq,
> > unsigned int event, void *data)
> > {
> > @@ -165,7 +398,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
> > struct notifier_block *nb = &p_data->nb;
> > int ret = 0;
> >
> > - if (!parent)
> > + if (p_data->parent_type == DEVFREQ_PARENT_DEV && !parent)
> > return -EPROBE_DEFER;
>
> If you modify the devfreq_passive_event_handler() as following,
> you can move this condition for DEVFREQ_PARENT_DEV into
> (register|unregister)_parent_dev_notifier.
>
> switch (event) {
> case DEVFREQ_GOV_START:
> ret = register_parent_dev_notifier(p_data);
> break;
> case DEVFREQ_GOV_STOP:
> ret = unregister_parent_dev_notifier(p_data);
> break;
> default:
> ret = -EINVAL;
> break;
> }
>
> return ret;
>
Get it.
> >
> > switch (event) {
> > @@ -173,13 +406,24 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
> > if (!p_data->this)
> > p_data->this = devfreq;
> >
> > - nb->notifier_call = devfreq_passive_notifier_call;
> > - ret = devfreq_register_notifier(parent, nb,
> > - DEVFREQ_TRANSITION_NOTIFIER);
> > + if (p_data->parent_type == DEVFREQ_PARENT_DEV) {
> > + nb->notifier_call = devfreq_passive_notifier_call;
> > + ret = devfreq_register_notifier(parent, nb,
> > + DEVFREQ_TRANSITION_NOTIFIER);
> > + } else if (p_data->parent_type == CPUFREQ_PARENT_DEV) {
> > + ret = cpufreq_passive_register(&p_data);
>
> I think that we better to collect the code related to notifier registration
> into one function like devfreq_pass_register_notifier() instead of
> cpufreq_passive_register() as following: I think it is more simple and readable.
>
> If you have more proper function name of register_parent_dev_notifier,
> please give your opinion.
>
> int register_parent_dev_notifier(struct devfreq_passive_data **p_data)
> switch (p_data->parent_type) {
> case DEVFREQ_PARENT_DEV:
> nb->notifier_call = devfreq_passive_notifier_call;
> ret = devfreq_register_notifier(parent, nb,
> break;
> case CPUFREQ_PARENT_DEV:
> cpufreq_register_notifier(...)
> ...
> break;
> }
Not fully understanding.
Do you mean expanding cpufreq_passive_register()?
I think leave it in function will be with clean for this code segment.
>
>
> > + } else {
> > + ret = -EINVAL;
> > + }
> > break;
> > case DEVFREQ_GOV_STOP:
> > - WARN_ON(devfreq_unregister_notifier(parent, nb,
> > - DEVFREQ_TRANSITION_NOTIFIER));
> > + if (p_data->parent_type == DEVFREQ_PARENT_DEV)
> > + WARN_ON(devfreq_unregister_notifier(parent, nb,
> > + DEVFREQ_TRANSITION_NOTIFIER));
> > + else if (p_data->parent_type == CPUFREQ_PARENT_DEV)
> > + cpufreq_passive_unregister(&p_data);
> > + else
> > + ret = -EINVAL;
>
> ditto. unregister_parent_dev_notifier(struct devfreq_passive_data **p_data)
Get it.
>
> > break;
> > default:
> > break;
> > diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
> > index a4b19d593151..04ce576fd6f1 100644
> > --- a/include/linux/devfreq.h
> > +++ b/include/linux/devfreq.h
> > @@ -278,6 +278,32 @@ struct devfreq_simple_ondemand_data {
> >
> > #if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
> > /**
> > + * struct devfreq_cpu_state - holds the per-cpu state
> > + * @freq: the current frequency of the cpu.
> > + * @min_freq: the min frequency of the cpu.
> > + * @max_freq: the max frequency of the cpu.
> > + * @first_cpu: the cpumask of the first cpu of a policy.
> > + * @dev: reference to cpu device.
> > + * @opp_table: reference to cpu opp table.
> > + *
> > + * This structure stores the required cpu_state of a cpu.
> > + * This is auto-populated by the governor.
> > + */
> > +struct devfreq_cpu_state {> + unsigned int freq;
>
> It is better to change from 'freq' to 'curr_freq'
> for more correct expression.
Get it.
>
> > + unsigned int min_freq;
> > + unsigned int max_freq;
> > + unsigned int first_cpu;
> > + struct device *dev;
>
> How about changing the name 'dev' to 'cpu_dev'?
Okay.
>
>
> > + struct opp_table *opp_table;
> > +};
>
> devfreq_cpu_state is only handled by within driver/devfreq/governor_passive.c.
>
> So, you can move it into drivers/devfreq/governor_passive.c
> and just add the definition into include/linux/devfreq.h as following:
> It is able to prevent the access of variable of 'struct devfreq_cpu_state'
> outside.
>
> struct devfreq_cpu_state;
Get it.
>
> > +
> > +enum devfreq_parent_dev_type {
> > + DEVFREQ_PARENT_DEV,
> > + CPUFREQ_PARENT_DEV,
> > +};
> > +
> > +/**
> > * struct devfreq_passive_data - ``void *data`` fed to struct devfreq
> > * and devfreq_add_device
> > * @parent: the devfreq instance of parent device.
> > @@ -288,13 +314,15 @@ struct devfreq_simple_ondemand_data {
> > * using governors except for passive governor.
> > * If the devfreq device has the specific method to decide
> > * the next frequency, should use this callback.
> > - * @this: the devfreq instance of own device.
> > - * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER list
> > + * @parent_type parent type of the device
>
> Need to add ':' at the end of word. -> "parent_type:".
>
> > + * @this: the devfreq instance of own device.
> > + * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER list
>
> I knew that you make them with same indentation.
> But, actually, it is not related to this patch like clean-up code.
> Even if it is not pretty, you better to don't touch 'this' and 'nb' indentaion.
Get it.
>
> > + * @cpu_state: the state min/max/current frequency of all online cpu's
> > *
> > * The devfreq_passive_data have to set the devfreq instance of parent
> > * device with governors except for the passive governor. But, don't need to
> > - * initialize the 'this' and 'nb' field because the devfreq core will handle
> > - * them.
> > + * initialize the 'this', 'nb' and 'cpu_state' field because the devfreq core
> > + * will handle them.
> > */
> > struct devfreq_passive_data {
> > /* Should set the devfreq instance of parent device */
> > @@ -303,9 +331,13 @@ struct devfreq_passive_data {
> > /* Optional callback to decide the next frequency of passvice device */
> > int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
> >
> > + /* Should set the type of parent device */
> > + enum devfreq_parent_dev_type parent_type;
> > +
> > /* For passive governor's internal use. Don't need to set them */
> > struct devfreq *this;
> > struct notifier_block nb;
> > + struct devfreq_cpu_state *cpu_state[NR_CPUS];
> > };
> > #endif
> >
> >
>
>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v8 4/8] PM / EM: add support for other devices than CPUs in Energy Model
From: Lukasz Luba @ 2020-06-02 11:31 UTC (permalink / raw)
To: Daniel Lezcano, linux-kernel, linux-pm, linux-arm-kernel,
dri-devel, linux-omap, linux-mediatek, linux-arm-msm, linux-imx
Cc: nm, juri.lelli, peterz, viresh.kumar, liviu.dudau,
bjorn.andersson, bsegall, festevam, mka, robh, amit.kucheria,
lorenzo.pieralisi, vincent.guittot, khilman, steven.price,
cw00.choi, mingo, mgorman, rui.zhang, alyssa.rosenzweig,
orjan.eide, daniel, b.zolnierkie, s.hauer, rostedt, matthias.bgg,
Dietmar.Eggemann, airlied, tomeu.vizoso, qperret, sboyd, rdunlap,
rjw, agross, kernel, sudeep.holla, patrick.bellasi, shawnguo
In-Reply-To: <d45e5592-8e11-858b-d3a3-2ec9ce1d1f54@linaro.org>
Hi Daniel,
On 6/1/20 10:44 PM, Daniel Lezcano wrote:
> On 27/05/2020 11:58, Lukasz Luba wrote:
>> Add support for other devices than CPUs. The registration function
>> does not require a valid cpumask pointer and is ready to handle new
>> devices. Some of the internal structures has been reorganized in order to
>> keep consistent view (like removing per_cpu pd pointers).
>>
>> Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
>> ---
>
> [ ... ]
>
>> }
>> EXPORT_SYMBOL_GPL(em_register_perf_domain);
>> +
>> +/**
>> + * em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device
>> + * @dev : Device for which the EM is registered
>> + *
>> + * Try to unregister the EM for the specified device (but not a CPU).
>> + */
>> +void em_dev_unregister_perf_domain(struct device *dev)
>> +{
>> + if (IS_ERR_OR_NULL(dev) || !dev->em_pd)
>> + return;
>> +
>> + if (_is_cpu_device(dev))
>> + return;
>> +
>> + mutex_lock(&em_pd_mutex);
>
> Is the mutex really needed?
I just wanted to align this unregister code with register. Since there
is debugfs dir lookup and the device's EM existence checks I thought it
wouldn't harm just to lock for a while and make sure the registration
path is not used. These two paths shouldn't affect each other, but with
modules loading/unloading I wanted to play safe.
I can change it maybe to just dmb() and the end of the function if it's
a big performance problem in this unloading path. What do you think?
>
> If this function is called that means there is no more user of the
> em_pd, no?
True, that EM users should already be unregistered i.e. thermal cooling.
>
>> + em_debug_remove_pd(dev);
>> +
>> + kfree(dev->em_pd->table);
>> + kfree(dev->em_pd);
>> + dev->em_pd = NULL;
>> + mutex_unlock(&em_pd_mutex);
>> +}
>> +EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
>>
>
>
Thank you for reviewing this.
Regards,
Lukasz
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v6 2/2] hwrng: add sec-rng driver
From: Greg Kroah-Hartman @ 2020-06-02 10:38 UTC (permalink / raw)
To: Neal Liu
Cc: devicetree, Herbert Xu, Arnd Bergmann, Sean Wang, lkml,
wsd_upstream, Rob Herring, linux-mediatek, linux-crypto,
Matt Mackall, Matthias Brugger, Crystal Guo, linux-arm-kernel
In-Reply-To: <1591085678-22764-3-git-send-email-neal.liu@mediatek.com>
On Tue, Jun 02, 2020 at 04:14:38PM +0800, Neal Liu wrote:
> For security awareness SoCs on ARMv8 with TrustZone enabled,
> peripherals like entropy sources is not accessible from normal world
> (linux) and rather accessible from secure world (HYP/ATF/TEE) only.
> This driver aims to provide a generic interface to Arm Trusted
> Firmware or Hypervisor rng service.
>
> Signed-off-by: Neal Liu <neal.liu@mediatek.com>
> ---
> drivers/char/hw_random/Kconfig | 13 ++++
> drivers/char/hw_random/Makefile | 1 +
> drivers/char/hw_random/sec-rng.c | 155 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 169 insertions(+)
> create mode 100644 drivers/char/hw_random/sec-rng.c
>
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 9bc46da..cb9c8a9 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -474,6 +474,19 @@ config HW_RANDOM_KEYSTONE
> help
> This option enables Keystone's hardware random generator.
>
> +config HW_RANDOM_SECURE
> + tristate "Arm Security Random Number Generator support"
> + depends on HAVE_ARM_SMCCC || COMPILE_TEST
> + default HW_RANDOM
> + help
> + This driver provides kernel-side support for the Arm Security
> + Random Number Generator.
> +
> + To compile this driver as a module, choose M here. the
> + module will be called sec-rng.
> +
> + If unsure, say Y.
Why Y?
> +
> endif # HW_RANDOM
>
> config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index a7801b4..04533d1 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -41,3 +41,4 @@ obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
> obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
> obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> +obj-$(CONFIG_HW_RANDOM_SECURE) += sec-rng.o
> diff --git a/drivers/char/hw_random/sec-rng.c b/drivers/char/hw_random/sec-rng.c
> new file mode 100644
> index 0000000..c6d3872
> --- /dev/null
> +++ b/drivers/char/hw_random/sec-rng.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/hw_random.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#define SMC_RET_NUM 4
> +#define SEC_RND_SIZE (sizeof(u32) * SMC_RET_NUM)
> +
> +#define HWRNG_SMC_FAST_CALL_VAL(func_num) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_SIP, (func_num))
> +
> +#define to_sec_rng(p) container_of(p, struct sec_rng_priv, rng)
> +
> +typedef void (sec_rng_fn)(unsigned long, unsigned long, unsigned long,
> + unsigned long, unsigned long, unsigned long,
> + unsigned long, unsigned long,
> + struct arm_smccc_res *);
Why not throw some more unsigned longs in there? :)
Seriously, no variable names for these? Why not?
And given that you only use the first parameter, why have 7 of them that
are not used at all? That feels pointless and needlessly complex.
> +
> +struct sec_rng_priv {
> + u16 func_num;
> + sec_rng_fn *rng_fn;
> + struct hwrng rng;
> +};
Nit, if you put 'struct hwrng' at the top of the structure, your
"to_sec_rng()" macro resolves to a simple cast, no math at all.
> +
> +/* Simple wrapper functions to be able to use a function pointer */
> +static void sec_rng_smc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3,
> + unsigned long a4, unsigned long a5,
> + unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res)
> +{
> + arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
> +}
> +
> +static void sec_rng_hvc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3,
> + unsigned long a4, unsigned long a5,
> + unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res)
> +{
> + arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
> +}
> +
> +static bool __sec_get_rnd(struct sec_rng_priv *priv, uint32_t *val)
> +{
> + struct arm_smccc_res res;
> +
> + priv->rng_fn(HWRNG_SMC_FAST_CALL_VAL(priv->func_num),
> + 0, 0, 0, 0, 0, 0, 0, &res);
See, all 0's :(
You could hard-code them in the functions above instead.
But, all of this pointer indirection is really odd, why is it needed at
all? Why not just call one or the other depending on the "type" at
runtime? Wouldn't that actually be faster (hint, it is...), if you
cared about speed here (hint, I doubt it matters).
> +
> + if (!res.a0 && !res.a1 && !res.a2 && !res.a3)
> + return false;
> +
> + val[0] = res.a0;
> + val[1] = res.a1;
> + val[2] = res.a2;
> + val[3] = res.a3;
So no values out of the random number generator can be 0? Feels like an
odd thing for a random number not to be allowed to do, why this
restriction?
> +
> + return true;
> +}
> +
> +static int sec_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> + struct sec_rng_priv *priv = to_sec_rng(rng);
> + u32 val[4] = {0};
> + int retval = 0;
> + int i;
> +
> + while (max >= SEC_RND_SIZE) {
> + if (!__sec_get_rnd(priv, val))
> + return retval;
> +
> + for (i = 0; i < SMC_RET_NUM; i++) {
> + *(u32 *)buf = val[i];
> + buf += sizeof(u32);
Wait, what happens if buf is not a multiple of 4? Didn't you just
overwrite some memory above with the previous line?
> + }
> +
> + retval += SEC_RND_SIZE;
> + max -= SEC_RND_SIZE;
> + }
> +
> + return retval;
> +}
> +
> +static int sec_rng_probe(struct platform_device *pdev)
> +{
> + struct sec_rng_priv *priv;
> + const char *method;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + if (of_property_read_string(pdev->dev.of_node, "method", &method))
> + return -ENXIO;
> +
> + if (!strncmp("smc", method, strlen("smc")))
> + priv->rng_fn = sec_rng_smc;
> + else if (!strncmp("hvc", method, strlen("hvc")))
> + priv->rng_fn = sec_rng_hvc;
> +
> + if (IS_ERR(priv->rng_fn)) {
How can this ever be true?
Just put another else on the above list and you should be fine.
> + dev_err(&pdev->dev, "method %s is not supported\n", method);
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u16(pdev->dev.of_node, "method-fid",
> + &priv->func_num))
> + return -ENXIO;
> +
> + if (of_property_read_u16(pdev->dev.of_node, "quality",
> + &priv->rng.quality))
> + return -ENXIO;
> +
> + priv->rng.name = pdev->name;
> + priv->rng.read = sec_rng_read;
> + priv->rng.priv = (unsigned long)&pdev->dev;
> +
> + ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to register rng device: %d\n", ret);
Doesn't the caller print out something if this fails?
thanks,
greg k-h
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v10] mfd: mt6360: add pmic mt6360 driver
From: Lee Jones @ 2020-06-02 10:32 UTC (permalink / raw)
To: Matthias Brugger
Cc: gene_chen, linux-kernel, cy_huang, linux-mediatek, Gene Chen,
Wilma.Wu, linux-arm-kernel, shufan_lee
In-Reply-To: <2231bffe-27d1-6aee-4699-77d2f754beef@gmail.com>
On Tue, 02 Jun 2020, Matthias Brugger wrote:
>
>
> On 02/06/2020 10:28, Lee Jones wrote:
> > On Tue, 02 Jun 2020, Gene Chen wrote:
> >
> >> From: Gene Chen <gene_chen@richtek.com>
> >>
> >> Add MFD driver for mt6360 pmic chip include Battery Charger/
> >> USB_PD/Flash, LED/RGB and LED/LDO/Buck
> >>
> >> Signed-off-by: Gene Chen <gene_chen@richtek.com>
> >> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> >
> > I did not sign this off.
> >
>
> You are right, you provided your Acked-for-MFD-by and took an earlier version of
> the patch [1]. But as this didn't show up in linux-next I suppose you dropped it
> afterwards because of kbuild test errors (deducing from the changes log).
If the builders can see it, -next can pull from it.
It was never dropped.
> I suppose if this errors are fixed now, we should be fine :)
Indeed. No more build errors. :)
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Sakari Ailus @ 2020-06-02 9:56 UTC (permalink / raw)
To: Dongchun Zhu
Cc: Mark Rutland, Rob Herring, Andy Shevchenko, srv_heupstream,
linux-devicetree, Linus Walleij,
Shengnan Wang (王圣男), Tomasz Figa,
Bartosz Golaszewski, Sj Huang, Nicolas Boichat,
moderated list:ARM/Mediatek SoC support, Louis Kuo,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linux Media Mailing List
In-Reply-To: <1591078501.8804.539.camel@mhfsdcap03>
Hi Dongchun,
On Tue, Jun 02, 2020 at 02:15:01PM +0800, Dongchun Zhu wrote:
> Hi Tomasz, Sakari,
>
> On Mon, 2020-06-01 at 20:18 +0200, Tomasz Figa wrote:
> > On Mon, Jun 1, 2020 at 4:35 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> > >
> > > Hi Tomasz,
> > >
> > > On Fri, 2020-05-29 at 15:43 +0200, Tomasz Figa wrote:
> > > > On Thu, May 28, 2020 at 10:06 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> > > > >
> > > > > Hi Sakari,
> > > > >
> > > > > On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> > > > > > Hi Dongchun,
> > > > > >
> > > > > > On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > > > > > > Hi Sakari, Rob,
> > > > > > >
> > > > > > > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > > > > > > Hi Rob, Dongchun,
> > > > > > > >
> > > > > > > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > > > > > > + properties:
> > > > > > > > > > > > + endpoint:
> > > > > > > > > > > > + type: object
> > > > > > > > > > > > + additionalProperties: false
> > > > > > > > > > > > +
> > > > > > > > > > > > + properties:
> > > > > > > > > >
> > > > > > > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > > > > > >
> > > > > > > > > Yes, if you are using it.
> > > > > > > >
> > > > > > > > Dongchun, can you confirm the chip has a single data and a single clock
> > > > > > > > lane and that it does not support lane reordering?
> > > > > > > >
> > > > > > >
> > > > > > > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > > > > > > uni-directional clock lane and one bi-directional data lane solution for
> > > > > > > communication links between components inside a mobile device.
> > > > > > > The data lane has full support for HS(uni-directional) and
> > > > > > > LP(bi-directional) data transfer mode.'
> > > > > > >
> > > > > > > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > > > > > > would not be added in next release.
> > > > > > >
> > > > > > > > So if there's nothing to convey to the driver, also the data-lanes should
> > > > > > > > be removed IMO.
> > > > > > > >
> > > > > > >
> > > > > > > However, 'data-lanes' property may still be required.
> > > > > > > It is known that either data-lanes or clock-lanes is an array of
> > > > > > > physical data lane indexes. Position of an entry determines the logical
> > > > > > > lane number, while the value of an entry indicates physical lane, e.g.,
> > > > > > > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > > > > > > the clock lane is on hardware lane 0.
> > > > > > >
> > > > > > > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > > > > > > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > > > > > > there is only a clock lane for OV02A10.
> > > > > > >
> > > > > > > Reminder:
> > > > > > > If 'data-lanes' property is not present, the driver would assume
> > > > > > > four-lane operation. This means for one-lane or two-lane operation, this
> > > > > > > property must be present and set to the right physical lane indexes.
> > > > > > > If the hardware does not support lane reordering, monotonically
> > > > > > > incremented values shall be used from 0 or 1 onwards, depending on
> > > > > > > whether or not there is also a clock lane.
> > > > > >
> > > > > > How can the driver use four lanes, considering the device only supports a
> > > > > > single lane??
> > > > > >
> > > > >
> > > > > I understood your meaning.
> > > > > If we omit the property 'data-lanes', the sensor should work still.
> > > > > But then what's the meaning of the existence of 'data-lanes'?
> > > > > If this property 'data-lanes' is always optional, then why dt-bindings
> > > > > provide the interface?
> > > > >
> > > > > In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
> > > > > that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
> > > > > shall enable four-lane configuration, which may increase consumption of
> > > > > both power and resource in the process of IIC communication.
> > > >
> > > > Wouldn't the receiver still have the data-lanes property under its
> > > > endpoint node, telling it how many lanes and in which order should be
> > > > used?
> > > >
> > >
> > > The MIPI receiver(RX) shall use
> > > v4l2_async_notifier_add_fwnode_remote_subdev() API to parse the property
> > > "data-lanes" under sensor output port.
> >
> > That's not true. The MIPI receiver driver parses its own port node
> > corresponding to the sensor. Also quoting the documentation [1]:
> >
> > "An endpoint subnode of a device contains all properties needed for
> > _configuration of this device_ for data exchange with other device. In most
> > cases properties at the peer 'endpoint' nodes will be identical, however they
> > might need to be different when there is any signal modifications on the bus
> > between two devices, e.g. there are logic signal inverters on the lines."
> >
> > In this case, there is such a signal modification if the sensor has a
> > 1-lane bus and the receiver more lines, so the data-lanes properties
> > would be different on both sides.
> >
> > [1] https://elixir.bootlin.com/linux/v5.7/source/Documentation/devicetree/bindings/media/video-interfaces.txt
> >
>
> Sorry for the misunderstanding.
> After doing some experiments about the data-lanes property under sensor
> i2c node, we found the API
> v4l2_async_notifier_add_fwnode_remote_subdev() that MIPI receiver driver
> used indeed parses the data-lanes under its own port node.
>
> Sorry make a mistake for the use case of sensor data-lanes previously.
> Now We may encounter one new question for this patch.
> In practice we haven't used the data-lanes under sensor i2c node
> anywhere, if sensor driver itself doesn't parse that.
>
> But there is still one reason to keep the exactly right data-lanes in
> DT. That is, the data-lanes under sensor i2c node could be used as a
> reference for MIPI receiver driver.
> Just as Tomasz said, 'The MIPI receiver driver parses its own port node
> corresponding to the sensor'.
>
> Sakari, Tomasz, what's your opinions about the present of data-lanes
> under sensor node or not?
The receiver driver doesn't parse the properties in the sensor
(transmitter) device's endpoint. If that property provides no information
to the receiver, as is the case here, it should be omitted.
--
Regards,
Sakari Ailus
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Sakari Ailus @ 2020-06-02 9:53 UTC (permalink / raw)
To: Tomasz Figa
Cc: Mark Rutland, Rob Herring, Andy Shevchenko, srv_heupstream,
linux-devicetree, Linus Walleij,
Shengnan Wang (王圣男), Bartosz Golaszewski,
Sj Huang, Nicolas Boichat,
moderated list:ARM/Mediatek SoC support, Dongchun Zhu, Louis Kuo,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linux Media Mailing List
In-Reply-To: <CAAFQd5AuHDpQN8xZsWgnAt6m2reAYJbs9nBp0+mBo7_FS81LbQ@mail.gmail.com>
On Fri, May 29, 2020 at 03:43:30PM +0200, Tomasz Figa wrote:
> On Thu, May 28, 2020 at 10:06 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> >
> > Hi Sakari,
> >
> > On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> > > Hi Dongchun,
> > >
> > > On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > > > Hi Sakari, Rob,
> > > >
> > > > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > > > Hi Rob, Dongchun,
> > > > >
> > > > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > > > + properties:
> > > > > > > > > + endpoint:
> > > > > > > > > + type: object
> > > > > > > > > + additionalProperties: false
> > > > > > > > > +
> > > > > > > > > + properties:
> > > > > > >
> > > > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > > >
> > > > > > Yes, if you are using it.
> > > > >
> > > > > Dongchun, can you confirm the chip has a single data and a single clock
> > > > > lane and that it does not support lane reordering?
> > > > >
> > > >
> > > > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > > > uni-directional clock lane and one bi-directional data lane solution for
> > > > communication links between components inside a mobile device.
> > > > The data lane has full support for HS(uni-directional) and
> > > > LP(bi-directional) data transfer mode.'
> > > >
> > > > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > > > would not be added in next release.
> > > >
> > > > > So if there's nothing to convey to the driver, also the data-lanes should
> > > > > be removed IMO.
> > > > >
> > > >
> > > > However, 'data-lanes' property may still be required.
> > > > It is known that either data-lanes or clock-lanes is an array of
> > > > physical data lane indexes. Position of an entry determines the logical
> > > > lane number, while the value of an entry indicates physical lane, e.g.,
> > > > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > > > the clock lane is on hardware lane 0.
> > > >
> > > > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > > > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > > > there is only a clock lane for OV02A10.
> > > >
> > > > Reminder:
> > > > If 'data-lanes' property is not present, the driver would assume
> > > > four-lane operation. This means for one-lane or two-lane operation, this
> > > > property must be present and set to the right physical lane indexes.
> > > > If the hardware does not support lane reordering, monotonically
> > > > incremented values shall be used from 0 or 1 onwards, depending on
> > > > whether or not there is also a clock lane.
> > >
> > > How can the driver use four lanes, considering the device only supports a
> > > single lane??
> > >
> >
> > I understood your meaning.
> > If we omit the property 'data-lanes', the sensor should work still.
> > But then what's the meaning of the existence of 'data-lanes'?
> > If this property 'data-lanes' is always optional, then why dt-bindings
> > provide the interface?
> >
> > In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
> > that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
> > shall enable four-lane configuration, which may increase consumption of
> > both power and resource in the process of IIC communication.
>
> Wouldn't the receiver still have the data-lanes property under its
> endpoint node, telling it how many lanes and in which order should be
> used?
Yes.
--
Sakari Ailus
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v10] mfd: mt6360: add pmic mt6360 driver
From: Matthias Brugger @ 2020-06-02 9:43 UTC (permalink / raw)
To: Lee Jones, Gene Chen
Cc: gene_chen, linux-kernel, cy_huang, linux-mediatek, Wilma.Wu,
linux-arm-kernel, shufan_lee
In-Reply-To: <20200602082816.GC3714@dell>
On 02/06/2020 10:28, Lee Jones wrote:
> On Tue, 02 Jun 2020, Gene Chen wrote:
>
>> From: Gene Chen <gene_chen@richtek.com>
>>
>> Add MFD driver for mt6360 pmic chip include Battery Charger/
>> USB_PD/Flash, LED/RGB and LED/LDO/Buck
>>
>> Signed-off-by: Gene Chen <gene_chen@richtek.com>
>> Signed-off-by: Lee Jones <lee.jones@linaro.org>
>
> I did not sign this off.
>
You are right, you provided your Acked-for-MFD-by and took an earlier version of
the patch [1]. But as this didn't show up in linux-next I suppose you dropped it
afterwards because of kbuild test errors (deducing from the changes log).
I suppose if this errors are fixed now, we should be fine :)
Regards,
Matthias
[1]
https://lkml.kernel.org/lkml/1587641093-25441-1-git-send-email-gene.chen.richtek@gmail.com/T/#m75e8ee81950ee34e155eccd2dc5ad9b1d2cef40a
>> ---
>> drivers/mfd/Kconfig | 12 ++
>> drivers/mfd/Makefile | 1 +
>> drivers/mfd/mt6360-core.c | 424 +++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/mfd/mt6360.h | 240 +++++++++++++++++++++++++
>> 4 files changed, 677 insertions(+)
>> create mode 100644 drivers/mfd/mt6360-core.c
>> create mode 100644 include/linux/mfd/mt6360.h
>>
>> changelogs between v1 & v2
>> - include missing header file
>>
>> changelogs between v2 & v3
>> - add changelogs
>>
>> changelogs between v3 & v4
>> - fix Kconfig description
>> - replace mt6360_pmu_info with mt6360_pmu_data
>> - replace probe with probe_new
>> - remove unnecessary irq_chip variable
>> - remove annotation
>> - replace MT6360_MFD_CELL with OF_MFD_CELL
>>
>> changelogs between v4 & v5
>> - remove unnecessary parse dt function
>> - use devm_i2c_new_dummy_device
>> - add base-commit message
>>
>> changelogs between v5 & v6
>> - review return value
>> - remove i2c id_table
>> - use GPL license v2
>>
>> changelogs between v6 & v7
>> - add author description
>> - replace MT6360_REGMAP_IRQ_REG by REGMAP_IRQ_REG_LINE
>> - remove mt6360-private.h
>>
>> changelogs between v7 & v8
>> - fix kbuild auto reboot by include interrupt header
>>
>> changelogs between v8 & v9
>> - fix GPL license out of date
>> - add commit message about Acked-for-MFD-by
>>
>> changelogs between v9 & v10
>
> v9 of this patch is already applied.
>
> You cannot send a v10.
>
>> - fix duplicate define of kbuild test reboot initializer-overrides
>
> I fixed this already.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git/commit/?h=for-mfd-next&id=098c4adf249c198519a4abebe482b1e6b8c50e47
>
>> - sync commit message format
>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v10] mfd: mt6360: add pmic mt6360 driver
From: Lee Jones @ 2020-06-02 8:28 UTC (permalink / raw)
To: Gene Chen
Cc: gene_chen, linux-kernel, cy_huang, linux-mediatek, matthias.bgg,
Wilma.Wu, linux-arm-kernel, shufan_lee
In-Reply-To: <1591070142-7653-1-git-send-email-gene.chen.richtek@gmail.com>
On Tue, 02 Jun 2020, Gene Chen wrote:
> From: Gene Chen <gene_chen@richtek.com>
>
> Add MFD driver for mt6360 pmic chip include Battery Charger/
> USB_PD/Flash, LED/RGB and LED/LDO/Buck
>
> Signed-off-by: Gene Chen <gene_chen@richtek.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
I did not sign this off.
> ---
> drivers/mfd/Kconfig | 12 ++
> drivers/mfd/Makefile | 1 +
> drivers/mfd/mt6360-core.c | 424 +++++++++++++++++++++++++++++++++++++++++++++
> include/linux/mfd/mt6360.h | 240 +++++++++++++++++++++++++
> 4 files changed, 677 insertions(+)
> create mode 100644 drivers/mfd/mt6360-core.c
> create mode 100644 include/linux/mfd/mt6360.h
>
> changelogs between v1 & v2
> - include missing header file
>
> changelogs between v2 & v3
> - add changelogs
>
> changelogs between v3 & v4
> - fix Kconfig description
> - replace mt6360_pmu_info with mt6360_pmu_data
> - replace probe with probe_new
> - remove unnecessary irq_chip variable
> - remove annotation
> - replace MT6360_MFD_CELL with OF_MFD_CELL
>
> changelogs between v4 & v5
> - remove unnecessary parse dt function
> - use devm_i2c_new_dummy_device
> - add base-commit message
>
> changelogs between v5 & v6
> - review return value
> - remove i2c id_table
> - use GPL license v2
>
> changelogs between v6 & v7
> - add author description
> - replace MT6360_REGMAP_IRQ_REG by REGMAP_IRQ_REG_LINE
> - remove mt6360-private.h
>
> changelogs between v7 & v8
> - fix kbuild auto reboot by include interrupt header
>
> changelogs between v8 & v9
> - fix GPL license out of date
> - add commit message about Acked-for-MFD-by
>
> changelogs between v9 & v10
v9 of this patch is already applied.
You cannot send a v10.
> - fix duplicate define of kbuild test reboot initializer-overrides
I fixed this already.
https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git/commit/?h=for-mfd-next&id=098c4adf249c198519a4abebe482b1e6b8c50e47
> - sync commit message format
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v6 2/2] hwrng: add sec-rng driver
From: Neal Liu @ 2020-06-02 8:14 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Rob Herring, Matthias Brugger,
Sean Wang, Arnd Bergmann, Greg Kroah-Hartman
Cc: devicetree, wsd_upstream, lkml, Crystal Guo, linux-mediatek,
linux-crypto, Neal Liu, linux-arm-kernel
In-Reply-To: <1591085678-22764-1-git-send-email-neal.liu@mediatek.com>
For security awareness SoCs on ARMv8 with TrustZone enabled,
peripherals like entropy sources is not accessible from normal world
(linux) and rather accessible from secure world (HYP/ATF/TEE) only.
This driver aims to provide a generic interface to Arm Trusted
Firmware or Hypervisor rng service.
Signed-off-by: Neal Liu <neal.liu@mediatek.com>
---
drivers/char/hw_random/Kconfig | 13 ++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/sec-rng.c | 155 ++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+)
create mode 100644 drivers/char/hw_random/sec-rng.c
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 9bc46da..cb9c8a9 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -474,6 +474,19 @@ config HW_RANDOM_KEYSTONE
help
This option enables Keystone's hardware random generator.
+config HW_RANDOM_SECURE
+ tristate "Arm Security Random Number Generator support"
+ depends on HAVE_ARM_SMCCC || COMPILE_TEST
+ default HW_RANDOM
+ help
+ This driver provides kernel-side support for the Arm Security
+ Random Number Generator.
+
+ To compile this driver as a module, choose M here. the
+ module will be called sec-rng.
+
+ If unsure, say Y.
+
endif # HW_RANDOM
config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index a7801b4..04533d1 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -41,3 +41,4 @@ obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
+obj-$(CONFIG_HW_RANDOM_SECURE) += sec-rng.o
diff --git a/drivers/char/hw_random/sec-rng.c b/drivers/char/hw_random/sec-rng.c
new file mode 100644
index 0000000..c6d3872
--- /dev/null
+++ b/drivers/char/hw_random/sec-rng.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/hw_random.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define SMC_RET_NUM 4
+#define SEC_RND_SIZE (sizeof(u32) * SMC_RET_NUM)
+
+#define HWRNG_SMC_FAST_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
+ ARM_SMCCC_OWNER_SIP, (func_num))
+
+#define to_sec_rng(p) container_of(p, struct sec_rng_priv, rng)
+
+typedef void (sec_rng_fn)(unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ struct arm_smccc_res *);
+
+struct sec_rng_priv {
+ u16 func_num;
+ sec_rng_fn *rng_fn;
+ struct hwrng rng;
+};
+
+/* Simple wrapper functions to be able to use a function pointer */
+static void sec_rng_smc(unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ unsigned long a6, unsigned long a7,
+ struct arm_smccc_res *res)
+{
+ arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static void sec_rng_hvc(unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ unsigned long a6, unsigned long a7,
+ struct arm_smccc_res *res)
+{
+ arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static bool __sec_get_rnd(struct sec_rng_priv *priv, uint32_t *val)
+{
+ struct arm_smccc_res res;
+
+ priv->rng_fn(HWRNG_SMC_FAST_CALL_VAL(priv->func_num),
+ 0, 0, 0, 0, 0, 0, 0, &res);
+
+ if (!res.a0 && !res.a1 && !res.a2 && !res.a3)
+ return false;
+
+ val[0] = res.a0;
+ val[1] = res.a1;
+ val[2] = res.a2;
+ val[3] = res.a3;
+
+ return true;
+}
+
+static int sec_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct sec_rng_priv *priv = to_sec_rng(rng);
+ u32 val[4] = {0};
+ int retval = 0;
+ int i;
+
+ while (max >= SEC_RND_SIZE) {
+ if (!__sec_get_rnd(priv, val))
+ return retval;
+
+ for (i = 0; i < SMC_RET_NUM; i++) {
+ *(u32 *)buf = val[i];
+ buf += sizeof(u32);
+ }
+
+ retval += SEC_RND_SIZE;
+ max -= SEC_RND_SIZE;
+ }
+
+ return retval;
+}
+
+static int sec_rng_probe(struct platform_device *pdev)
+{
+ struct sec_rng_priv *priv;
+ const char *method;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (of_property_read_string(pdev->dev.of_node, "method", &method))
+ return -ENXIO;
+
+ if (!strncmp("smc", method, strlen("smc")))
+ priv->rng_fn = sec_rng_smc;
+ else if (!strncmp("hvc", method, strlen("hvc")))
+ priv->rng_fn = sec_rng_hvc;
+
+ if (IS_ERR(priv->rng_fn)) {
+ dev_err(&pdev->dev, "method %s is not supported\n", method);
+ return -EINVAL;
+ }
+
+ if (of_property_read_u16(pdev->dev.of_node, "method-fid",
+ &priv->func_num))
+ return -ENXIO;
+
+ if (of_property_read_u16(pdev->dev.of_node, "quality",
+ &priv->rng.quality))
+ return -ENXIO;
+
+ priv->rng.name = pdev->name;
+ priv->rng.read = sec_rng_read;
+ priv->rng.priv = (unsigned long)&pdev->dev;
+
+ ret = devm_hwrng_register(&pdev->dev, &priv->rng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register rng device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id sec_rng_match[] = {
+ { .compatible = "arm,sec-rng", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sec_rng_match);
+
+static struct platform_driver sec_rng_driver = {
+ .probe = sec_rng_probe,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sec_rng_match,
+ },
+};
+
+module_platform_driver(sec_rng_driver);
+
+MODULE_DESCRIPTION("Security Random Number Generator Driver");
+MODULE_AUTHOR("Neal Liu <neal.liu@mediatek.com>");
+MODULE_LICENSE("GPL");
--
1.7.9.5
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Security Random Number Generator support
From: Neal Liu @ 2020-06-02 8:14 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Rob Herring, Matthias Brugger,
Sean Wang, Arnd Bergmann, Greg Kroah-Hartman
Cc: devicetree, wsd_upstream, lkml, Crystal Guo, linux-mediatek,
linux-crypto, Neal Liu, linux-arm-kernel
These patch series introduce a security random number generator
which provides a generic interface to get hardware rnd from Secure
state. The Secure state can be Arm Trusted Firmware(ATF), Trusted
Execution Environment(TEE), or even EL2 hypervisor.
Patch #1..2 adds sec-rng kernel driver for Trustzone based SoCs.
For security awareness SoCs on ARMv8 with TrustZone enabled,
peripherals like entropy sources is not accessible from normal world
(linux) and rather accessible from secure world (HYP/ATF/TEE) only.
This driver aims to provide a generic interface to Arm Trusted
Firmware or Hypervisor rng service.
changes since v1:
- rename mt67xx-rng to mtk-sec-rng since all MediaTek ARMv8 SoCs can reuse
this driver.
- refine coding style and unnecessary check.
changes since v2:
- remove unused comments.
- remove redundant variable.
changes since v3:
- add dt-bindings for MediaTek rng with TrustZone enabled.
- revise HWRNG SMC call fid.
changes since v4:
- move bindings to the arm/firmware directory.
- revise driver init flow to check more property.
changes since v5:
- refactor to more generic security rng driver which
is not platform specific.
*** BLURB HERE ***
Neal Liu (2):
dt-bindings: rng: add bindings for sec-rng
hwrng: add sec-rng driver
.../devicetree/bindings/rng/sec-rng.yaml | 53 ++++++
drivers/char/hw_random/Kconfig | 13 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/sec-rng.c | 155 ++++++++++++++++++
4 files changed, 222 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/sec-rng.yaml
create mode 100644 drivers/char/hw_random/sec-rng.c
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v6 1/2] dt-bindings: rng: add bindings for sec-rng
From: Neal Liu @ 2020-06-02 8:14 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Rob Herring, Matthias Brugger,
Sean Wang, Arnd Bergmann, Greg Kroah-Hartman
Cc: devicetree, wsd_upstream, lkml, Crystal Guo, linux-mediatek,
linux-crypto, Neal Liu, linux-arm-kernel
In-Reply-To: <1591085678-22764-1-git-send-email-neal.liu@mediatek.com>
Add bindings for ARM TrustZone based Security Random
Number Generator.
Signed-off-by: Neal Liu <neal.liu@mediatek.com>
---
Documentation/devicetree/bindings/rng/sec-rng.yaml | 53 ++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/sec-rng.yaml
diff --git a/Documentation/devicetree/bindings/rng/sec-rng.yaml b/Documentation/devicetree/bindings/rng/sec-rng.yaml
new file mode 100644
index 0000000..7f4ae50
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/sec-rng.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# # Copyright 2020 MediaTek Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/rng/sec-rng.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Security Random Number Generator
+
+description: |
+ sec-rng is a security random number generator which provides a generic
+ interface to get hardware rnd from Secure state. The Secure state can be
+ Arm Trusted Firmware(ATF), Trusted Execution Environment(TEE), or even
+ EL2 hypervisor.
+
+maintainer:
+ - Neal Liu <neal.liu@mediatek.com>
+
+properties:
+ compatible:
+ enum:
+ - arm,sec-rng
+
+ method:
+ description: The method of calling to Secure state
+ enum:
+ - smc
+ - hvc
+
+ method-fid:
+ description: The function number within the SMC and HVC function identifier
+ maxItems: 1
+
+ quality:
+ description: Estimation of true entropy in RNG's bitstream per 1024 bits
+ maxItems: 1
+
+required:
+ - compatible
+ - methods
+ - method-fid
+ - quality
+
+additionalProperties: false
+
+examples:
+ - |
+ hwrng: hwrng {
+ compatible = "arm,sec-rng";
+ method = "smc";
+ method-fid = /bits/ 16 <0x26a>;
+ quality = /bits/ 16 <900>;
+ };
--
1.7.9.5
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Dongchun Zhu @ 2020-06-02 6:15 UTC (permalink / raw)
To: Tomasz Figa
Cc: Mark Rutland, Rob Herring, Andy Shevchenko, srv_heupstream,
linux-devicetree, Linus Walleij,
Shengnan Wang (王圣男), Louis Kuo,
Bartosz Golaszewski, Sj Huang, Nicolas Boichat,
moderated list:ARM/Mediatek SoC support, Sakari Ailus,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linux Media Mailing List
In-Reply-To: <CAAFQd5AY9gejoiwxojvvG0FaVfEAf8gCqOddvo-dxemQWFksVw@mail.gmail.com>
Hi Tomasz, Sakari,
On Mon, 2020-06-01 at 20:18 +0200, Tomasz Figa wrote:
> On Mon, Jun 1, 2020 at 4:35 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> >
> > Hi Tomasz,
> >
> > On Fri, 2020-05-29 at 15:43 +0200, Tomasz Figa wrote:
> > > On Thu, May 28, 2020 at 10:06 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> > > >
> > > > Hi Sakari,
> > > >
> > > > On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> > > > > Hi Dongchun,
> > > > >
> > > > > On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > > > > > Hi Sakari, Rob,
> > > > > >
> > > > > > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > > > > > Hi Rob, Dongchun,
> > > > > > >
> > > > > > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > > > > > + properties:
> > > > > > > > > > > + endpoint:
> > > > > > > > > > > + type: object
> > > > > > > > > > > + additionalProperties: false
> > > > > > > > > > > +
> > > > > > > > > > > + properties:
> > > > > > > > >
> > > > > > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > > > > >
> > > > > > > > Yes, if you are using it.
> > > > > > >
> > > > > > > Dongchun, can you confirm the chip has a single data and a single clock
> > > > > > > lane and that it does not support lane reordering?
> > > > > > >
> > > > > >
> > > > > > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > > > > > uni-directional clock lane and one bi-directional data lane solution for
> > > > > > communication links between components inside a mobile device.
> > > > > > The data lane has full support for HS(uni-directional) and
> > > > > > LP(bi-directional) data transfer mode.'
> > > > > >
> > > > > > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > > > > > would not be added in next release.
> > > > > >
> > > > > > > So if there's nothing to convey to the driver, also the data-lanes should
> > > > > > > be removed IMO.
> > > > > > >
> > > > > >
> > > > > > However, 'data-lanes' property may still be required.
> > > > > > It is known that either data-lanes or clock-lanes is an array of
> > > > > > physical data lane indexes. Position of an entry determines the logical
> > > > > > lane number, while the value of an entry indicates physical lane, e.g.,
> > > > > > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > > > > > the clock lane is on hardware lane 0.
> > > > > >
> > > > > > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > > > > > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > > > > > there is only a clock lane for OV02A10.
> > > > > >
> > > > > > Reminder:
> > > > > > If 'data-lanes' property is not present, the driver would assume
> > > > > > four-lane operation. This means for one-lane or two-lane operation, this
> > > > > > property must be present and set to the right physical lane indexes.
> > > > > > If the hardware does not support lane reordering, monotonically
> > > > > > incremented values shall be used from 0 or 1 onwards, depending on
> > > > > > whether or not there is also a clock lane.
> > > > >
> > > > > How can the driver use four lanes, considering the device only supports a
> > > > > single lane??
> > > > >
> > > >
> > > > I understood your meaning.
> > > > If we omit the property 'data-lanes', the sensor should work still.
> > > > But then what's the meaning of the existence of 'data-lanes'?
> > > > If this property 'data-lanes' is always optional, then why dt-bindings
> > > > provide the interface?
> > > >
> > > > In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
> > > > that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
> > > > shall enable four-lane configuration, which may increase consumption of
> > > > both power and resource in the process of IIC communication.
> > >
> > > Wouldn't the receiver still have the data-lanes property under its
> > > endpoint node, telling it how many lanes and in which order should be
> > > used?
> > >
> >
> > The MIPI receiver(RX) shall use
> > v4l2_async_notifier_add_fwnode_remote_subdev() API to parse the property
> > "data-lanes" under sensor output port.
>
> That's not true. The MIPI receiver driver parses its own port node
> corresponding to the sensor. Also quoting the documentation [1]:
>
> "An endpoint subnode of a device contains all properties needed for
> _configuration of this device_ for data exchange with other device. In most
> cases properties at the peer 'endpoint' nodes will be identical, however they
> might need to be different when there is any signal modifications on the bus
> between two devices, e.g. there are logic signal inverters on the lines."
>
> In this case, there is such a signal modification if the sensor has a
> 1-lane bus and the receiver more lines, so the data-lanes properties
> would be different on both sides.
>
> [1] https://elixir.bootlin.com/linux/v5.7/source/Documentation/devicetree/bindings/media/video-interfaces.txt
>
Sorry for the misunderstanding.
After doing some experiments about the data-lanes property under sensor
i2c node, we found the API
v4l2_async_notifier_add_fwnode_remote_subdev() that MIPI receiver driver
used indeed parses the data-lanes under its own port node.
Sorry make a mistake for the use case of sensor data-lanes previously.
Now We may encounter one new question for this patch.
In practice we haven't used the data-lanes under sensor i2c node
anywhere, if sensor driver itself doesn't parse that.
But there is still one reason to keep the exactly right data-lanes in
DT. That is, the data-lanes under sensor i2c node could be used as a
reference for MIPI receiver driver.
Just as Tomasz said, 'The MIPI receiver driver parses its own port node
corresponding to the sensor'.
Sakari, Tomasz, what's your opinions about the present of data-lanes
under sensor node or not?
> Best regards,
> Tomasz
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v10] mfd: mt6360: add pmic mt6360 driver
From: Gene Chen @ 2020-06-02 3:55 UTC (permalink / raw)
To: lee.jones, matthias.bgg
Cc: gene_chen, linux-kernel, cy_huang, linux-mediatek, Wilma.Wu,
linux-arm-kernel, shufan_lee
From: Gene Chen <gene_chen@richtek.com>
Add MFD driver for mt6360 pmic chip include Battery Charger/
USB_PD/Flash, LED/RGB and LED/LDO/Buck
Signed-off-by: Gene Chen <gene_chen@richtek.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/Kconfig | 12 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/mt6360-core.c | 424 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/mt6360.h | 240 +++++++++++++++++++++++++
4 files changed, 677 insertions(+)
create mode 100644 drivers/mfd/mt6360-core.c
create mode 100644 include/linux/mfd/mt6360.h
changelogs between v1 & v2
- include missing header file
changelogs between v2 & v3
- add changelogs
changelogs between v3 & v4
- fix Kconfig description
- replace mt6360_pmu_info with mt6360_pmu_data
- replace probe with probe_new
- remove unnecessary irq_chip variable
- remove annotation
- replace MT6360_MFD_CELL with OF_MFD_CELL
changelogs between v4 & v5
- remove unnecessary parse dt function
- use devm_i2c_new_dummy_device
- add base-commit message
changelogs between v5 & v6
- review return value
- remove i2c id_table
- use GPL license v2
changelogs between v6 & v7
- add author description
- replace MT6360_REGMAP_IRQ_REG by REGMAP_IRQ_REG_LINE
- remove mt6360-private.h
changelogs between v7 & v8
- fix kbuild auto reboot by include interrupt header
changelogs between v8 & v9
- fix GPL license out of date
- add commit message about Acked-for-MFD-by
changelogs between v9 & v10
- fix duplicate define of kbuild test reboot initializer-overrides
- sync commit message format
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0a59249..3f8a0a0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -870,6 +870,18 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_MT6360
+ tristate "Mediatek MT6360 SubPMIC"
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ depends on I2C
+ help
+ Say Y here to enable MT6360 PMU/PMIC/LDO functional support.
+ PMU part includes Charger, Flashlight, RGB LED
+ PMIC part includes 2-channel BUCKs and 2-channel LDOs
+ LDO part includes 4-channel LDOs
+
config MFD_MT6397
tristate "MediaTek MT6397 PMIC Support"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f935d10..01fa149 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -239,6 +239,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
+obj-$(CONFIG_MFD_MT6360) += mt6360-core.o
mt6397-objs := mt6397-core.o mt6397-irq.o
obj-$(CONFIG_MFD_MT6397) += mt6397.o
obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o
diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
new file mode 100644
index 0000000..db8cdf5
--- /dev/null
+++ b/drivers/mfd/mt6360-core.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * Author: Gene Chen <gene_chen@richtek.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/version.h>
+
+#include <linux/mfd/mt6360.h>
+
+/* reg 0 -> 0 ~ 7 */
+#define MT6360_CHG_TREG_EVT (4)
+#define MT6360_CHG_AICR_EVT (5)
+#define MT6360_CHG_MIVR_EVT (6)
+#define MT6360_PWR_RDY_EVT (7)
+/* REG 1 -> 8 ~ 15 */
+#define MT6360_CHG_BATSYSUV_EVT (9)
+#define MT6360_FLED_CHG_VINOVP_EVT (11)
+#define MT6360_CHG_VSYSUV_EVT (12)
+#define MT6360_CHG_VSYSOV_EVT (13)
+#define MT6360_CHG_VBATOV_EVT (14)
+#define MT6360_CHG_VBUSOV_EVT (15)
+/* REG 2 -> 16 ~ 23 */
+/* REG 3 -> 24 ~ 31 */
+#define MT6360_WD_PMU_DET (25)
+#define MT6360_WD_PMU_DONE (26)
+#define MT6360_CHG_TMRI (27)
+#define MT6360_CHG_ADPBADI (29)
+#define MT6360_CHG_RVPI (30)
+#define MT6360_OTPI (31)
+/* REG 4 -> 32 ~ 39 */
+#define MT6360_CHG_AICCMEASL (32)
+#define MT6360_CHGDET_DONEI (34)
+#define MT6360_WDTMRI (35)
+#define MT6360_SSFINISHI (36)
+#define MT6360_CHG_RECHGI (37)
+#define MT6360_CHG_TERMI (38)
+#define MT6360_CHG_IEOCI (39)
+/* REG 5 -> 40 ~ 47 */
+#define MT6360_PUMPX_DONEI (40)
+#define MT6360_BAT_OVP_ADC_EVT (41)
+#define MT6360_TYPEC_OTP_EVT (42)
+#define MT6360_ADC_WAKEUP_EVT (43)
+#define MT6360_ADC_DONEI (44)
+#define MT6360_BST_BATUVI (45)
+#define MT6360_BST_VBUSOVI (46)
+#define MT6360_BST_OLPI (47)
+/* REG 6 -> 48 ~ 55 */
+#define MT6360_ATTACH_I (48)
+#define MT6360_DETACH_I (49)
+#define MT6360_QC30_STPDONE (51)
+#define MT6360_QC_VBUSDET_DONE (52)
+#define MT6360_HVDCP_DET (53)
+#define MT6360_CHGDETI (54)
+#define MT6360_DCDTI (55)
+/* REG 7 -> 56 ~ 63 */
+#define MT6360_FOD_DONE_EVT (56)
+#define MT6360_FOD_OV_EVT (57)
+#define MT6360_CHRDET_UVP_EVT (58)
+#define MT6360_CHRDET_OVP_EVT (59)
+#define MT6360_CHRDET_EXT_EVT (60)
+#define MT6360_FOD_LR_EVT (61)
+#define MT6360_FOD_HR_EVT (62)
+#define MT6360_FOD_DISCHG_FAIL_EVT (63)
+/* REG 8 -> 64 ~ 71 */
+#define MT6360_USBID_EVT (64)
+#define MT6360_APWDTRST_EVT (65)
+#define MT6360_EN_EVT (66)
+#define MT6360_QONB_RST_EVT (67)
+#define MT6360_MRSTB_EVT (68)
+#define MT6360_OTP_EVT (69)
+#define MT6360_VDDAOV_EVT (70)
+#define MT6360_SYSUV_EVT (71)
+/* REG 9 -> 72 ~ 79 */
+#define MT6360_FLED_STRBPIN_EVT (72)
+#define MT6360_FLED_TORPIN_EVT (73)
+#define MT6360_FLED_TX_EVT (74)
+#define MT6360_FLED_LVF_EVT (75)
+#define MT6360_FLED2_SHORT_EVT (78)
+#define MT6360_FLED1_SHORT_EVT (79)
+/* REG 10 -> 80 ~ 87 */
+#define MT6360_FLED2_STRB_EVT (80)
+#define MT6360_FLED1_STRB_EVT (81)
+#define MT6360_FLED2_STRB_TO_EVT (82)
+#define MT6360_FLED1_STRB_TO_EVT (83)
+#define MT6360_FLED2_TOR_EVT (84)
+#define MT6360_FLED1_TOR_EVT (85)
+/* REG 11 -> 88 ~ 95 */
+/* REG 12 -> 96 ~ 103 */
+#define MT6360_BUCK1_PGB_EVT (96)
+#define MT6360_BUCK1_OC_EVT (100)
+#define MT6360_BUCK1_OV_EVT (101)
+#define MT6360_BUCK1_UV_EVT (102)
+/* REG 13 -> 104 ~ 111 */
+#define MT6360_BUCK2_PGB_EVT (104)
+#define MT6360_BUCK2_OC_EVT (108)
+#define MT6360_BUCK2_OV_EVT (109)
+#define MT6360_BUCK2_UV_EVT (110)
+/* REG 14 -> 112 ~ 119 */
+#define MT6360_LDO1_OC_EVT (113)
+#define MT6360_LDO2_OC_EVT (114)
+#define MT6360_LDO3_OC_EVT (115)
+#define MT6360_LDO5_OC_EVT (117)
+#define MT6360_LDO6_OC_EVT (118)
+#define MT6360_LDO7_OC_EVT (119)
+/* REG 15 -> 120 ~ 127 */
+#define MT6360_LDO1_PGB_EVT (121)
+#define MT6360_LDO2_PGB_EVT (122)
+#define MT6360_LDO3_PGB_EVT (123)
+#define MT6360_LDO5_PGB_EVT (125)
+#define MT6360_LDO6_PGB_EVT (126)
+#define MT6360_LDO7_PGB_EVT (127)
+
+static const struct regmap_irq mt6360_pmu_irqs[] = {
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_TREG_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_AICR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_MIVR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_PWR_RDY_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_BATSYSUV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED_CHG_VINOVP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSUV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSOV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_VBATOV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_VBUSOV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DET, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DONE, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_TMRI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_ADPBADI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_RVPI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_OTPI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_AICCMEASL, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHGDET_DONEI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_WDTMRI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_SSFINISHI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_RECHGI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_TERMI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHG_IEOCI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_PUMPX_DONEI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BAT_OVP_ADC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_TYPEC_OTP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_ADC_WAKEUP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_ADC_DONEI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BST_BATUVI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BST_VBUSOVI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BST_OLPI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_ATTACH_I, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_DETACH_I, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_QC30_STPDONE, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_QC_VBUSDET_DONE, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_HVDCP_DET, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHGDETI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_DCDTI, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FOD_DONE_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FOD_OV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHRDET_UVP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHRDET_OVP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_CHRDET_EXT_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FOD_LR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FOD_HR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FOD_DISCHG_FAIL_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_USBID_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_APWDTRST_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_EN_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_QONB_RST_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_MRSTB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_OTP_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_VDDAOV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_SYSUV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED_STRBPIN_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED_TORPIN_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED_TX_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED_LVF_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED2_SHORT_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED1_SHORT_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_TO_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_TO_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED2_TOR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_FLED1_TOR_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK1_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK1_UV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK2_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_BUCK2_UV_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO1_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO2_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO3_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO5_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO6_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO7_OC_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO1_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO2_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO3_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO5_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO6_PGB_EVT, 8),
+ REGMAP_IRQ_REG_LINE(MT6360_LDO7_PGB_EVT, 8),
+};
+
+static int mt6360_pmu_handle_post_irq(void *irq_drv_data)
+{
+ struct mt6360_pmu_data *mpd = irq_drv_data;
+
+ return regmap_update_bits(mpd->regmap,
+ MT6360_PMU_IRQ_SET, MT6360_IRQ_RETRIG, MT6360_IRQ_RETRIG);
+}
+
+static struct regmap_irq_chip mt6360_pmu_irq_chip = {
+ .irqs = mt6360_pmu_irqs,
+ .num_irqs = ARRAY_SIZE(mt6360_pmu_irqs),
+ .num_regs = MT6360_PMU_IRQ_REGNUM,
+ .mask_base = MT6360_PMU_CHG_MASK1,
+ .status_base = MT6360_PMU_CHG_IRQ1,
+ .ack_base = MT6360_PMU_CHG_IRQ1,
+ .init_ack_masked = true,
+ .use_ack = true,
+ .handle_post_irq = mt6360_pmu_handle_post_irq,
+};
+
+static const struct regmap_config mt6360_pmu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MT6360_PMU_MAXREG,
+};
+
+static const struct resource mt6360_adc_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_ADC_DONEI, "adc_donei"),
+};
+
+static const struct resource mt6360_chg_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_TREG_EVT, "chg_treg_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_PWR_RDY_EVT, "pwr_rdy_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_BATSYSUV_EVT, "chg_batsysuv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSUV_EVT, "chg_vsysuv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSOV_EVT, "chg_vsysov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBATOV_EVT, "chg_vbatov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBUSOV_EVT, "chg_vbusov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_AICCMEASL, "chg_aiccmeasl"),
+ DEFINE_RES_IRQ_NAMED(MT6360_WDTMRI, "wdtmri"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_RECHGI, "chg_rechgi"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_TERMI, "chg_termi"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_IEOCI, "chg_ieoci"),
+ DEFINE_RES_IRQ_NAMED(MT6360_PUMPX_DONEI, "pumpx_donei"),
+ DEFINE_RES_IRQ_NAMED(MT6360_ATTACH_I, "attach_i"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHRDET_EXT_EVT, "chrdet_ext_evt"),
+};
+
+static const struct resource mt6360_led_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED_CHG_VINOVP_EVT, "fled_chg_vinovp_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED_LVF_EVT, "fled_lvf_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED2_SHORT_EVT, "fled2_short_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED1_SHORT_EVT, "fled1_short_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED2_STRB_TO_EVT, "fled2_strb_to_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED1_STRB_TO_EVT, "fled1_strb_to_evt"),
+};
+
+static const struct resource mt6360_pmic_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_PGB_EVT, "buck1_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OC_EVT, "buck1_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OV_EVT, "buck1_ov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_UV_EVT, "buck1_uv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_PGB_EVT, "buck2_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OC_EVT, "buck2_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OV_EVT, "buck2_ov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_UV_EVT, "buck2_uv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"),
+};
+
+static const struct resource mt6360_ldo_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO5_OC_EVT, "ldo5_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO1_PGB_EVT, "ldo1_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO2_PGB_EVT, "ldo2_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO3_PGB_EVT, "ldo3_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO5_PGB_EVT, "ldo5_pgb_evt"),
+};
+
+static const struct mfd_cell mt6360_devs[] = {
+ OF_MFD_CELL("mt6360_adc", mt6360_adc_resources,
+ NULL, 0, 0, "mediatek,mt6360_adc"),
+ OF_MFD_CELL("mt6360_chg", mt6360_chg_resources,
+ NULL, 0, 0, "mediatek,mt6360_chg"),
+ OF_MFD_CELL("mt6360_led", mt6360_led_resources,
+ NULL, 0, 0, "mediatek,mt6360_led"),
+ OF_MFD_CELL("mt6360_pmic", mt6360_pmic_resources,
+ NULL, 0, 0, "mediatek,mt6360_pmic"),
+ OF_MFD_CELL("mt6360_ldo", mt6360_ldo_resources,
+ NULL, 0, 0, "mediatek,mt6360_ldo"),
+ OF_MFD_CELL("mt6360_tcpc", NULL,
+ NULL, 0, 0, "mediatek,mt6360_tcpc"),
+};
+
+static const unsigned short mt6360_slave_addr[MT6360_SLAVE_MAX] = {
+ MT6360_PMU_SLAVEID,
+ MT6360_PMIC_SLAVEID,
+ MT6360_LDO_SLAVEID,
+ MT6360_TCPC_SLAVEID,
+};
+
+static int mt6360_pmu_probe(struct i2c_client *client)
+{
+ struct mt6360_pmu_data *mpd;
+ unsigned int reg_data;
+ int i, ret;
+
+ mpd = devm_kzalloc(&client->dev, sizeof(*mpd), GFP_KERNEL);
+ if (!mpd)
+ return -ENOMEM;
+
+ mpd->dev = &client->dev;
+ i2c_set_clientdata(client, mpd);
+
+ mpd->regmap = devm_regmap_init_i2c(client, &mt6360_pmu_regmap_config);
+ if (IS_ERR(mpd->regmap)) {
+ dev_err(&client->dev, "Failed to register regmap\n");
+ return PTR_ERR(mpd->regmap);
+ }
+
+ ret = regmap_read(mpd->regmap, MT6360_PMU_DEV_INFO, ®_data);
+ if (ret) {
+ dev_err(&client->dev, "Device not found\n");
+ return ret;
+ }
+
+ mpd->chip_rev = reg_data & CHIP_REV_MASK;
+ if (mpd->chip_rev != CHIP_VEN_MT6360) {
+ dev_err(&client->dev, "Device not supported\n");
+ return -ENODEV;
+ }
+
+ mt6360_pmu_irq_chip.irq_drv_data = mpd;
+ ret = devm_regmap_add_irq_chip(&client->dev, mpd->regmap, client->irq,
+ IRQF_TRIGGER_FALLING, 0,
+ &mt6360_pmu_irq_chip, &mpd->irq_data);
+ if (ret) {
+ dev_err(&client->dev, "Failed to add Regmap IRQ Chip\n");
+ return ret;
+ }
+
+ mpd->i2c[0] = client;
+ for (i = 1; i < MT6360_SLAVE_MAX; i++) {
+ mpd->i2c[i] = devm_i2c_new_dummy_device(&client->dev,
+ client->adapter,
+ mt6360_slave_addr[i]);
+ if (IS_ERR(mpd->i2c[i])) {
+ dev_err(&client->dev,
+ "Failed to get new dummy I2C device for address 0x%x",
+ mt6360_slave_addr[i]);
+ return PTR_ERR(mpd->i2c[i]);
+ }
+ i2c_set_clientdata(mpd->i2c[i], mpd);
+ }
+
+ ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
+ mt6360_devs, ARRAY_SIZE(mt6360_devs), NULL,
+ 0, regmap_irq_get_domain(mpd->irq_data));
+ if (ret) {
+ dev_err(&client->dev,
+ "Failed to register subordinate devices\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused mt6360_pmu_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(i2c->irq);
+
+ return 0;
+}
+
+static int __maybe_unused mt6360_pmu_resume(struct device *dev)
+{
+
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(i2c->irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mt6360_pmu_pm_ops,
+ mt6360_pmu_suspend, mt6360_pmu_resume);
+
+static const struct of_device_id __maybe_unused mt6360_pmu_of_id[] = {
+ { .compatible = "mediatek,mt6360_pmu", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id);
+
+static struct i2c_driver mt6360_pmu_driver = {
+ .driver = {
+ .pm = &mt6360_pmu_pm_ops,
+ .of_match_table = of_match_ptr(mt6360_pmu_of_id),
+ },
+ .probe_new = mt6360_pmu_probe,
+};
+module_i2c_driver(mt6360_pmu_driver);
+
+MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>");
+MODULE_DESCRIPTION("MT6360 PMU I2C Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/mt6360.h b/include/linux/mfd/mt6360.h
new file mode 100644
index 0000000..ea13040
--- /dev/null
+++ b/include/linux/mfd/mt6360.h
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#ifndef __MT6360_H__
+#define __MT6360_H__
+
+#include <linux/regmap.h>
+
+enum {
+ MT6360_SLAVE_PMU = 0,
+ MT6360_SLAVE_PMIC,
+ MT6360_SLAVE_LDO,
+ MT6360_SLAVE_TCPC,
+ MT6360_SLAVE_MAX,
+};
+
+#define MT6360_PMU_SLAVEID (0x34)
+#define MT6360_PMIC_SLAVEID (0x1A)
+#define MT6360_LDO_SLAVEID (0x64)
+#define MT6360_TCPC_SLAVEID (0x4E)
+
+struct mt6360_pmu_data {
+ struct i2c_client *i2c[MT6360_SLAVE_MAX];
+ struct device *dev;
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data;
+ unsigned int chip_rev;
+};
+
+/* PMU register defininition */
+#define MT6360_PMU_DEV_INFO (0x00)
+#define MT6360_PMU_CORE_CTRL1 (0x01)
+#define MT6360_PMU_RST1 (0x02)
+#define MT6360_PMU_CRCEN (0x03)
+#define MT6360_PMU_RST_PAS_CODE1 (0x04)
+#define MT6360_PMU_RST_PAS_CODE2 (0x05)
+#define MT6360_PMU_CORE_CTRL2 (0x06)
+#define MT6360_PMU_TM_PAS_CODE1 (0x07)
+#define MT6360_PMU_TM_PAS_CODE2 (0x08)
+#define MT6360_PMU_TM_PAS_CODE3 (0x09)
+#define MT6360_PMU_TM_PAS_CODE4 (0x0A)
+#define MT6360_PMU_IRQ_IND (0x0B)
+#define MT6360_PMU_IRQ_MASK (0x0C)
+#define MT6360_PMU_IRQ_SET (0x0D)
+#define MT6360_PMU_SHDN_CTRL (0x0E)
+#define MT6360_PMU_TM_INF (0x0F)
+#define MT6360_PMU_I2C_CTRL (0x10)
+#define MT6360_PMU_CHG_CTRL1 (0x11)
+#define MT6360_PMU_CHG_CTRL2 (0x12)
+#define MT6360_PMU_CHG_CTRL3 (0x13)
+#define MT6360_PMU_CHG_CTRL4 (0x14)
+#define MT6360_PMU_CHG_CTRL5 (0x15)
+#define MT6360_PMU_CHG_CTRL6 (0x16)
+#define MT6360_PMU_CHG_CTRL7 (0x17)
+#define MT6360_PMU_CHG_CTRL8 (0x18)
+#define MT6360_PMU_CHG_CTRL9 (0x19)
+#define MT6360_PMU_CHG_CTRL10 (0x1A)
+#define MT6360_PMU_CHG_CTRL11 (0x1B)
+#define MT6360_PMU_CHG_CTRL12 (0x1C)
+#define MT6360_PMU_CHG_CTRL13 (0x1D)
+#define MT6360_PMU_CHG_CTRL14 (0x1E)
+#define MT6360_PMU_CHG_CTRL15 (0x1F)
+#define MT6360_PMU_CHG_CTRL16 (0x20)
+#define MT6360_PMU_CHG_AICC_RESULT (0x21)
+#define MT6360_PMU_DEVICE_TYPE (0x22)
+#define MT6360_PMU_QC_CONTROL1 (0x23)
+#define MT6360_PMU_QC_CONTROL2 (0x24)
+#define MT6360_PMU_QC30_CONTROL1 (0x25)
+#define MT6360_PMU_QC30_CONTROL2 (0x26)
+#define MT6360_PMU_USB_STATUS1 (0x27)
+#define MT6360_PMU_QC_STATUS1 (0x28)
+#define MT6360_PMU_QC_STATUS2 (0x29)
+#define MT6360_PMU_CHG_PUMP (0x2A)
+#define MT6360_PMU_CHG_CTRL17 (0x2B)
+#define MT6360_PMU_CHG_CTRL18 (0x2C)
+#define MT6360_PMU_CHRDET_CTRL1 (0x2D)
+#define MT6360_PMU_CHRDET_CTRL2 (0x2E)
+#define MT6360_PMU_DPDN_CTRL (0x2F)
+#define MT6360_PMU_CHG_HIDDEN_CTRL1 (0x30)
+#define MT6360_PMU_CHG_HIDDEN_CTRL2 (0x31)
+#define MT6360_PMU_CHG_HIDDEN_CTRL3 (0x32)
+#define MT6360_PMU_CHG_HIDDEN_CTRL4 (0x33)
+#define MT6360_PMU_CHG_HIDDEN_CTRL5 (0x34)
+#define MT6360_PMU_CHG_HIDDEN_CTRL6 (0x35)
+#define MT6360_PMU_CHG_HIDDEN_CTRL7 (0x36)
+#define MT6360_PMU_CHG_HIDDEN_CTRL8 (0x37)
+#define MT6360_PMU_CHG_HIDDEN_CTRL9 (0x38)
+#define MT6360_PMU_CHG_HIDDEN_CTRL10 (0x39)
+#define MT6360_PMU_CHG_HIDDEN_CTRL11 (0x3A)
+#define MT6360_PMU_CHG_HIDDEN_CTRL12 (0x3B)
+#define MT6360_PMU_CHG_HIDDEN_CTRL13 (0x3C)
+#define MT6360_PMU_CHG_HIDDEN_CTRL14 (0x3D)
+#define MT6360_PMU_CHG_HIDDEN_CTRL15 (0x3E)
+#define MT6360_PMU_CHG_HIDDEN_CTRL16 (0x3F)
+#define MT6360_PMU_CHG_HIDDEN_CTRL17 (0x40)
+#define MT6360_PMU_CHG_HIDDEN_CTRL18 (0x41)
+#define MT6360_PMU_CHG_HIDDEN_CTRL19 (0x42)
+#define MT6360_PMU_CHG_HIDDEN_CTRL20 (0x43)
+#define MT6360_PMU_CHG_HIDDEN_CTRL21 (0x44)
+#define MT6360_PMU_CHG_HIDDEN_CTRL22 (0x45)
+#define MT6360_PMU_CHG_HIDDEN_CTRL23 (0x46)
+#define MT6360_PMU_CHG_HIDDEN_CTRL24 (0x47)
+#define MT6360_PMU_CHG_HIDDEN_CTRL25 (0x48)
+#define MT6360_PMU_BC12_CTRL (0x49)
+#define MT6360_PMU_CHG_STAT (0x4A)
+#define MT6360_PMU_RESV1 (0x4B)
+#define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEH (0x4E)
+#define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEL (0x4F)
+#define MT6360_PMU_TYPEC_OTP_HYST_TH (0x50)
+#define MT6360_PMU_TYPEC_OTP_CTRL (0x51)
+#define MT6360_PMU_ADC_BAT_DATA_H (0x52)
+#define MT6360_PMU_ADC_BAT_DATA_L (0x53)
+#define MT6360_PMU_IMID_BACKBST_ON (0x54)
+#define MT6360_PMU_IMID_BACKBST_OFF (0x55)
+#define MT6360_PMU_ADC_CONFIG (0x56)
+#define MT6360_PMU_ADC_EN2 (0x57)
+#define MT6360_PMU_ADC_IDLE_T (0x58)
+#define MT6360_PMU_ADC_RPT_1 (0x5A)
+#define MT6360_PMU_ADC_RPT_2 (0x5B)
+#define MT6360_PMU_ADC_RPT_3 (0x5C)
+#define MT6360_PMU_ADC_RPT_ORG1 (0x5D)
+#define MT6360_PMU_ADC_RPT_ORG2 (0x5E)
+#define MT6360_PMU_BAT_OVP_TH_SEL_CODEH (0x5F)
+#define MT6360_PMU_BAT_OVP_TH_SEL_CODEL (0x60)
+#define MT6360_PMU_CHG_CTRL19 (0x61)
+#define MT6360_PMU_VDDASUPPLY (0x62)
+#define MT6360_PMU_BC12_MANUAL (0x63)
+#define MT6360_PMU_CHGDET_FUNC (0x64)
+#define MT6360_PMU_FOD_CTRL (0x65)
+#define MT6360_PMU_CHG_CTRL20 (0x66)
+#define MT6360_PMU_CHG_HIDDEN_CTRL26 (0x67)
+#define MT6360_PMU_CHG_HIDDEN_CTRL27 (0x68)
+#define MT6360_PMU_RESV2 (0x69)
+#define MT6360_PMU_USBID_CTRL1 (0x6D)
+#define MT6360_PMU_USBID_CTRL2 (0x6E)
+#define MT6360_PMU_USBID_CTRL3 (0x6F)
+#define MT6360_PMU_FLED_CFG (0x70)
+#define MT6360_PMU_RESV3 (0x71)
+#define MT6360_PMU_FLED1_CTRL (0x72)
+#define MT6360_PMU_FLED_STRB_CTRL (0x73)
+#define MT6360_PMU_FLED1_STRB_CTRL2 (0x74)
+#define MT6360_PMU_FLED1_TOR_CTRL (0x75)
+#define MT6360_PMU_FLED2_CTRL (0x76)
+#define MT6360_PMU_RESV4 (0x77)
+#define MT6360_PMU_FLED2_STRB_CTRL2 (0x78)
+#define MT6360_PMU_FLED2_TOR_CTRL (0x79)
+#define MT6360_PMU_FLED_VMIDTRK_CTRL1 (0x7A)
+#define MT6360_PMU_FLED_VMID_RTM (0x7B)
+#define MT6360_PMU_FLED_VMIDTRK_CTRL2 (0x7C)
+#define MT6360_PMU_FLED_PWSEL (0x7D)
+#define MT6360_PMU_FLED_EN (0x7E)
+#define MT6360_PMU_FLED_Hidden1 (0x7F)
+#define MT6360_PMU_RGB_EN (0x80)
+#define MT6360_PMU_RGB1_ISNK (0x81)
+#define MT6360_PMU_RGB2_ISNK (0x82)
+#define MT6360_PMU_RGB3_ISNK (0x83)
+#define MT6360_PMU_RGB_ML_ISNK (0x84)
+#define MT6360_PMU_RGB1_DIM (0x85)
+#define MT6360_PMU_RGB2_DIM (0x86)
+#define MT6360_PMU_RGB3_DIM (0x87)
+#define MT6360_PMU_RESV5 (0x88)
+#define MT6360_PMU_RGB12_Freq (0x89)
+#define MT6360_PMU_RGB34_Freq (0x8A)
+#define MT6360_PMU_RGB1_Tr (0x8B)
+#define MT6360_PMU_RGB1_Tf (0x8C)
+#define MT6360_PMU_RGB1_TON_TOFF (0x8D)
+#define MT6360_PMU_RGB2_Tr (0x8E)
+#define MT6360_PMU_RGB2_Tf (0x8F)
+#define MT6360_PMU_RGB2_TON_TOFF (0x90)
+#define MT6360_PMU_RGB3_Tr (0x91)
+#define MT6360_PMU_RGB3_Tf (0x92)
+#define MT6360_PMU_RGB3_TON_TOFF (0x93)
+#define MT6360_PMU_RGB_Hidden_CTRL1 (0x94)
+#define MT6360_PMU_RGB_Hidden_CTRL2 (0x95)
+#define MT6360_PMU_RESV6 (0x97)
+#define MT6360_PMU_SPARE1 (0x9A)
+#define MT6360_PMU_SPARE2 (0xA0)
+#define MT6360_PMU_SPARE3 (0xB0)
+#define MT6360_PMU_SPARE4 (0xC0)
+#define MT6360_PMU_CHG_IRQ1 (0xD0)
+#define MT6360_PMU_CHG_IRQ2 (0xD1)
+#define MT6360_PMU_CHG_IRQ3 (0xD2)
+#define MT6360_PMU_CHG_IRQ4 (0xD3)
+#define MT6360_PMU_CHG_IRQ5 (0xD4)
+#define MT6360_PMU_CHG_IRQ6 (0xD5)
+#define MT6360_PMU_QC_IRQ (0xD6)
+#define MT6360_PMU_FOD_IRQ (0xD7)
+#define MT6360_PMU_BASE_IRQ (0xD8)
+#define MT6360_PMU_FLED_IRQ1 (0xD9)
+#define MT6360_PMU_FLED_IRQ2 (0xDA)
+#define MT6360_PMU_RGB_IRQ (0xDB)
+#define MT6360_PMU_BUCK1_IRQ (0xDC)
+#define MT6360_PMU_BUCK2_IRQ (0xDD)
+#define MT6360_PMU_LDO_IRQ1 (0xDE)
+#define MT6360_PMU_LDO_IRQ2 (0xDF)
+#define MT6360_PMU_CHG_STAT1 (0xE0)
+#define MT6360_PMU_CHG_STAT2 (0xE1)
+#define MT6360_PMU_CHG_STAT3 (0xE2)
+#define MT6360_PMU_CHG_STAT4 (0xE3)
+#define MT6360_PMU_CHG_STAT5 (0xE4)
+#define MT6360_PMU_CHG_STAT6 (0xE5)
+#define MT6360_PMU_QC_STAT (0xE6)
+#define MT6360_PMU_FOD_STAT (0xE7)
+#define MT6360_PMU_BASE_STAT (0xE8)
+#define MT6360_PMU_FLED_STAT1 (0xE9)
+#define MT6360_PMU_FLED_STAT2 (0xEA)
+#define MT6360_PMU_RGB_STAT (0xEB)
+#define MT6360_PMU_BUCK1_STAT (0xEC)
+#define MT6360_PMU_BUCK2_STAT (0xED)
+#define MT6360_PMU_LDO_STAT1 (0xEE)
+#define MT6360_PMU_LDO_STAT2 (0xEF)
+#define MT6360_PMU_CHG_MASK1 (0xF0)
+#define MT6360_PMU_CHG_MASK2 (0xF1)
+#define MT6360_PMU_CHG_MASK3 (0xF2)
+#define MT6360_PMU_CHG_MASK4 (0xF3)
+#define MT6360_PMU_CHG_MASK5 (0xF4)
+#define MT6360_PMU_CHG_MASK6 (0xF5)
+#define MT6360_PMU_QC_MASK (0xF6)
+#define MT6360_PMU_FOD_MASK (0xF7)
+#define MT6360_PMU_BASE_MASK (0xF8)
+#define MT6360_PMU_FLED_MASK1 (0xF9)
+#define MT6360_PMU_FLED_MASK2 (0xFA)
+#define MT6360_PMU_FAULTB_MASK (0xFB)
+#define MT6360_PMU_BUCK1_MASK (0xFC)
+#define MT6360_PMU_BUCK2_MASK (0xFD)
+#define MT6360_PMU_LDO_MASK1 (0xFE)
+#define MT6360_PMU_LDO_MASK2 (0xFF)
+#define MT6360_PMU_MAXREG (MT6360_PMU_LDO_MASK2)
+
+/* MT6360_PMU_IRQ_SET */
+#define MT6360_PMU_IRQ_REGNUM (MT6360_PMU_LDO_IRQ2 - MT6360_PMU_CHG_IRQ1 + 1)
+#define MT6360_IRQ_RETRIG BIT(2)
+
+#define CHIP_VEN_MASK (0xF0)
+#define CHIP_VEN_MT6360 (0x50)
+#define CHIP_REV_MASK (0x0F)
+
+#endif /* __MT6360_H__ */
--
2.7.4
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code
From: Jerry Snitselaar @ 2020-06-02 0:02 UTC (permalink / raw)
To: Lu Baolu
Cc: Heiko Stuebner, virtualization, linux-tegra, Thierry Reding,
Will Deacon, Marek Szyprowski, Jean-Philippe Brucker,
linux-samsung-soc, Joerg Roedel, iommu, Krzysztof Kozlowski,
Jonathan Hunter, linux-rockchip, Andy Gross, linux-s390,
linux-arm-msm, linux-mediatek, Matthias Brugger, Bjorn Andersson,
Gerald Schaefer, David Woodhouse, linux-kernel, Rob Clark,
Kukjin Kim, Robin Murphy
In-Reply-To: <47711845-98ee-95b8-aa95-423a36ed9741@linux.intel.com>
On Tue Jun 02 20, Lu Baolu wrote:
>Hi Jerry,
>
>On 6/1/20 6:42 PM, Jerry Snitselaar wrote:
>>>
>>>Hi Joerg,
>>>
>>>With this patchset, I have an epyc system where if I boot with
>>>iommu=nopt and force a dump I will see some io page faults for a nic
>>>on the system. The vmcore is harvested and the system reboots. I
>>>haven't reproduced it on other systems yet, but without the patchset I
>>>don't see the io page faults during the kdump.
>>>
>>>Regards,
>>>Jerry
>>
>>I just hit an issue on a separate intel based system (kdump iommu=nopt),
>>where it panics in during intel_iommu_attach_device, in is_aux_domain,
>>due to device_domain_info being DEFER_DEVICE_DOMAIN_INFO. That doesn't
>>get set to a valid address until the domain_add_dev_info call.
>>
>>Is it as simple as the following?
>
>I guess you won't hit this issue if you use iommu/next branch of Joerg's
>tree. We've changed to use a generic helper to retrieve the valid per
>device iommu data or NULL (if there's no).
>
>Best regards,
>baolu
>
Yeah, that will solve the panic.
>>
>>diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
>>index 29d3940847d3..f1bbeed46a4c 100644
>>--- a/drivers/iommu/intel-iommu.c
>>+++ b/drivers/iommu/intel-iommu.c
>>@@ -5053,8 +5053,8 @@ is_aux_domain(struct device *dev, struct
>>iommu_domain *domain)
>> {
>> struct device_domain_info *info = dev->archdata.iommu;
>>
>>- return info && info->auxd_enabled &&
>>- domain->type == IOMMU_DOMAIN_UNMANAGED;
>>+ return info && info != DEFER_DEVICE_DOMAIN_INFO &&
>>+ info->auxd_enabled && domain->type ==
>>IOMMU_DOMAIN_UNMANAGED;
>> }
>>
>> static void auxiliary_link_device(struct dmar_domain *domain,
>>
>>
>>Regards,
>>Jerry
>_______________________________________________
>iommu mailing list
>iommu@lists.linux-foundation.org
>https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code
From: Lu Baolu @ 2020-06-01 23:20 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Robin Murphy, Marek Szyprowski,
Kukjin Kim, Krzysztof Kozlowski, David Woodhouse, Andy Gross,
Bjorn Andersson, Matthias Brugger, Rob Clark, Heiko Stuebner,
Gerald Schaefer, Thierry Reding, Jonathan Hunter,
Jean-Philippe Brucker, linux-s390, linux-samsung-soc,
linux-arm-msm, linux-kernel, virtualization, linux-rockchip,
iommu, linux-mediatek, linux-tegra
Cc: baolu.lu
In-Reply-To: <20200601131702.4ksimsjvnsmo3mvn@cantor>
Hi Jerry,
On 6/1/20 9:17 PM, Jerry Snitselaar wrote:
> On Mon Jun 01 20, Jerry Snitselaar wrote:
>> On Fri May 29 20, Jerry Snitselaar wrote:
>>> On Tue Apr 14 20, Joerg Roedel wrote:
>>>> Hi,
>>>>
>>>> here is the second version of this patch-set. The first version with
>>>> some more introductory text can be found here:
>>>>
>>>> https://lore.kernel.org/lkml/20200407183742.4344-1-joro@8bytes.org/
>>>>
>>>> Changes v1->v2:
>>>>
>>>> * Rebased to v5.7-rc1
>>>>
>>>> * Re-wrote the arm-smmu changes as suggested by Robin Murphy
>>>>
>>>> * Re-worked the Exynos patches to hopefully not break the
>>>> driver anymore
>>>>
>>>> * Fixed a missing mutex_unlock() reported by Marek Szyprowski,
>>>> thanks for that.
>>>>
>>>> There is also a git-branch available with these patches applied:
>>>>
>>>> https://git.kernel.org/pub/scm/linux/kernel/git/joro/linux.git/log/?h=iommu-probe-device-v2
>>>>
>>>>
>>>> Please review.
>>>>
>>>> Thanks,
>>>>
>>>> Joerg
>>>>
>>>> Joerg Roedel (32):
>>>> iommu: Move default domain allocation to separate function
>>>> iommu/amd: Implement iommu_ops->def_domain_type call-back
>>>> iommu/vt-d: Wire up iommu_ops->def_domain_type
>>>> iommu/amd: Remove dma_mask check from check_device()
>>>> iommu/amd: Return -ENODEV in add_device when device is not handled by
>>>> IOMMU
>>>> iommu: Add probe_device() and remove_device() call-backs
>>>> iommu: Move default domain allocation to iommu_probe_device()
>>>> iommu: Keep a list of allocated groups in __iommu_probe_device()
>>>> iommu: Move new probe_device path to separate function
>>>> iommu: Split off default domain allocation from group assignment
>>>> iommu: Move iommu_group_create_direct_mappings() out of
>>>> iommu_group_add_device()
>>>> iommu: Export bus_iommu_probe() and make is safe for re-probing
>>>> iommu/amd: Remove dev_data->passthrough
>>>> iommu/amd: Convert to probe/release_device() call-backs
>>>> iommu/vt-d: Convert to probe/release_device() call-backs
>>>> iommu/arm-smmu: Convert to probe/release_device() call-backs
>>>> iommu/pamu: Convert to probe/release_device() call-backs
>>>> iommu/s390: Convert to probe/release_device() call-backs
>>>> iommu/virtio: Convert to probe/release_device() call-backs
>>>> iommu/msm: Convert to probe/release_device() call-backs
>>>> iommu/mediatek: Convert to probe/release_device() call-backs
>>>> iommu/mediatek-v1 Convert to probe/release_device() call-backs
>>>> iommu/qcom: Convert to probe/release_device() call-backs
>>>> iommu/rockchip: Convert to probe/release_device() call-backs
>>>> iommu/tegra: Convert to probe/release_device() call-backs
>>>> iommu/renesas: Convert to probe/release_device() call-backs
>>>> iommu/omap: Remove orphan_dev tracking
>>>> iommu/omap: Convert to probe/release_device() call-backs
>>>> iommu/exynos: Use first SYSMMU in controllers list for IOMMU core
>>>> iommu/exynos: Convert to probe/release_device() call-backs
>>>> iommu: Remove add_device()/remove_device() code-paths
>>>> iommu: Unexport iommu_group_get_for_dev()
>>>>
>>>> Sai Praneeth Prakhya (1):
>>>> iommu: Add def_domain_type() callback in iommu_ops
>>>>
>>>> drivers/iommu/amd_iommu.c | 97 ++++----
>>>> drivers/iommu/amd_iommu_types.h | 1 -
>>>> drivers/iommu/arm-smmu-v3.c | 38 +--
>>>> drivers/iommu/arm-smmu.c | 39 ++--
>>>> drivers/iommu/exynos-iommu.c | 24 +-
>>>> drivers/iommu/fsl_pamu_domain.c | 22 +-
>>>> drivers/iommu/intel-iommu.c | 68 +-----
>>>> drivers/iommu/iommu.c | 393 +++++++++++++++++++++++++-------
>>>> drivers/iommu/ipmmu-vmsa.c | 60 ++---
>>>> drivers/iommu/msm_iommu.c | 34 +--
>>>> drivers/iommu/mtk_iommu.c | 24 +-
>>>> drivers/iommu/mtk_iommu_v1.c | 50 ++--
>>>> drivers/iommu/omap-iommu.c | 99 ++------
>>>> drivers/iommu/qcom_iommu.c | 24 +-
>>>> drivers/iommu/rockchip-iommu.c | 26 +--
>>>> drivers/iommu/s390-iommu.c | 22 +-
>>>> drivers/iommu/tegra-gart.c | 24 +-
>>>> drivers/iommu/tegra-smmu.c | 31 +--
>>>> drivers/iommu/virtio-iommu.c | 41 +---
>>>> include/linux/iommu.h | 21 +-
>>>> 20 files changed, 533 insertions(+), 605 deletions(-)
>>>>
>>>> --
>>>> 2.17.1
>>>>
>>>> _______________________________________________
>>>> iommu mailing list
>>>> iommu@lists.linux-foundation.org
>>>> https://lists.linuxfoundation.org/mailman/listinfo/iommu
>>>>
>>>
>>> Hi Joerg,
>>>
>>> With this patchset, I have an epyc system where if I boot with
>>> iommu=nopt and force a dump I will see some io page faults for a nic
>>> on the system. The vmcore is harvested and the system reboots. I
>>> haven't reproduced it on other systems yet, but without the patchset I
>>> don't see the io page faults during the kdump.
>>>
>>> Regards,
>>> Jerry
>>
>> I just hit an issue on a separate intel based system (kdump iommu=nopt),
>> where it panics in during intel_iommu_attach_device, in is_aux_domain,
>> due to device_domain_info being DEFER_DEVICE_DOMAIN_INFO. That doesn't
>> get set to a valid address until the domain_add_dev_info call.
>>
>> Is it as simple as the following?
>>
>> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
>> index 29d3940847d3..f1bbeed46a4c 100644
>> --- a/drivers/iommu/intel-iommu.c
>> +++ b/drivers/iommu/intel-iommu.c
>> @@ -5053,8 +5053,8 @@ is_aux_domain(struct device *dev, struct
>> iommu_domain *domain)
>> {
>> struct device_domain_info *info = dev->archdata.iommu;
>> - return info && info->auxd_enabled &&
>> - domain->type == IOMMU_DOMAIN_UNMANAGED;
>> + return info && info != DEFER_DEVICE_DOMAIN_INFO &&
>> + info->auxd_enabled && domain->type ==
>> IOMMU_DOMAIN_UNMANAGED;
>> }
>> static void auxiliary_link_device(struct dmar_domain *domain,
>>
>>
>> Regards,
>> Jerry
>>
>
> With the patch, I avoid the panic, but I'm seeing an issue similar to
> the epyc system.
> I'm getting dmar faults from a couple of nics and the hp ilo. The
> addresses in question
> were in e820 reserved sections, but there aren't rmrr covering those
> addresses. The system
> manages to harvest the vmcore and reboot like the epyc. Without the
> patches I don't see
> the dmar faults. I needed to give this system back, but I'll try to poke
> at it some more
> in the next couple of days.
Thanks and looking forward to further debugging information.
Best regards,
baolu
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code
From: Lu Baolu @ 2020-06-01 23:16 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Robin Murphy, Marek Szyprowski,
Kukjin Kim, Krzysztof Kozlowski, David Woodhouse, Andy Gross,
Bjorn Andersson, Matthias Brugger, Rob Clark, Heiko Stuebner,
Gerald Schaefer, Thierry Reding, Jonathan Hunter,
Jean-Philippe Brucker, linux-s390, linux-samsung-soc,
linux-arm-msm, linux-kernel, virtualization, linux-rockchip,
iommu, linux-mediatek, linux-tegra
Cc: baolu.lu
In-Reply-To: <20200601104240.7f5xhz7gooqhaq4n@cantor>
Hi Jerry,
On 6/1/20 6:42 PM, Jerry Snitselaar wrote:
>>
>> Hi Joerg,
>>
>> With this patchset, I have an epyc system where if I boot with
>> iommu=nopt and force a dump I will see some io page faults for a nic
>> on the system. The vmcore is harvested and the system reboots. I
>> haven't reproduced it on other systems yet, but without the patchset I
>> don't see the io page faults during the kdump.
>>
>> Regards,
>> Jerry
>
> I just hit an issue on a separate intel based system (kdump iommu=nopt),
> where it panics in during intel_iommu_attach_device, in is_aux_domain,
> due to device_domain_info being DEFER_DEVICE_DOMAIN_INFO. That doesn't
> get set to a valid address until the domain_add_dev_info call.
>
> Is it as simple as the following?
I guess you won't hit this issue if you use iommu/next branch of Joerg's
tree. We've changed to use a generic helper to retrieve the valid per
device iommu data or NULL (if there's no).
Best regards,
baolu
>
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 29d3940847d3..f1bbeed46a4c 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -5053,8 +5053,8 @@ is_aux_domain(struct device *dev, struct
> iommu_domain *domain)
> {
> struct device_domain_info *info = dev->archdata.iommu;
>
> - return info && info->auxd_enabled &&
> - domain->type == IOMMU_DOMAIN_UNMANAGED;
> + return info && info != DEFER_DEVICE_DOMAIN_INFO &&
> + info->auxd_enabled && domain->type ==
> IOMMU_DOMAIN_UNMANAGED;
> }
>
> static void auxiliary_link_device(struct dmar_domain *domain,
>
>
> Regards,
> Jerry
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v8 4/8] PM / EM: add support for other devices than CPUs in Energy Model
From: Daniel Lezcano @ 2020-06-01 21:44 UTC (permalink / raw)
To: Lukasz Luba, linux-kernel, linux-pm, linux-arm-kernel, dri-devel,
linux-omap, linux-mediatek, linux-arm-msm, linux-imx
Cc: nm, juri.lelli, peterz, viresh.kumar, liviu.dudau,
bjorn.andersson, bsegall, festevam, mka, robh, amit.kucheria,
lorenzo.pieralisi, vincent.guittot, khilman, steven.price,
cw00.choi, mingo, mgorman, rui.zhang, alyssa.rosenzweig,
orjan.eide, daniel, b.zolnierkie, s.hauer, rostedt, matthias.bgg,
Dietmar.Eggemann, airlied, tomeu.vizoso, qperret, sboyd, rdunlap,
rjw, agross, kernel, sudeep.holla, patrick.bellasi, shawnguo
In-Reply-To: <20200527095854.21714-5-lukasz.luba@arm.com>
On 27/05/2020 11:58, Lukasz Luba wrote:
> Add support for other devices than CPUs. The registration function
> does not require a valid cpumask pointer and is ready to handle new
> devices. Some of the internal structures has been reorganized in order to
> keep consistent view (like removing per_cpu pd pointers).
>
> Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
> ---
[ ... ]
> }
> EXPORT_SYMBOL_GPL(em_register_perf_domain);
> +
> +/**
> + * em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device
> + * @dev : Device for which the EM is registered
> + *
> + * Try to unregister the EM for the specified device (but not a CPU).
> + */
> +void em_dev_unregister_perf_domain(struct device *dev)
> +{
> + if (IS_ERR_OR_NULL(dev) || !dev->em_pd)
> + return;
> +
> + if (_is_cpu_device(dev))
> + return;
> +
> + mutex_lock(&em_pd_mutex);
Is the mutex really needed?
If this function is called that means there is no more user of the
em_pd, no?
> + em_debug_remove_pd(dev);
> +
> + kfree(dev->em_pd->table);
> + kfree(dev->em_pd);
> + dev->em_pd = NULL;
> + mutex_unlock(&em_pd_mutex);
> +}
> +EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [V6, 2/2] media: i2c: dw9768: Add DW9768 VCM driver
From: Tomasz Figa @ 2020-06-01 18:47 UTC (permalink / raw)
To: Dongchun Zhu
Cc: Mark Rutland, Nicolas Boichat, Andy Shevchenko, srv_heupstream,
linux-devicetree, Linus Walleij,
Shengnan Wang (王圣男), Louis Kuo,
Bartosz Golaszewski, Sj Huang, Rob Herring,
moderated list:ARM/Mediatek SoC support, Sakari Ailus,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Linux Media Mailing List
In-Reply-To: <1590570089.8804.453.camel@mhfsdcap03>
On Wed, May 27, 2020 at 11:03 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
>
> Hi Tomasz,
>
> On Mon, 2020-05-25 at 13:45 +0200, Tomasz Figa wrote:
> > On Fri, May 22, 2020 at 11:27 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> > >
> > > Hi Tomasz,
> > >
> > > Thanks for the review. My replies are as below.
> > >
> > > On Thu, 2020-05-21 at 19:51 +0000, Tomasz Figa wrote:
> > > > Hi Dongchun, Sakari,
> > > >
> > > > On Mon, May 18, 2020 at 09:27:31PM +0800, Dongchun Zhu wrote:
> > [snip]
> > > > > + pm_runtime_enable(dev);
> > > > > + if (!pm_runtime_enabled(dev)) {
> > > > > + ret = dw9768_runtime_resume(dev);
> > > > > + if (ret < 0) {
> > > > > + dev_err(dev, "failed to power on: %d\n", ret);
> > > > > + goto entity_cleanup;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + ret = v4l2_async_register_subdev(&dw9768->sd);
> > > > > + if (ret < 0)
> > > > > + goto entity_cleanup;
> > > > > +
> > > > > + return 0;
> > > > > +
> > > > > +entity_cleanup:
> > > >
> > > > Need to power off if the code above powered on.
> > > >
> > >
> > > Thanks for the reminder.
> > > If there is something wrong with runtime PM, actuator is to be powered
> > > on via dw9768_runtime_resume() API.
> > > When actuator sub-device is powered on completely and async registered
> > > successfully, we shall power off it afterwards.
> > >
> >
> > The code above calls dw9768_runtime_resume() if
> > !pm_runtime_enabled(dev), but the clean-up code below the
> > entity_cleanup label doesn't have the corresponding
> > dw9768_runtime_suspend() call.
> >
>
> Did you mean the 'entity_cleanup' after v4l2_async_register_subdev()?
Yes.
> Actually I made some changes for OV02A V9, according to this comment.
> Could you help review that change? Thanks.
Sure, I will take a look.
Best regards,
Tomasz
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v3 0/2] regmap: provide simple bitops and use them in a driver
From: Mark Brown @ 2020-06-01 18:46 UTC (permalink / raw)
To: David Miller
Cc: stephane.leprovost, bgolaszewski, netdev, brgl, sean.wang,
linux-kernel, fparent, pedro.tsai, linux-mediatek,
andrew.perepech, john, matthias.bgg, kuba, Mark-MC.Lee,
linux-arm-kernel
In-Reply-To: <20200601.113536.134620919829517847.davem@davemloft.net>
[-- Attachment #1.1: Type: text/plain, Size: 496 bytes --]
On Mon, Jun 01, 2020 at 11:35:36AM -0700, David Miller wrote:
> > v2 -> v3:
> > - drop unneeded ternary operator
> Series applied to net-next, thank you.
I already applied patch 1 and sent a pull request to Linus for it. As I
said:
| Let me know if you need a pull request for this, given the merge window
| is likely to open over the weekend I figured it's likely too late to
| apply the second patch before then.
Hopefully this merges cleanly... ideally we'd have had that pull
request.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 170 bytes --]
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v3 0/2] regmap: provide simple bitops and use them in a driver
From: David Miller @ 2020-06-01 18:35 UTC (permalink / raw)
To: brgl
Cc: stephane.leprovost, bgolaszewski, netdev, sean.wang, linux-kernel,
pedro.tsai, fparent, broonie, linux-mediatek, andrew.perepech,
john, matthias.bgg, kuba, Mark-MC.Lee, linux-arm-kernel
In-Reply-To: <20200528154503.26304-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <brgl@bgdev.pl>
Date: Thu, 28 May 2020 17:45:01 +0200
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> I noticed that oftentimes I use regmap_update_bits() for simple bit
> setting or clearing. In this case the fourth argument is superfluous as
> it's always 0 or equal to the mask argument.
>
> This series proposes to add simple bit operations for setting, clearing
> and testing specific bits with regmap.
>
> The second patch uses all three in a driver that got recently picked into
> the net-next tree.
>
> The patches obviously target different trees so - if you're ok with
> the change itself - I propose you pick the first one into your regmap
> tree for v5.8 and then I'll resend the second patch to add the first
> user for these macros for v5.9.
>
> v1 -> v2:
> - convert the new macros to static inline functions
>
> v2 -> v3:
> - drop unneeded ternary operator
Series applied to net-next, thank you.
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Tomasz Figa @ 2020-06-01 18:18 UTC (permalink / raw)
To: Dongchun Zhu
Cc: Mark Rutland, Rob Herring, Andy Shevchenko, srv_heupstream,
linux-devicetree, Linus Walleij,
Shengnan Wang (王圣男), Louis Kuo,
Bartosz Golaszewski, Sj Huang, Nicolas Boichat,
moderated list:ARM/Mediatek SoC support, Sakari Ailus,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linux Media Mailing List
In-Reply-To: <1590978816.8804.523.camel@mhfsdcap03>
On Mon, Jun 1, 2020 at 4:35 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
>
> Hi Tomasz,
>
> On Fri, 2020-05-29 at 15:43 +0200, Tomasz Figa wrote:
> > On Thu, May 28, 2020 at 10:06 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> > >
> > > Hi Sakari,
> > >
> > > On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> > > > Hi Dongchun,
> > > >
> > > > On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > > > > Hi Sakari, Rob,
> > > > >
> > > > > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > > > > Hi Rob, Dongchun,
> > > > > >
> > > > > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > > > > + properties:
> > > > > > > > > > + endpoint:
> > > > > > > > > > + type: object
> > > > > > > > > > + additionalProperties: false
> > > > > > > > > > +
> > > > > > > > > > + properties:
> > > > > > > >
> > > > > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > > > >
> > > > > > > Yes, if you are using it.
> > > > > >
> > > > > > Dongchun, can you confirm the chip has a single data and a single clock
> > > > > > lane and that it does not support lane reordering?
> > > > > >
> > > > >
> > > > > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > > > > uni-directional clock lane and one bi-directional data lane solution for
> > > > > communication links between components inside a mobile device.
> > > > > The data lane has full support for HS(uni-directional) and
> > > > > LP(bi-directional) data transfer mode.'
> > > > >
> > > > > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > > > > would not be added in next release.
> > > > >
> > > > > > So if there's nothing to convey to the driver, also the data-lanes should
> > > > > > be removed IMO.
> > > > > >
> > > > >
> > > > > However, 'data-lanes' property may still be required.
> > > > > It is known that either data-lanes or clock-lanes is an array of
> > > > > physical data lane indexes. Position of an entry determines the logical
> > > > > lane number, while the value of an entry indicates physical lane, e.g.,
> > > > > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > > > > the clock lane is on hardware lane 0.
> > > > >
> > > > > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > > > > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > > > > there is only a clock lane for OV02A10.
> > > > >
> > > > > Reminder:
> > > > > If 'data-lanes' property is not present, the driver would assume
> > > > > four-lane operation. This means for one-lane or two-lane operation, this
> > > > > property must be present and set to the right physical lane indexes.
> > > > > If the hardware does not support lane reordering, monotonically
> > > > > incremented values shall be used from 0 or 1 onwards, depending on
> > > > > whether or not there is also a clock lane.
> > > >
> > > > How can the driver use four lanes, considering the device only supports a
> > > > single lane??
> > > >
> > >
> > > I understood your meaning.
> > > If we omit the property 'data-lanes', the sensor should work still.
> > > But then what's the meaning of the existence of 'data-lanes'?
> > > If this property 'data-lanes' is always optional, then why dt-bindings
> > > provide the interface?
> > >
> > > In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
> > > that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
> > > shall enable four-lane configuration, which may increase consumption of
> > > both power and resource in the process of IIC communication.
> >
> > Wouldn't the receiver still have the data-lanes property under its
> > endpoint node, telling it how many lanes and in which order should be
> > used?
> >
>
> The MIPI receiver(RX) shall use
> v4l2_async_notifier_add_fwnode_remote_subdev() API to parse the property
> "data-lanes" under sensor output port.
That's not true. The MIPI receiver driver parses its own port node
corresponding to the sensor. Also quoting the documentation [1]:
"An endpoint subnode of a device contains all properties needed for
_configuration of this device_ for data exchange with other device. In most
cases properties at the peer 'endpoint' nodes will be identical, however they
might need to be different when there is any signal modifications on the bus
between two devices, e.g. there are logic signal inverters on the lines."
In this case, there is such a signal modification if the sensor has a
1-lane bus and the receiver more lines, so the data-lanes properties
would be different on both sides.
[1] https://elixir.bootlin.com/linux/v5.7/source/Documentation/devicetree/bindings/media/video-interfaces.txt
Best regards,
Tomasz
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code
From: Jerry Snitselaar @ 2020-06-01 13:17 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Robin Murphy, Marek Szyprowski,
Kukjin Kim, Krzysztof Kozlowski, David Woodhouse, Lu Baolu,
Andy Gross, Bjorn Andersson, Matthias Brugger, Rob Clark,
Heiko Stuebner, Gerald Schaefer, Thierry Reding, Jonathan Hunter,
Jean-Philippe Brucker, linux-s390, linux-samsung-soc,
linux-arm-msm, linux-kernel, virtualization, linux-rockchip,
iommu, linux-mediatek, linux-tegra
In-Reply-To: <20200601104240.7f5xhz7gooqhaq4n@cantor>
On Mon Jun 01 20, Jerry Snitselaar wrote:
>On Fri May 29 20, Jerry Snitselaar wrote:
>>On Tue Apr 14 20, Joerg Roedel wrote:
>>>Hi,
>>>
>>>here is the second version of this patch-set. The first version with
>>>some more introductory text can be found here:
>>>
>>> https://lore.kernel.org/lkml/20200407183742.4344-1-joro@8bytes.org/
>>>
>>>Changes v1->v2:
>>>
>>> * Rebased to v5.7-rc1
>>>
>>> * Re-wrote the arm-smmu changes as suggested by Robin Murphy
>>>
>>> * Re-worked the Exynos patches to hopefully not break the
>>> driver anymore
>>>
>>> * Fixed a missing mutex_unlock() reported by Marek Szyprowski,
>>> thanks for that.
>>>
>>>There is also a git-branch available with these patches applied:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/joro/linux.git/log/?h=iommu-probe-device-v2
>>>
>>>Please review.
>>>
>>>Thanks,
>>>
>>> Joerg
>>>
>>>Joerg Roedel (32):
>>>iommu: Move default domain allocation to separate function
>>>iommu/amd: Implement iommu_ops->def_domain_type call-back
>>>iommu/vt-d: Wire up iommu_ops->def_domain_type
>>>iommu/amd: Remove dma_mask check from check_device()
>>>iommu/amd: Return -ENODEV in add_device when device is not handled by
>>> IOMMU
>>>iommu: Add probe_device() and remove_device() call-backs
>>>iommu: Move default domain allocation to iommu_probe_device()
>>>iommu: Keep a list of allocated groups in __iommu_probe_device()
>>>iommu: Move new probe_device path to separate function
>>>iommu: Split off default domain allocation from group assignment
>>>iommu: Move iommu_group_create_direct_mappings() out of
>>> iommu_group_add_device()
>>>iommu: Export bus_iommu_probe() and make is safe for re-probing
>>>iommu/amd: Remove dev_data->passthrough
>>>iommu/amd: Convert to probe/release_device() call-backs
>>>iommu/vt-d: Convert to probe/release_device() call-backs
>>>iommu/arm-smmu: Convert to probe/release_device() call-backs
>>>iommu/pamu: Convert to probe/release_device() call-backs
>>>iommu/s390: Convert to probe/release_device() call-backs
>>>iommu/virtio: Convert to probe/release_device() call-backs
>>>iommu/msm: Convert to probe/release_device() call-backs
>>>iommu/mediatek: Convert to probe/release_device() call-backs
>>>iommu/mediatek-v1 Convert to probe/release_device() call-backs
>>>iommu/qcom: Convert to probe/release_device() call-backs
>>>iommu/rockchip: Convert to probe/release_device() call-backs
>>>iommu/tegra: Convert to probe/release_device() call-backs
>>>iommu/renesas: Convert to probe/release_device() call-backs
>>>iommu/omap: Remove orphan_dev tracking
>>>iommu/omap: Convert to probe/release_device() call-backs
>>>iommu/exynos: Use first SYSMMU in controllers list for IOMMU core
>>>iommu/exynos: Convert to probe/release_device() call-backs
>>>iommu: Remove add_device()/remove_device() code-paths
>>>iommu: Unexport iommu_group_get_for_dev()
>>>
>>>Sai Praneeth Prakhya (1):
>>>iommu: Add def_domain_type() callback in iommu_ops
>>>
>>>drivers/iommu/amd_iommu.c | 97 ++++----
>>>drivers/iommu/amd_iommu_types.h | 1 -
>>>drivers/iommu/arm-smmu-v3.c | 38 +--
>>>drivers/iommu/arm-smmu.c | 39 ++--
>>>drivers/iommu/exynos-iommu.c | 24 +-
>>>drivers/iommu/fsl_pamu_domain.c | 22 +-
>>>drivers/iommu/intel-iommu.c | 68 +-----
>>>drivers/iommu/iommu.c | 393 +++++++++++++++++++++++++-------
>>>drivers/iommu/ipmmu-vmsa.c | 60 ++---
>>>drivers/iommu/msm_iommu.c | 34 +--
>>>drivers/iommu/mtk_iommu.c | 24 +-
>>>drivers/iommu/mtk_iommu_v1.c | 50 ++--
>>>drivers/iommu/omap-iommu.c | 99 ++------
>>>drivers/iommu/qcom_iommu.c | 24 +-
>>>drivers/iommu/rockchip-iommu.c | 26 +--
>>>drivers/iommu/s390-iommu.c | 22 +-
>>>drivers/iommu/tegra-gart.c | 24 +-
>>>drivers/iommu/tegra-smmu.c | 31 +--
>>>drivers/iommu/virtio-iommu.c | 41 +---
>>>include/linux/iommu.h | 21 +-
>>>20 files changed, 533 insertions(+), 605 deletions(-)
>>>
>>>--
>>>2.17.1
>>>
>>>_______________________________________________
>>>iommu mailing list
>>>iommu@lists.linux-foundation.org
>>>https://lists.linuxfoundation.org/mailman/listinfo/iommu
>>>
>>
>>Hi Joerg,
>>
>>With this patchset, I have an epyc system where if I boot with
>>iommu=nopt and force a dump I will see some io page faults for a nic
>>on the system. The vmcore is harvested and the system reboots. I
>>haven't reproduced it on other systems yet, but without the patchset I
>>don't see the io page faults during the kdump.
>>
>>Regards,
>>Jerry
>
>I just hit an issue on a separate intel based system (kdump iommu=nopt),
>where it panics in during intel_iommu_attach_device, in is_aux_domain,
>due to device_domain_info being DEFER_DEVICE_DOMAIN_INFO. That doesn't
>get set to a valid address until the domain_add_dev_info call.
>
>Is it as simple as the following?
>
>diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
>index 29d3940847d3..f1bbeed46a4c 100644
>--- a/drivers/iommu/intel-iommu.c
>+++ b/drivers/iommu/intel-iommu.c
>@@ -5053,8 +5053,8 @@ is_aux_domain(struct device *dev, struct iommu_domain *domain)
> {
> struct device_domain_info *info = dev->archdata.iommu;
>- return info && info->auxd_enabled &&
>- domain->type == IOMMU_DOMAIN_UNMANAGED;
>+ return info && info != DEFER_DEVICE_DOMAIN_INFO &&
>+ info->auxd_enabled && domain->type == IOMMU_DOMAIN_UNMANAGED;
> }
> static void auxiliary_link_device(struct dmar_domain *domain,
>
>
>Regards,
>Jerry
>
With the patch, I avoid the panic, but I'm seeing an issue similar to the epyc system.
I'm getting dmar faults from a couple of nics and the hp ilo. The addresses in question
were in e820 reserved sections, but there aren't rmrr covering those addresses. The system
manages to harvest the vmcore and reboot like the epyc. Without the patches I don't see
the dmar faults. I needed to give this system back, but I'll try to poke at it some more
in the next couple of days.
Regards,
Jerry
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v3 2/5] scsi: ufs-mediatek: Do not gate clocks if auto-hibern8 is not entered yet
From: Stanley Chu @ 2020-06-01 10:46 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
Cc: Stanley Chu, bvanassche, andy.teng, cc.chou, chun-hung.wu,
kuohong.wang, linux-kernel, cang, linux-mediatek, peter.wang,
matthias.bgg, beanhuo, chaotian.jing, linux-arm-kernel, asutoshd
In-Reply-To: <20200601104646.15436-1-stanley.chu@mediatek.com>
There are some chances that link enters hibern8 lately by auto-hibern8
scheme during the clock-gating flow. Clocks shall not be gated if link
is still active otherwise host or device may hang.
Fix this by returning error code to the caller __ufshcd_setup_clocks()
to skip gating clocks there if link is not confirmed in hibern8
state yet.
Also allow some waiting time for the hibern8 state transition.
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Andy Teng <andy.teng@mediatek.com>
---
drivers/scsi/ufs/ufs-mediatek.c | 36 ++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 523ee5573921..3c85f5e97dea 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -178,15 +178,30 @@ static void ufs_mtk_setup_ref_clk_wait_us(struct ufs_hba *hba,
host->ref_clk_ungating_wait_us = ungating_us;
}
-static u32 ufs_mtk_link_get_state(struct ufs_hba *hba)
+int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
+ unsigned long max_wait_ms)
{
+ ktime_t timeout, time_checked;
u32 val;
- ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL);
- val = ufshcd_readl(hba, REG_UFS_PROBE);
- val = val >> 28;
+ timeout = ktime_add_us(ktime_get(), ms_to_ktime(max_wait_ms));
+ do {
+ time_checked = ktime_get();
+ ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL);
+ val = ufshcd_readl(hba, REG_UFS_PROBE);
+ val = val >> 28;
+
+ if (val == state)
+ return 0;
- return val;
+ /* Sleep for max. 200us */
+ usleep_range(100, 200);
+ } while (ktime_before(time_checked, timeout));
+
+ if (val == state)
+ return 0;
+
+ return -ETIMEDOUT;
}
/**
@@ -221,10 +236,13 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
* triggered by Auto-Hibern8.
*/
if (!ufshcd_can_hibern8_during_gating(hba) &&
- ufshcd_is_auto_hibern8_enabled(hba) &&
- ufs_mtk_link_get_state(hba) ==
- VS_LINK_HIBERN8)
- ufs_mtk_setup_ref_clk(hba, on);
+ ufshcd_is_auto_hibern8_enabled(hba)) {
+ ret = ufs_mtk_wait_link_state(hba,
+ VS_LINK_HIBERN8,
+ 15);
+ if (!ret)
+ ufs_mtk_setup_ref_clk(hba, on);
+ }
}
} else if (on && status == POST_CHANGE) {
ret = phy_power_on(host->mphy);
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v3 4/5] scsi: ufs-mediatek: Fix unbalanced clock on/off
From: Stanley Chu @ 2020-06-01 10:46 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar, jejb
Cc: Stanley Chu, bvanassche, andy.teng, cc.chou, chun-hung.wu,
kuohong.wang, linux-kernel, cang, linux-mediatek, peter.wang,
matthias.bgg, beanhuo, chaotian.jing, linux-arm-kernel, asutoshd
In-Reply-To: <20200601104646.15436-1-stanley.chu@mediatek.com>
MediaTek UFS clocks are separated to two parts and controlled
by different modules: ufs-mediatek and phy-ufs-mediatek.
If both Auto-Hibern8 and clk-gating feature are enabled, mphy
power control is not balanced thus unbalanced control also
happens to the clocks probed by phy-ufs-mediatek module.
Fix this issue by
- Promise usage of phy_power_on/off balanced
- Remove phy_power_on/off control in suspend/resume vops since
both can be handled in setup_clock vops only
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
---
drivers/scsi/ufs/ufs-mediatek.c | 60 ++++++++++++++++++++-------------
drivers/scsi/ufs/ufs-mediatek.h | 1 +
2 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 5f41b7b7db8f..1cc7bea1468b 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -205,6 +205,23 @@ int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
return -ETIMEDOUT;
}
+static void ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+ struct phy *mphy = host->mphy;
+
+ if (!mphy)
+ return;
+
+ if (on && !host->mphy_powered_on)
+ phy_power_on(mphy);
+ else if (!on && host->mphy_powered_on)
+ phy_power_off(mphy);
+ else
+ return;
+ host->mphy_powered_on = on;
+}
+
/**
* ufs_mtk_setup_clocks - enables/disable clocks
* @hba: host controller instance
@@ -218,6 +235,7 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
int ret = 0;
+ bool clk_pwr_off = false;
/*
* In case ufs_mtk_init() is not yet done, simply ignore.
@@ -228,25 +246,29 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
return 0;
if (!on && status == PRE_CHANGE) {
- if (!ufshcd_is_link_active(hba)) {
- ufs_mtk_setup_ref_clk(hba, on);
- ret = phy_power_off(host->mphy);
- } else {
+ if (ufshcd_is_link_off(hba)) {
+ clk_pwr_off = true;
+ } else if (ufshcd_is_link_hibern8(hba) ||
+ (!ufshcd_can_hibern8_during_gating(hba) &&
+ ufshcd_is_auto_hibern8_enabled(hba))) {
/*
- * Gate ref-clk if link state is in Hibern8
- * triggered by Auto-Hibern8.
+ * Gate ref-clk and poweroff mphy if link state is in
+ * OFF or Hibern8 by either Auto-Hibern8 or
+ * ufshcd_link_state_transition().
*/
- if (!ufshcd_can_hibern8_during_gating(hba) &&
- ufshcd_is_auto_hibern8_enabled(hba)) {
- ret = ufs_mtk_wait_link_state(hba,
- VS_LINK_HIBERN8,
- 15);
- if (!ret)
- ufs_mtk_setup_ref_clk(hba, on);
- }
+ ret = ufs_mtk_wait_link_state(hba,
+ VS_LINK_HIBERN8,
+ 15);
+ if (!ret)
+ clk_pwr_off = true;
+ }
+
+ if (clk_pwr_off) {
+ ufs_mtk_setup_ref_clk(hba, on);
+ ufs_mtk_mphy_power_on(hba, on);
}
} else if (on && status == POST_CHANGE) {
- ret = phy_power_on(host->mphy);
+ ufs_mtk_mphy_power_on(hba, on);
ufs_mtk_setup_ref_clk(hba, on);
}
@@ -538,7 +560,6 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
int err;
- struct ufs_mtk_host *host = ufshcd_get_variant(hba);
if (ufshcd_is_link_hibern8(hba)) {
err = ufs_mtk_link_set_lpm(hba);
@@ -559,20 +580,13 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
ufs_mtk_vreg_set_lpm(hba, true);
}
- if (!ufshcd_is_link_active(hba))
- phy_power_off(host->mphy);
-
return 0;
}
static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
- struct ufs_mtk_host *host = ufshcd_get_variant(hba);
int err;
- if (!ufshcd_is_link_active(hba))
- phy_power_on(host->mphy);
-
if (ufshcd_is_link_hibern8(hba)) {
ufs_mtk_vreg_set_lpm(hba, false);
err = ufs_mtk_link_set_hpm(hba);
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index fc42dcbfd800..6052ec105aba 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -91,6 +91,7 @@ enum {
struct ufs_mtk_host {
struct ufs_hba *hba;
struct phy *mphy;
+ bool mphy_powered_on;
bool unipro_lpm;
bool ref_clk_enabled;
u16 ref_clk_ungating_wait_us;
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox