Re: [PATCH v1] cpufreq: tegra20: Fix imbalanced clock enable count

2018-05-22 Thread Viresh Kumar
On 23-05-18, 00:14, Dmitry Osipenko wrote:
> Tegra20-cpufreq driver missed enabling the CPU clocks. This results in a
> clock-enable refcount disbalance on PLL_P <-> PLL_X reparent, causing
> PLL_X to get disabled while it shouldn't. Fix this by enabling the clocks
> on the driver probe.
> 
> Signed-off-by: Dmitry Osipenko 
> ---
> 
> CPUFreq maintainers,
> 
> Please take into account that this patch is made on top of my recent
> series of patches [0] "Clean up Tegra20 cpufreq driver" that was fully
> reviewed, but seems not applied yet. Let me know if you prefer to re-spin
> the [0], including this patch into the series.
> 
> [0] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=45321

This is already picked by Rafael and is sitting in pm/bleeding-edge
branch. Should get merged into linux-next in a day or two.

>  drivers/cpufreq/tegra20-cpufreq.c | 16 +++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/tegra20-cpufreq.c 
> b/drivers/cpufreq/tegra20-cpufreq.c
> index 05f57dcd5215..ca5229265b60 100644
> --- a/drivers/cpufreq/tegra20-cpufreq.c
> +++ b/drivers/cpufreq/tegra20-cpufreq.c
> @@ -176,6 +176,14 @@ static int tegra20_cpufreq_probe(struct platform_device 
> *pdev)
>   goto put_pll_x;
>   }
>  
> + err = clk_prepare_enable(cpufreq->pll_x_clk);
> + if (err)
> + goto put_pll_p;
> +
> + err = clk_prepare_enable(cpufreq->pll_p_clk);
> + if (err)
> + goto disable_pll_x;
> +
>   cpufreq->dev = >dev;
>   cpufreq->driver.get = cpufreq_generic_get;
>   cpufreq->driver.attr = cpufreq_generic_attr;
> @@ -192,12 +200,16 @@ static int tegra20_cpufreq_probe(struct platform_device 
> *pdev)
>  
>   err = cpufreq_register_driver(>driver);
>   if (err)
> - goto put_pll_p;
> + goto disable_pll_p;
>  
>   platform_set_drvdata(pdev, cpufreq);
>  
>   return 0;
>  
> +disable_pll_p:
> + clk_disable_unprepare(cpufreq->pll_p_clk);
> +disable_pll_x:
> + clk_disable_unprepare(cpufreq->pll_x_clk);
>  put_pll_p:
>   clk_put(cpufreq->pll_p_clk);
>  put_pll_x:
> @@ -214,6 +226,8 @@ static int tegra20_cpufreq_remove(struct platform_device 
> *pdev)
>  
>   cpufreq_unregister_driver(>driver);
>  
> + clk_disable_unprepare(cpufreq->pll_p_clk);
> + clk_disable_unprepare(cpufreq->pll_x_clk);
>   clk_put(cpufreq->pll_p_clk);
>   clk_put(cpufreq->pll_x_clk);
>   clk_put(cpufreq->cpu_clk);

Acked-by: Viresh Kumar 

-- 
viresh


Re: [PATCH v1] cpufreq: tegra20: Fix imbalanced clock enable count

2018-05-22 Thread Viresh Kumar
On 23-05-18, 00:14, Dmitry Osipenko wrote:
> Tegra20-cpufreq driver missed enabling the CPU clocks. This results in a
> clock-enable refcount disbalance on PLL_P <-> PLL_X reparent, causing
> PLL_X to get disabled while it shouldn't. Fix this by enabling the clocks
> on the driver probe.
> 
> Signed-off-by: Dmitry Osipenko 
> ---
> 
> CPUFreq maintainers,
> 
> Please take into account that this patch is made on top of my recent
> series of patches [0] "Clean up Tegra20 cpufreq driver" that was fully
> reviewed, but seems not applied yet. Let me know if you prefer to re-spin
> the [0], including this patch into the series.
> 
> [0] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=45321

This is already picked by Rafael and is sitting in pm/bleeding-edge
branch. Should get merged into linux-next in a day or two.

>  drivers/cpufreq/tegra20-cpufreq.c | 16 +++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/tegra20-cpufreq.c 
> b/drivers/cpufreq/tegra20-cpufreq.c
> index 05f57dcd5215..ca5229265b60 100644
> --- a/drivers/cpufreq/tegra20-cpufreq.c
> +++ b/drivers/cpufreq/tegra20-cpufreq.c
> @@ -176,6 +176,14 @@ static int tegra20_cpufreq_probe(struct platform_device 
> *pdev)
>   goto put_pll_x;
>   }
>  
> + err = clk_prepare_enable(cpufreq->pll_x_clk);
> + if (err)
> + goto put_pll_p;
> +
> + err = clk_prepare_enable(cpufreq->pll_p_clk);
> + if (err)
> + goto disable_pll_x;
> +
>   cpufreq->dev = >dev;
>   cpufreq->driver.get = cpufreq_generic_get;
>   cpufreq->driver.attr = cpufreq_generic_attr;
> @@ -192,12 +200,16 @@ static int tegra20_cpufreq_probe(struct platform_device 
> *pdev)
>  
>   err = cpufreq_register_driver(>driver);
>   if (err)
> - goto put_pll_p;
> + goto disable_pll_p;
>  
>   platform_set_drvdata(pdev, cpufreq);
>  
>   return 0;
>  
> +disable_pll_p:
> + clk_disable_unprepare(cpufreq->pll_p_clk);
> +disable_pll_x:
> + clk_disable_unprepare(cpufreq->pll_x_clk);
>  put_pll_p:
>   clk_put(cpufreq->pll_p_clk);
>  put_pll_x:
> @@ -214,6 +226,8 @@ static int tegra20_cpufreq_remove(struct platform_device 
> *pdev)
>  
>   cpufreq_unregister_driver(>driver);
>  
> + clk_disable_unprepare(cpufreq->pll_p_clk);
> + clk_disable_unprepare(cpufreq->pll_x_clk);
>   clk_put(cpufreq->pll_p_clk);
>   clk_put(cpufreq->pll_x_clk);
>   clk_put(cpufreq->cpu_clk);

Acked-by: Viresh Kumar 

-- 
viresh


Re: [PATCH] mfd: cros_ec: retry commands when EC is known to be busy

2018-05-22 Thread Lee Jones
On Tue, 22 May 2018, Brian Norris wrote:

> Commit 001dde9400d5 ("mfd: cros ec: spi: Fix "in progress" error
> signaling") pointed out some bad code, but its analysis and conclusion
> was not 100% correct.
> 
> It *is* correct that we should not propagate result==EC_RES_IN_PROGRESS
> for transport errors, because this has a special meaning -- that we
> should follow up with EC_CMD_GET_COMMS_STATUS until the EC is no longer
> busy. This is definitely the wrong thing for many commands, because
> among other problems, EC_CMD_GET_COMMS_STATUS doesn't actually retrieve
> any RX data from the EC, so commands that expected some data back will
> instead start processing junk.
> 
> For such commands, the right answer is to either propagate the error
> (and return that error to the caller) or resend the original command
> (*not* EC_CMD_GET_COMMS_STATUS).
> 
> Unfortunately, commit 001dde9400d5 forgets a crucial point: that for
> some long-running operations, the EC physically cannot respond to
> commands any more. For example, with EC_CMD_FLASH_ERASE, the EC may be
> re-flashing its own code regions, so it can't respond to SPI interrupts.
> Instead, the EC prepares us ahead of time for being busy for a "long"
> time, and fills its hardware buffer with EC_SPI_PAST_END. Thus, we
> expect to see several "transport" errors (or, messages filled with
> EC_SPI_PAST_END). So we should really translate that to a retryable
> error (-EAGAIN) and continue sending EC_CMD_GET_COMMS_STATUS until we
> get a ready status.
> 
> IOW, it is actually important to treat some of these "junk" values as
> retryable errors.
> 
> Together with commit 001dde9400d5, this resolves bugs like the
> following:
> 
> 1. EC_CMD_FLASH_ERASE now works again (with commit 001dde9400d5, we
>would abort the first time we saw EC_SPI_PAST_END)
> 2. Before commit 001dde9400d5, transport errors (e.g.,
>EC_SPI_RX_BAD_DATA) seen in other commands (e.g.,
>EC_CMD_RTC_GET_VALUE) used to yield junk data in the RX buffer; they
>will now yield -EAGAIN return values, and tools like 'hwclock' will
>simply fail instead of retrieving and re-programming undefined time
>values
> 
> Fixes: 001dde9400d5 ("mfd: cros ec: spi: Fix "in progress" error signaling")
> Signed-off-by: Brian Norris 
> ---
>  drivers/mfd/cros_ec_spi.c   | 24 
>  drivers/platform/chrome/cros_ec_proto.c |  2 ++
>  2 files changed, 22 insertions(+), 4 deletions(-)

I'm convinced.

Applied, thanks.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


Re: [PATCH] mfd: cros_ec: retry commands when EC is known to be busy

2018-05-22 Thread Lee Jones
On Tue, 22 May 2018, Brian Norris wrote:

> Commit 001dde9400d5 ("mfd: cros ec: spi: Fix "in progress" error
> signaling") pointed out some bad code, but its analysis and conclusion
> was not 100% correct.
> 
> It *is* correct that we should not propagate result==EC_RES_IN_PROGRESS
> for transport errors, because this has a special meaning -- that we
> should follow up with EC_CMD_GET_COMMS_STATUS until the EC is no longer
> busy. This is definitely the wrong thing for many commands, because
> among other problems, EC_CMD_GET_COMMS_STATUS doesn't actually retrieve
> any RX data from the EC, so commands that expected some data back will
> instead start processing junk.
> 
> For such commands, the right answer is to either propagate the error
> (and return that error to the caller) or resend the original command
> (*not* EC_CMD_GET_COMMS_STATUS).
> 
> Unfortunately, commit 001dde9400d5 forgets a crucial point: that for
> some long-running operations, the EC physically cannot respond to
> commands any more. For example, with EC_CMD_FLASH_ERASE, the EC may be
> re-flashing its own code regions, so it can't respond to SPI interrupts.
> Instead, the EC prepares us ahead of time for being busy for a "long"
> time, and fills its hardware buffer with EC_SPI_PAST_END. Thus, we
> expect to see several "transport" errors (or, messages filled with
> EC_SPI_PAST_END). So we should really translate that to a retryable
> error (-EAGAIN) and continue sending EC_CMD_GET_COMMS_STATUS until we
> get a ready status.
> 
> IOW, it is actually important to treat some of these "junk" values as
> retryable errors.
> 
> Together with commit 001dde9400d5, this resolves bugs like the
> following:
> 
> 1. EC_CMD_FLASH_ERASE now works again (with commit 001dde9400d5, we
>would abort the first time we saw EC_SPI_PAST_END)
> 2. Before commit 001dde9400d5, transport errors (e.g.,
>EC_SPI_RX_BAD_DATA) seen in other commands (e.g.,
>EC_CMD_RTC_GET_VALUE) used to yield junk data in the RX buffer; they
>will now yield -EAGAIN return values, and tools like 'hwclock' will
>simply fail instead of retrieving and re-programming undefined time
>values
> 
> Fixes: 001dde9400d5 ("mfd: cros ec: spi: Fix "in progress" error signaling")
> Signed-off-by: Brian Norris 
> ---
>  drivers/mfd/cros_ec_spi.c   | 24 
>  drivers/platform/chrome/cros_ec_proto.c |  2 ++
>  2 files changed, 22 insertions(+), 4 deletions(-)

I'm convinced.

Applied, thanks.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


Re: [PATCH v2 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver

2018-05-22 Thread Viresh Kumar
On 22-05-18, 16:13, Taniya Das wrote:
> On 5/22/2018 12:36 AM, skan...@codeaurora.org wrote:
> > On 2018-05-21 02:01, Viresh Kumar wrote:
> > > On 19-05-18, 23:04, Taniya Das wrote:

> > > > +    /* Make sure the write goes through before proceeding */
> > > > +    mb();
> > > 
> > > Btw what happens right after this is done ? Are we guaranteed that the
> > > frequency is updated in the hardware after this ? What about enabling
> > > fast-switch for your platform ? Look at drivers/cpufreq/scmi-cpufreq.c
> > > to see how that is done.
> > 
> > Yeah, I don't think this is needed really.
> > 
> 
> Just want to make sure it doesn't really sit in the write buffer before
> return.

As per Saravana you will be dropping it now, right ?

> > > > +    index = readl_relaxed(c->perf_base);
> > > > +    index = min(index, LUT_MAX_ENTRIES - 1);
> > > 
> > > Will the hardware ever read a value over 39 here ?
> > 
> > The register could be initialized to whatever before the kernel is
> > brought up. Don't want to depend on it being correct to avoid out of
> > bounds access that could leak data.

Fair enough.

> > > > +static int qcom_read_lut(struct platform_device *pdev,
> > > > + struct cpufreq_qcom *c)
> > > > +{
> > > > +    struct device *dev = >dev;
> > > > +    u32 data, src, lval, i, core_count, prev_cc;
> > > > +
> > > > +    c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> > > > +    sizeof(*c->table), GFP_KERNEL);
> > > > +    if (!c->table)
> > > > +    return -ENOMEM;
> > > > +
> > > > +    for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> > > > +    data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
> > > > +    src = ((data & GENMASK(31, 30)) >> 30);
> > > > +    lval = (data & GENMASK(7, 0));
> > > > +    core_count = CORE_COUNT_VAL(data);
> > > > +
> > > > +    if (!src)
> > > > +    c->table[i].frequency = INIT_RATE / 1000;
> > > > +    else
> > > > +    c->table[i].frequency = XO_RATE * lval / 1000;
> > > > +
> > > > +    c->table[i].driver_data = c->table[i].frequency;
> > > 
> > > Why do you need to use driver_data here? Why can't you simple use
> > > frequency field in the below conditional expressions ?
> > > 
> 
> The frequency field would be marked INVALID in case the core count does not
> match and the frequency data would be lost.
> 
> > > > +
> > > > +    dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
> > > > +    i, c->table[i].frequency, core_count);
> > > > +
> > > > +    if (core_count != c->max_cores)
> > > > +    c->table[i].frequency = CPUFREQ_ENTRY_INVALID;
> > > > +
> > > > +    /*
> > > > + * Two of the same frequencies with the same core counts means
> > > > + * end of table.
> > > > + */
> > > > +    if (i > 0 && c->table[i - 1].driver_data ==
> > > > +    c->table[i].driver_data && prev_cc == core_count) {
> > > > +    struct cpufreq_frequency_table *prev = >table[i - 1];
> > > > +
> > > > +    if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
> > > 
> > > There can only be a single boost frequency at max ?
> > 
> > As of now, yes. If that changes, we'll change this code later.
> > 
> > > > +    prev->flags = CPUFREQ_BOOST_FREQ;
> > > > +    prev->frequency = prev->driver_data;
> > > 
> > > Okay you are using driver_data as a local variable to keep this value
> > > safe which you might have overwritten. Maybe use a simple variable
> > > prev_freq for this. It would be much more readable in that case and
> > > you wouldn't end up abusing the driver_data field.
> > > 
> 
> Please correct me, currently the driver_data is not used by cpufreq core and
> that was the reason to use it. In case you still think it is not a good way
> to handle it, I would try to handle it differently.

Yeah, the driver data will not be used by cpufreq core, but I think
the code would be far more readable if you use a local variable like
prev_freq instead.

> > > > +    }
> > > > +
> > > > +    break;
> > > > +    }
> > > > +    prev_cc = core_count;
> > > > +    }
> > > > +    c->table[i].frequency = CPUFREQ_TABLE_END;
> > > 
> > > Wouldn't you end up writing on c->table[40].frequency here if there
> > > are 40 frequency value present ?
> > 
> > Yeah, the loop condition needs to be fixed.
> > 
> 
> The table allocation is done for 'LUT_MAX_ENTRIES + 1'.
> Yes in case we have all [0-39] (i.e 40 entries) read from the hardware,
> would store the same and mark the 40th index as table end. Please correct if
> I missed something in your comment.

Ahh, you are right. I misread it.

-- 
viresh


Re: [PATCH v2 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver

2018-05-22 Thread Viresh Kumar
On 22-05-18, 16:13, Taniya Das wrote:
> On 5/22/2018 12:36 AM, skan...@codeaurora.org wrote:
> > On 2018-05-21 02:01, Viresh Kumar wrote:
> > > On 19-05-18, 23:04, Taniya Das wrote:

> > > > +    /* Make sure the write goes through before proceeding */
> > > > +    mb();
> > > 
> > > Btw what happens right after this is done ? Are we guaranteed that the
> > > frequency is updated in the hardware after this ? What about enabling
> > > fast-switch for your platform ? Look at drivers/cpufreq/scmi-cpufreq.c
> > > to see how that is done.
> > 
> > Yeah, I don't think this is needed really.
> > 
> 
> Just want to make sure it doesn't really sit in the write buffer before
> return.

As per Saravana you will be dropping it now, right ?

> > > > +    index = readl_relaxed(c->perf_base);
> > > > +    index = min(index, LUT_MAX_ENTRIES - 1);
> > > 
> > > Will the hardware ever read a value over 39 here ?
> > 
> > The register could be initialized to whatever before the kernel is
> > brought up. Don't want to depend on it being correct to avoid out of
> > bounds access that could leak data.

Fair enough.

> > > > +static int qcom_read_lut(struct platform_device *pdev,
> > > > + struct cpufreq_qcom *c)
> > > > +{
> > > > +    struct device *dev = >dev;
> > > > +    u32 data, src, lval, i, core_count, prev_cc;
> > > > +
> > > > +    c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> > > > +    sizeof(*c->table), GFP_KERNEL);
> > > > +    if (!c->table)
> > > > +    return -ENOMEM;
> > > > +
> > > > +    for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> > > > +    data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
> > > > +    src = ((data & GENMASK(31, 30)) >> 30);
> > > > +    lval = (data & GENMASK(7, 0));
> > > > +    core_count = CORE_COUNT_VAL(data);
> > > > +
> > > > +    if (!src)
> > > > +    c->table[i].frequency = INIT_RATE / 1000;
> > > > +    else
> > > > +    c->table[i].frequency = XO_RATE * lval / 1000;
> > > > +
> > > > +    c->table[i].driver_data = c->table[i].frequency;
> > > 
> > > Why do you need to use driver_data here? Why can't you simple use
> > > frequency field in the below conditional expressions ?
> > > 
> 
> The frequency field would be marked INVALID in case the core count does not
> match and the frequency data would be lost.
> 
> > > > +
> > > > +    dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
> > > > +    i, c->table[i].frequency, core_count);
> > > > +
> > > > +    if (core_count != c->max_cores)
> > > > +    c->table[i].frequency = CPUFREQ_ENTRY_INVALID;
> > > > +
> > > > +    /*
> > > > + * Two of the same frequencies with the same core counts means
> > > > + * end of table.
> > > > + */
> > > > +    if (i > 0 && c->table[i - 1].driver_data ==
> > > > +    c->table[i].driver_data && prev_cc == core_count) {
> > > > +    struct cpufreq_frequency_table *prev = >table[i - 1];
> > > > +
> > > > +    if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
> > > 
> > > There can only be a single boost frequency at max ?
> > 
> > As of now, yes. If that changes, we'll change this code later.
> > 
> > > > +    prev->flags = CPUFREQ_BOOST_FREQ;
> > > > +    prev->frequency = prev->driver_data;
> > > 
> > > Okay you are using driver_data as a local variable to keep this value
> > > safe which you might have overwritten. Maybe use a simple variable
> > > prev_freq for this. It would be much more readable in that case and
> > > you wouldn't end up abusing the driver_data field.
> > > 
> 
> Please correct me, currently the driver_data is not used by cpufreq core and
> that was the reason to use it. In case you still think it is not a good way
> to handle it, I would try to handle it differently.

Yeah, the driver data will not be used by cpufreq core, but I think
the code would be far more readable if you use a local variable like
prev_freq instead.

> > > > +    }
> > > > +
> > > > +    break;
> > > > +    }
> > > > +    prev_cc = core_count;
> > > > +    }
> > > > +    c->table[i].frequency = CPUFREQ_TABLE_END;
> > > 
> > > Wouldn't you end up writing on c->table[40].frequency here if there
> > > are 40 frequency value present ?
> > 
> > Yeah, the loop condition needs to be fixed.
> > 
> 
> The table allocation is done for 'LUT_MAX_ENTRIES + 1'.
> Yes in case we have all [0-39] (i.e 40 entries) read from the hardware,
> would store the same and mark the 40th index as table end. Please correct if
> I missed something in your comment.

Ahh, you are right. I misread it.

-- 
viresh


Re: [PATCH rdma-next 3/5] RDMA/hns: Increase checking CMQ status timeout value

2018-05-22 Thread Leon Romanovsky
On Thu, May 17, 2018 at 04:02:51PM +0800, Wei Hu (Xavier) wrote:
> This patch increases checking CMQ status timeout value and
> uses the same value with NIC driver to avoid deficiency of
> time.
>
> Signed-off-by: Wei Hu (Xavier) 
> ---
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 
> b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> index 182b672..f16df1b 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> @@ -76,7 +76,7 @@
>  #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED  0xF000
>  #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM   2
>  #define HNS_ROCE_INVALID_LKEY0x100
> -#define HNS_ROCE_CMQ_TX_TIMEOUT  200
> +#define HNS_ROCE_CMQ_TX_TIMEOUT  3

Don't you think that loop of 30 seconds too much?

Thanks

>
>  #define HNS_ROCE_CONTEXT_HOP_NUM 1
>  #define HNS_ROCE_MTT_HOP_NUM 1
> --
> 1.9.1
>


signature.asc
Description: PGP signature


Re: [PATCH rdma-next 3/5] RDMA/hns: Increase checking CMQ status timeout value

2018-05-22 Thread Leon Romanovsky
On Thu, May 17, 2018 at 04:02:51PM +0800, Wei Hu (Xavier) wrote:
> This patch increases checking CMQ status timeout value and
> uses the same value with NIC driver to avoid deficiency of
> time.
>
> Signed-off-by: Wei Hu (Xavier) 
> ---
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 
> b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> index 182b672..f16df1b 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> @@ -76,7 +76,7 @@
>  #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED  0xF000
>  #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM   2
>  #define HNS_ROCE_INVALID_LKEY0x100
> -#define HNS_ROCE_CMQ_TX_TIMEOUT  200
> +#define HNS_ROCE_CMQ_TX_TIMEOUT  3

Don't you think that loop of 30 seconds too much?

Thanks

>
>  #define HNS_ROCE_CONTEXT_HOP_NUM 1
>  #define HNS_ROCE_MTT_HOP_NUM 1
> --
> 1.9.1
>


signature.asc
Description: PGP signature


Re: [PATCH v2 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings

2018-05-22 Thread Viresh Kumar
On 22-05-18, 14:31, Rob Herring wrote:
> On Sat, May 19, 2018 at 11:04:50PM +0530, Taniya Das wrote:
> > +   freq-domain-0 {
> > +   compatible = "cpufreq";
> > +   reg = <0x17d43920 0x4>,
> > +<0x17d43110 0x500>,
> > +<0x17d41000 0x4>;
> > +   reg-names = "perf_base", "lut_base", "en_base";
> > +   qcom,cpulist = <   >;

I was thinking, can't we add platform specific properties in the CPU
nodes ? If yes, then we can point the phandle of fw node from the CPUs
and this awkward list can go away.

-- 
viresh


Re: [PATCH v2 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings

2018-05-22 Thread Viresh Kumar
On 22-05-18, 14:31, Rob Herring wrote:
> On Sat, May 19, 2018 at 11:04:50PM +0530, Taniya Das wrote:
> > +   freq-domain-0 {
> > +   compatible = "cpufreq";
> > +   reg = <0x17d43920 0x4>,
> > +<0x17d43110 0x500>,
> > +<0x17d41000 0x4>;
> > +   reg-names = "perf_base", "lut_base", "en_base";
> > +   qcom,cpulist = <   >;

I was thinking, can't we add platform specific properties in the CPU
nodes ? If yes, then we can point the phandle of fw node from the CPUs
and this awkward list can go away.

-- 
viresh


Re: [PATCH] cpufreq: Add Kryo CPU scaling driver

2018-05-22 Thread Viresh Kumar
On 22-05-18, 14:07, Sudeep Holla wrote:
> On Tue, May 22, 2018 at 02:29:45PM +0300, Ilia Lin wrote:
> > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
> > the CPU frequency subset and voltage value of each OPP varies
> > based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
> > defines the voltage and frequency value based on the msm-id in SMEM
> > and speedbin blown in the efuse combination.
> > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> > to provide the OPP framework with required information.
> > This is used to determine the voltage and frequency value for each OPP of
> > operating-points-v2 table when it is parsed by the OPP framework.
> > 
> > Signed-off-by: Ilia Lin 
> > Acked-by: Viresh Kumar 
> 
> [...]
> 
> > +
> > +   switch (msm8996_version) {
> > +   case MSM8996_V3:
> > +   versions = 1 << (unsigned int)(*speedbin);
> > +   break;
> > +   case MSM8996_SG:
> > +   versions = 1 << ((unsigned int)(*speedbin) + 4);
> > +   break;
> > +   default:
> > +   BUG();
> > +   break;
> > +   }
> > +
> > +   for_each_possible_cpu(cpu) {
> > +   cpu_dev = get_cpu_device(cpu);
> > +   if (NULL == cpu_dev) {
> > +   ret = -ENODEV;
> > +   goto free_opp;
> > +   }
> > +
> > +   opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
> > + , 1);
> 
> Will be not get NULL for all CPUs except 0 ?

With my patches, we will get the OPP table again with refcount
incremented. And on failures, we need to call put-supported-hw helper
only for the CPUs for which it passed previously.

-- 
viresh


Re: [PATCH] cpufreq: Add Kryo CPU scaling driver

2018-05-22 Thread Viresh Kumar
On 22-05-18, 14:07, Sudeep Holla wrote:
> On Tue, May 22, 2018 at 02:29:45PM +0300, Ilia Lin wrote:
> > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
> > the CPU frequency subset and voltage value of each OPP varies
> > based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
> > defines the voltage and frequency value based on the msm-id in SMEM
> > and speedbin blown in the efuse combination.
> > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> > to provide the OPP framework with required information.
> > This is used to determine the voltage and frequency value for each OPP of
> > operating-points-v2 table when it is parsed by the OPP framework.
> > 
> > Signed-off-by: Ilia Lin 
> > Acked-by: Viresh Kumar 
> 
> [...]
> 
> > +
> > +   switch (msm8996_version) {
> > +   case MSM8996_V3:
> > +   versions = 1 << (unsigned int)(*speedbin);
> > +   break;
> > +   case MSM8996_SG:
> > +   versions = 1 << ((unsigned int)(*speedbin) + 4);
> > +   break;
> > +   default:
> > +   BUG();
> > +   break;
> > +   }
> > +
> > +   for_each_possible_cpu(cpu) {
> > +   cpu_dev = get_cpu_device(cpu);
> > +   if (NULL == cpu_dev) {
> > +   ret = -ENODEV;
> > +   goto free_opp;
> > +   }
> > +
> > +   opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
> > + , 1);
> 
> Will be not get NULL for all CPUs except 0 ?

With my patches, we will get the OPP table again with refcount
incremented. And on failures, we need to call put-supported-hw helper
only for the CPUs for which it passed previously.

-- 
viresh


Re: [PATCH] media: uvcvideo: Support realtek's UVC 1.5 device

2018-05-22 Thread Kai Heng Feng


On May 23, 2018, at 4:32 AM, Laurent Pinchart  
 wrote:


Hello,

Thank you for the patch.

On Wednesday, 9 May 2018 05:13:08 EEST ming_q...@realsil.com.cn wrote:

From: ming_qian 

The length of UVC 1.5 video control is 48, and it id 34 for UVC 1.1.
Change it to 48 for UVC 1.5 device,
and the UVC 1.5 device can be recognized.

More changes to the driver are needed for full UVC 1.5 compatibility.
However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have
been reported to work well.


This patch is however not specific to Realtek devices, so I think we should
make the subject line more generic. It's fine mentioning in the commit  
message
itself that the Realtek RTS5847/RTS5852 cameras have been successfully  
tested.



Signed-off-by: ming_qian 
---
 drivers/media/usb/uvc/uvc_video.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_video.c
b/drivers/media/usb/uvc/uvc_video.c index aa0082f..32dfb32 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -171,6 +171,8 @@ static int uvc_get_video_ctrl(struct uvc_streaming
*stream, int ret;

size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
+   if (stream->dev->uvc_version >= 0x0150)
+   size = 48;
if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
query == UVC_GET_DEF)
return -EIO;
@@ -259,6 +261,8 @@ static int uvc_set_video_ctrl(struct uvc_streaming
*stream, int ret;

size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
+   if (stream->dev->uvc_version >= 0x0150)
+   size = 48;
data = kzalloc(size, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;


Instead of duplicating the computation in both functions, I think we should
move the code to a helper function.

Furthermore there are equality checks further down both functions that  
compare

the size to 34, they should be updated to also support UVC 1.5.

I propose the following updated patch. If you're fine with it there's no  
need

to resubmit, I'll queue it for v4.19.

I have dropped the Reviewed-by and Tested-by tags as the patch has changed.

commit a9c002732695eab2096580a0d1a1687bc2f95928
Author: ming_qian 
Date:   Wed May 9 10:13:08 2018 +0800

media: uvcvideo: Support UVC 1.5 video probe & commit controls

The length of UVC 1.5 video control is 48, and it is 34 for UVC 1.1.
Change it to 48 for UVC 1.5 device, and the UVC 1.5 device can be
recognized.

More changes to the driver are needed for full UVC 1.5 compatibility.
However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have been
reported to work well.

Cc: sta...@vger.kernel.org
Signed-off-by: ming_qian 
[Factor out code to helper function, update size checks]
Signed-off-by: Laurent Pinchart 


I tested this new patch and it works well.

Tested-by: Kai-Heng Feng 



diff --git a/drivers/media/usb/uvc/uvc_video.c  
b/drivers/media/usb/uvc/uvc_video.c

index eb9e04a59427..285b0e813b9d 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -207,14 +207,27 @@ static void uvc_fixup_video_ctrl(struct  
uvc_streaming *stream,

}
 }

+static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
+{
+   /*
+* Return the size of the video probe and commit controls, which depends
+* on the protocol version.
+*/
+   if (stream->dev->uvc_version < 0x0110)
+   return 26;
+   else if (stream->dev->uvc_version < 0x0150)
+   return 34;
+   else
+   return 48;
+}
+
 static int uvc_get_video_ctrl(struct uvc_streaming *stream,
struct uvc_streaming_control *ctrl, int probe, u8 query)
 {
+   u16 size = uvc_video_ctrl_size(stream);
u8 *data;
-   u16 size;
int ret;

-   size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
query == UVC_GET_DEF)
return -EIO;
@@ -271,7 +284,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming  
*stream,

ctrl->dwMaxVideoFrameSize = get_unaligned_le32([18]);
ctrl->dwMaxPayloadTransferSize = get_unaligned_le32([22]);

-   if (size == 34) {
+   if (size >= 34) {
ctrl->dwClockFrequency = get_unaligned_le32([26]);
ctrl->bmFramingInfo = data[30];
ctrl->bPreferedVersion = data[31];
@@ -300,11 +313,10 @@ static int uvc_get_video_ctrl(struct uvc_streaming  
*stream,

 static int uvc_set_video_ctrl(struct uvc_streaming *stream,
struct uvc_streaming_control *ctrl, int probe)
 {
+   u16 size = uvc_video_ctrl_size(stream);
u8 *data;
-   u16 size;
 

Re: [PATCH] media: uvcvideo: Support realtek's UVC 1.5 device

2018-05-22 Thread Kai Heng Feng


On May 23, 2018, at 4:32 AM, Laurent Pinchart  
 wrote:


Hello,

Thank you for the patch.

On Wednesday, 9 May 2018 05:13:08 EEST ming_q...@realsil.com.cn wrote:

From: ming_qian 

The length of UVC 1.5 video control is 48, and it id 34 for UVC 1.1.
Change it to 48 for UVC 1.5 device,
and the UVC 1.5 device can be recognized.

More changes to the driver are needed for full UVC 1.5 compatibility.
However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have
been reported to work well.


This patch is however not specific to Realtek devices, so I think we should
make the subject line more generic. It's fine mentioning in the commit  
message
itself that the Realtek RTS5847/RTS5852 cameras have been successfully  
tested.



Signed-off-by: ming_qian 
---
 drivers/media/usb/uvc/uvc_video.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_video.c
b/drivers/media/usb/uvc/uvc_video.c index aa0082f..32dfb32 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -171,6 +171,8 @@ static int uvc_get_video_ctrl(struct uvc_streaming
*stream, int ret;

size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
+   if (stream->dev->uvc_version >= 0x0150)
+   size = 48;
if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
query == UVC_GET_DEF)
return -EIO;
@@ -259,6 +261,8 @@ static int uvc_set_video_ctrl(struct uvc_streaming
*stream, int ret;

size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
+   if (stream->dev->uvc_version >= 0x0150)
+   size = 48;
data = kzalloc(size, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;


Instead of duplicating the computation in both functions, I think we should
move the code to a helper function.

Furthermore there are equality checks further down both functions that  
compare

the size to 34, they should be updated to also support UVC 1.5.

I propose the following updated patch. If you're fine with it there's no  
need

to resubmit, I'll queue it for v4.19.

I have dropped the Reviewed-by and Tested-by tags as the patch has changed.

commit a9c002732695eab2096580a0d1a1687bc2f95928
Author: ming_qian 
Date:   Wed May 9 10:13:08 2018 +0800

media: uvcvideo: Support UVC 1.5 video probe & commit controls

The length of UVC 1.5 video control is 48, and it is 34 for UVC 1.1.
Change it to 48 for UVC 1.5 device, and the UVC 1.5 device can be
recognized.

More changes to the driver are needed for full UVC 1.5 compatibility.
However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have been
reported to work well.

Cc: sta...@vger.kernel.org
Signed-off-by: ming_qian 
[Factor out code to helper function, update size checks]
Signed-off-by: Laurent Pinchart 


I tested this new patch and it works well.

Tested-by: Kai-Heng Feng 



diff --git a/drivers/media/usb/uvc/uvc_video.c  
b/drivers/media/usb/uvc/uvc_video.c

index eb9e04a59427..285b0e813b9d 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -207,14 +207,27 @@ static void uvc_fixup_video_ctrl(struct  
uvc_streaming *stream,

}
 }

+static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
+{
+   /*
+* Return the size of the video probe and commit controls, which depends
+* on the protocol version.
+*/
+   if (stream->dev->uvc_version < 0x0110)
+   return 26;
+   else if (stream->dev->uvc_version < 0x0150)
+   return 34;
+   else
+   return 48;
+}
+
 static int uvc_get_video_ctrl(struct uvc_streaming *stream,
struct uvc_streaming_control *ctrl, int probe, u8 query)
 {
+   u16 size = uvc_video_ctrl_size(stream);
u8 *data;
-   u16 size;
int ret;

-   size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
query == UVC_GET_DEF)
return -EIO;
@@ -271,7 +284,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming  
*stream,

ctrl->dwMaxVideoFrameSize = get_unaligned_le32([18]);
ctrl->dwMaxPayloadTransferSize = get_unaligned_le32([22]);

-   if (size == 34) {
+   if (size >= 34) {
ctrl->dwClockFrequency = get_unaligned_le32([26]);
ctrl->bmFramingInfo = data[30];
ctrl->bPreferedVersion = data[31];
@@ -300,11 +313,10 @@ static int uvc_get_video_ctrl(struct uvc_streaming  
*stream,

 static int uvc_set_video_ctrl(struct uvc_streaming *stream,
struct uvc_streaming_control *ctrl, int probe)
 {
+   u16 size = uvc_video_ctrl_size(stream);
u8 *data;
-   u16 size;
int ret;

-   size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
data = kzalloc(size, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -321,7 +333,7 @@ static 

Re: [PATCH V3] powercap/drivers/idle_injection: Add an idle injection framework

2018-05-22 Thread Viresh Kumar
On 22-05-18, 15:42, Daniel Lezcano wrote:
> On 21/05/2018 12:32, Viresh Kumar wrote:
> > On 18-05-18, 16:50, Daniel Lezcano wrote:
> >> Initially, the cpu_cooling device for ARM was changed by adding a new
> >> policy inserting idle cycles. The intel_powerclamp driver does a
> >> similar action.
> >>
> >> Instead of implementing idle injections privately in the cpu_cooling
> >> device, move the idle injection code in a dedicated framework and give
> >> the opportunity to other frameworks to make use of it.
> > 
> > I thought you agreed to move above in the comments section ?
> 
> This is what I did. I just kept the relevant log here.

The fact that you are stating that you tried to update the cooling
device earlier looked like a bit of version history to me, not what
this patch is doing.

But its okay if you really want that to be preserved in git history :)

> >> +static void idle_injection_fn(unsigned int cpu)
> >> +{
> >> +  struct idle_injection_device *ii_dev;
> >> +  struct idle_injection_thread *iit;
> >> +  int run_duration_ms, idle_duration_ms;
> >> +
> >> +  ii_dev = per_cpu(idle_injection_device, cpu);
> >> +
> >> +  iit = per_cpu_ptr(_injection_thread, cpu);
> >> +
> >> +  /*
> >> +   * Boolean used by the smpboot mainloop and used as a flip-flop
> >> +   * in this function
> >> +   */
> >> +  iit->should_run = 0;
> >> +
> >> +  atomic_inc(_dev->count);
> >> +
> >> +  idle_duration_ms = atomic_read(_dev->idle_duration_ms);
> >> +
> >> +  play_idle(idle_duration_ms);
> >> +
> >> +  /*
> >> +   * The last CPU waking up is in charge of setting the timer. If
> >> +   * the CPU is hotplugged, the timer will move to another CPU
> >> +   * (which may not belong to the same cluster) but that is not a
> >> +   * problem as the timer will be set again by another CPU
> >> +   * belonging to the cluster. This mechanism is self adaptive.
> >> +   */
> >> +  if (!atomic_dec_and_test(_dev->count))
> >> +  return;
> >> +
> >> +  run_duration_ms = atomic_read(_dev->run_duration_ms);
> > 
> > This reads as if it is okay to have run_duration_ms set as 0, so we
> > run idle loop only once. Which is fine, but why do you mandate this to
> > be non-zero in idle_injection_start() ?
> 
> It does not make sense to run this function with a run duration set to
> zero because we will immediately go to idle again after exiting idle. So
> the action is exiting. In this context we can't accept to start
> injecting idle cycles.

Right and that's why I said "Which is fine" in my comment above. My
question was more on why we error out in idle_injection_start() if
run_duration_ms is 0.

Just for my understanding, is it a valid usecase where we want to run
the idle loop only once ? i.e. set idle_duration_ms to a non-zero
value but run_duration_ms to 0 ? In that case we shouldn't check for
zero run_duration_ms in idle_injection_start().

> >> +  if (!run_duration_ms)
> >> +  return;
> >> +
> >> +  hrtimer_start(_dev->timer, ms_to_ktime(run_duration_ms),
> >> +HRTIMER_MODE_REL_PINNED);
> >> +}
> >> +
> >> +/**
> >> + * idle_injection_set_duration - idle and run duration helper
> >> + * @run_duration_ms: an unsigned int giving the running time in 
> >> milliseconds
> >> + * @idle_duration_ms: an unsigned int giving the idle time in milliseconds
> >> + */
> >> +void idle_injection_set_duration(struct idle_injection_device *ii_dev,
> >> +   unsigned int run_duration_ms,
> >> +   unsigned int idle_duration_ms)
> >> +{
> >> +  atomic_set(_dev->run_duration_ms, run_duration_ms);
> >> +  atomic_set(_dev->idle_duration_ms, idle_duration_ms);
> > 
> > You check for valid values of these in idle_injection_start() but not
> > here, why ?
> 
> By checking against a zero values in the start function is a way to make
> sure we are not starting the idle injection with uninitialized values
> and by setting the duration to zero is a way to stop the idle injection.

Why do we need two ways of stopping the idle injection thread ? Why
isn't just calling idle_injection_stop() the right thing to do in that
case ?

> >> +}
> >> +
> >> +/**
> >> + * idle_injection_get_duration - idle and run duration helper
> >> + * @run_duration_ms: a pointer to an unsigned int to store the running 
> >> time
> >> + * @idle_duration_ms: a pointer to an unsigned int to store the idle time
> >> + */
> >> +void idle_injection_get_duration(struct idle_injection_device *ii_dev,
> >> +   unsigned int *run_duration_ms,
> >> +   unsigned int *idle_duration_ms)
> >> +{
> >> +  *run_duration_ms = atomic_read(_dev->run_duration_ms);
> >> +  *idle_duration_ms = atomic_read(_dev->idle_duration_ms);
> >> +}
> >> +
> >> +/**
> >> + * idle_injection_start - starts the idle injections
> >> + * @ii_dev: a pointer to an idle_injection_device structure
> >> + *
> >> + * The function starts the idle injection cycles by first waking up
> >> + * all the tasks the 

Re: [PATCH v3 00/14] tracing: Add triggers to trace_marker writes

2018-05-22 Thread Namhyung Kim
Hi Steve,

On Wed, May 16, 2018 at 11:00:12AM -0400, Steven Rostedt wrote:
> A few people have asked for this in the past, and I finally got around
> to implementing it. What this does is to allow writes into trace_marker
> to initiate a trigger.
> 
> The trace_marker event is described in:
> 
>  tracefs/events/ftrace/print
> 
> Thus the trigger file is added there:
> 
>  tracefs/events/ftrace/print/trigger
> 
> As there's already a "hist" file there, everything appears to work
> just like any other trigger to an event. See the last patch for
> documentation on how to use the triggers to a trace_marker write.
> 
> By the way, the patch:
> 
>   tracing: Prevent further users of zero size static arrays in trace events
> 
> May prevent your kernel from building if you include Xen. You will need
> to add this patch to make it work (or include the git repo below).
> 
>  http://lkml.kernel.org/r/20180509144605.5a220...@gandalf.local.home
> 
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
> ftrace/core
> 
> Head SHA1: dded7b759602085b4bd2c5581f58f6b179912d89
> 
> 
> Steven Rostedt (VMware) (14):
>   tracing: Do not reference event data in post call triggers
>   tracing: Add __find_event_file() to find event files without 
> restrictions
>   tracing: Have event_trace_init() called by trace_init_tracefs()
>   tracing: Add brackets in ftrace event dynamic arrays
>   tracing: Do not show filter file for ftrace internal events
>   tracing: Add trigger file for trace_markers tracefs/ftrace/print
>   tracing: Have zero size length in filter logic be full string
>   tracing: Prevent further users of zero size static arrays in trace 
> events
>   tracing: Allow histogram triggers to access ftrace internal events
>   tracing: Document trace_marker triggers
>   ftrace/selftest: Have the reset_trigger code be a bit more careful
>   ftrace/selftest: Fix reset_trigger() to handle triggers with filters
>   tracing/selftest: Add selftests to test trace_marker histogram triggers
>   tracing/selftest: Add test to test hist trigger between kernel event 
> and trace_marker
> 
> 

For the series:

Reviewed-by: Namhyung Kim 

Thanks,
Namhyung


> Changes since v2:
> 
>  - typo fixes in documentation (Tom Zanussi)
>  - Rename trigger-trace-marker{-hist} in selftest (Masami Hiramatsu)
>  - Fix onmatch(sched.sched_waking) (Namhyung Kim)
>  - Rename test to say trace_marker trigger from event trigger (Steven Rostedt)
> 
>  Diff from v2 below.
> 
>  Documentation/trace/events.rst |   6 +-
>  Documentation/trace/ftrace.rst |   5 +
>  Documentation/trace/histogram.txt  | 546 
> -
>  include/linux/trace_events.h   |   3 +-
>  include/trace/trace_events.h   |   1 +
>  kernel/trace/trace.c   |  19 +
>  kernel/trace/trace.h   |   9 +-
>  kernel/trace/trace_entries.h   |   6 +-
>  kernel/trace/trace_events.c|  36 +-
>  kernel/trace/trace_events_filter.c |  23 +-
>  kernel/trace/trace_events_hist.c   |   2 +-
>  kernel/trace/trace_events_trigger.c|   6 +-
>  kernel/trace/trace_export.c|   9 +-
>  tools/testing/selftests/ftrace/test.d/functions|  23 +-
>  .../test.d/trigger/trigger-trace-marker-hist.tc|  49 ++
>  .../trigger/trigger-trace-marker-synthetic.tc  |  88 
>  16 files changed, 790 insertions(+), 41 deletions(-)
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-hist.tc
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-synthetic.tc
> 
> 
> diff --git a/Documentation/trace/histogram.txt 
> b/Documentation/trace/histogram.txt
> index 8c871f0c0e33..ae2d4f9d0a62 100644
> --- a/Documentation/trace/histogram.txt
> +++ b/Documentation/trace/histogram.txt
> @@ -2005,7 +2005,7 @@ and after it wakes up, something like this:
>  
>  static void traceputs(char *str)
>  {
> - /* tracemark_fd is the trace_marker file descripto */
> + /* tracemark_fd is the trace_marker file descriptor */
>   if (tracemark_fd < 0)
>   return;
>   /* write the tracemark message */
> @@ -2048,7 +2048,7 @@ Now running cyclictest with:
>  
>  Note, the -b 1000 is used just to make --tracemark available.
>  
> -The we can see the histogram created by this with:
> +Then we can see the histogram created by this with:
>  
>   # cat events/synthetic/latency/hist
>  # event histogram
> @@ -2360,7 +2360,7 @@ kernel with trace_marker.
>  
>  The difference this time is that instead of using the trace_marker to start
>  the latency, the sched_waking event is used, matching the common_pid for the
> -trace_marker write with the pid that is being worken by sched_waking.
> 

Re: [PATCH V3] powercap/drivers/idle_injection: Add an idle injection framework

2018-05-22 Thread Viresh Kumar
On 22-05-18, 15:42, Daniel Lezcano wrote:
> On 21/05/2018 12:32, Viresh Kumar wrote:
> > On 18-05-18, 16:50, Daniel Lezcano wrote:
> >> Initially, the cpu_cooling device for ARM was changed by adding a new
> >> policy inserting idle cycles. The intel_powerclamp driver does a
> >> similar action.
> >>
> >> Instead of implementing idle injections privately in the cpu_cooling
> >> device, move the idle injection code in a dedicated framework and give
> >> the opportunity to other frameworks to make use of it.
> > 
> > I thought you agreed to move above in the comments section ?
> 
> This is what I did. I just kept the relevant log here.

The fact that you are stating that you tried to update the cooling
device earlier looked like a bit of version history to me, not what
this patch is doing.

But its okay if you really want that to be preserved in git history :)

> >> +static void idle_injection_fn(unsigned int cpu)
> >> +{
> >> +  struct idle_injection_device *ii_dev;
> >> +  struct idle_injection_thread *iit;
> >> +  int run_duration_ms, idle_duration_ms;
> >> +
> >> +  ii_dev = per_cpu(idle_injection_device, cpu);
> >> +
> >> +  iit = per_cpu_ptr(_injection_thread, cpu);
> >> +
> >> +  /*
> >> +   * Boolean used by the smpboot mainloop and used as a flip-flop
> >> +   * in this function
> >> +   */
> >> +  iit->should_run = 0;
> >> +
> >> +  atomic_inc(_dev->count);
> >> +
> >> +  idle_duration_ms = atomic_read(_dev->idle_duration_ms);
> >> +
> >> +  play_idle(idle_duration_ms);
> >> +
> >> +  /*
> >> +   * The last CPU waking up is in charge of setting the timer. If
> >> +   * the CPU is hotplugged, the timer will move to another CPU
> >> +   * (which may not belong to the same cluster) but that is not a
> >> +   * problem as the timer will be set again by another CPU
> >> +   * belonging to the cluster. This mechanism is self adaptive.
> >> +   */
> >> +  if (!atomic_dec_and_test(_dev->count))
> >> +  return;
> >> +
> >> +  run_duration_ms = atomic_read(_dev->run_duration_ms);
> > 
> > This reads as if it is okay to have run_duration_ms set as 0, so we
> > run idle loop only once. Which is fine, but why do you mandate this to
> > be non-zero in idle_injection_start() ?
> 
> It does not make sense to run this function with a run duration set to
> zero because we will immediately go to idle again after exiting idle. So
> the action is exiting. In this context we can't accept to start
> injecting idle cycles.

Right and that's why I said "Which is fine" in my comment above. My
question was more on why we error out in idle_injection_start() if
run_duration_ms is 0.

Just for my understanding, is it a valid usecase where we want to run
the idle loop only once ? i.e. set idle_duration_ms to a non-zero
value but run_duration_ms to 0 ? In that case we shouldn't check for
zero run_duration_ms in idle_injection_start().

> >> +  if (!run_duration_ms)
> >> +  return;
> >> +
> >> +  hrtimer_start(_dev->timer, ms_to_ktime(run_duration_ms),
> >> +HRTIMER_MODE_REL_PINNED);
> >> +}
> >> +
> >> +/**
> >> + * idle_injection_set_duration - idle and run duration helper
> >> + * @run_duration_ms: an unsigned int giving the running time in 
> >> milliseconds
> >> + * @idle_duration_ms: an unsigned int giving the idle time in milliseconds
> >> + */
> >> +void idle_injection_set_duration(struct idle_injection_device *ii_dev,
> >> +   unsigned int run_duration_ms,
> >> +   unsigned int idle_duration_ms)
> >> +{
> >> +  atomic_set(_dev->run_duration_ms, run_duration_ms);
> >> +  atomic_set(_dev->idle_duration_ms, idle_duration_ms);
> > 
> > You check for valid values of these in idle_injection_start() but not
> > here, why ?
> 
> By checking against a zero values in the start function is a way to make
> sure we are not starting the idle injection with uninitialized values
> and by setting the duration to zero is a way to stop the idle injection.

Why do we need two ways of stopping the idle injection thread ? Why
isn't just calling idle_injection_stop() the right thing to do in that
case ?

> >> +}
> >> +
> >> +/**
> >> + * idle_injection_get_duration - idle and run duration helper
> >> + * @run_duration_ms: a pointer to an unsigned int to store the running 
> >> time
> >> + * @idle_duration_ms: a pointer to an unsigned int to store the idle time
> >> + */
> >> +void idle_injection_get_duration(struct idle_injection_device *ii_dev,
> >> +   unsigned int *run_duration_ms,
> >> +   unsigned int *idle_duration_ms)
> >> +{
> >> +  *run_duration_ms = atomic_read(_dev->run_duration_ms);
> >> +  *idle_duration_ms = atomic_read(_dev->idle_duration_ms);
> >> +}
> >> +
> >> +/**
> >> + * idle_injection_start - starts the idle injections
> >> + * @ii_dev: a pointer to an idle_injection_device structure
> >> + *
> >> + * The function starts the idle injection cycles by first waking up
> >> + * all the tasks the 

Re: [PATCH v3 00/14] tracing: Add triggers to trace_marker writes

2018-05-22 Thread Namhyung Kim
Hi Steve,

On Wed, May 16, 2018 at 11:00:12AM -0400, Steven Rostedt wrote:
> A few people have asked for this in the past, and I finally got around
> to implementing it. What this does is to allow writes into trace_marker
> to initiate a trigger.
> 
> The trace_marker event is described in:
> 
>  tracefs/events/ftrace/print
> 
> Thus the trigger file is added there:
> 
>  tracefs/events/ftrace/print/trigger
> 
> As there's already a "hist" file there, everything appears to work
> just like any other trigger to an event. See the last patch for
> documentation on how to use the triggers to a trace_marker write.
> 
> By the way, the patch:
> 
>   tracing: Prevent further users of zero size static arrays in trace events
> 
> May prevent your kernel from building if you include Xen. You will need
> to add this patch to make it work (or include the git repo below).
> 
>  http://lkml.kernel.org/r/20180509144605.5a220...@gandalf.local.home
> 
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
> ftrace/core
> 
> Head SHA1: dded7b759602085b4bd2c5581f58f6b179912d89
> 
> 
> Steven Rostedt (VMware) (14):
>   tracing: Do not reference event data in post call triggers
>   tracing: Add __find_event_file() to find event files without 
> restrictions
>   tracing: Have event_trace_init() called by trace_init_tracefs()
>   tracing: Add brackets in ftrace event dynamic arrays
>   tracing: Do not show filter file for ftrace internal events
>   tracing: Add trigger file for trace_markers tracefs/ftrace/print
>   tracing: Have zero size length in filter logic be full string
>   tracing: Prevent further users of zero size static arrays in trace 
> events
>   tracing: Allow histogram triggers to access ftrace internal events
>   tracing: Document trace_marker triggers
>   ftrace/selftest: Have the reset_trigger code be a bit more careful
>   ftrace/selftest: Fix reset_trigger() to handle triggers with filters
>   tracing/selftest: Add selftests to test trace_marker histogram triggers
>   tracing/selftest: Add test to test hist trigger between kernel event 
> and trace_marker
> 
> 

For the series:

Reviewed-by: Namhyung Kim 

Thanks,
Namhyung


> Changes since v2:
> 
>  - typo fixes in documentation (Tom Zanussi)
>  - Rename trigger-trace-marker{-hist} in selftest (Masami Hiramatsu)
>  - Fix onmatch(sched.sched_waking) (Namhyung Kim)
>  - Rename test to say trace_marker trigger from event trigger (Steven Rostedt)
> 
>  Diff from v2 below.
> 
>  Documentation/trace/events.rst |   6 +-
>  Documentation/trace/ftrace.rst |   5 +
>  Documentation/trace/histogram.txt  | 546 
> -
>  include/linux/trace_events.h   |   3 +-
>  include/trace/trace_events.h   |   1 +
>  kernel/trace/trace.c   |  19 +
>  kernel/trace/trace.h   |   9 +-
>  kernel/trace/trace_entries.h   |   6 +-
>  kernel/trace/trace_events.c|  36 +-
>  kernel/trace/trace_events_filter.c |  23 +-
>  kernel/trace/trace_events_hist.c   |   2 +-
>  kernel/trace/trace_events_trigger.c|   6 +-
>  kernel/trace/trace_export.c|   9 +-
>  tools/testing/selftests/ftrace/test.d/functions|  23 +-
>  .../test.d/trigger/trigger-trace-marker-hist.tc|  49 ++
>  .../trigger/trigger-trace-marker-synthetic.tc  |  88 
>  16 files changed, 790 insertions(+), 41 deletions(-)
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-hist.tc
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-synthetic.tc
> 
> 
> diff --git a/Documentation/trace/histogram.txt 
> b/Documentation/trace/histogram.txt
> index 8c871f0c0e33..ae2d4f9d0a62 100644
> --- a/Documentation/trace/histogram.txt
> +++ b/Documentation/trace/histogram.txt
> @@ -2005,7 +2005,7 @@ and after it wakes up, something like this:
>  
>  static void traceputs(char *str)
>  {
> - /* tracemark_fd is the trace_marker file descripto */
> + /* tracemark_fd is the trace_marker file descriptor */
>   if (tracemark_fd < 0)
>   return;
>   /* write the tracemark message */
> @@ -2048,7 +2048,7 @@ Now running cyclictest with:
>  
>  Note, the -b 1000 is used just to make --tracemark available.
>  
> -The we can see the histogram created by this with:
> +Then we can see the histogram created by this with:
>  
>   # cat events/synthetic/latency/hist
>  # event histogram
> @@ -2360,7 +2360,7 @@ kernel with trace_marker.
>  
>  The difference this time is that instead of using the trace_marker to start
>  the latency, the sched_waking event is used, matching the common_pid for the
> -trace_marker write with the pid that is being worken by sched_waking.
> +trace_marker write 

Re: Revert "dmaengine: pl330: add DMA_PAUSE feature"

2018-05-22 Thread Vinod
On 22-05-18, 10:27, Frank Mori Hess wrote:
> On Mon, May 21, 2018 at 11:37 PM, Vinod Koul  wrote:
> >
> > Well looks like even adding support for sync_pause doesn't solve your issue 
> > on
> > pl330. Do you want to move this to PIO mode then..?

The issue for which you requested the revert of pl330 pause

> I'm not sure what you think my issue is with the pl330, are you
> confusing me with Marek?  My position is that pause is unsupported by
> the pl330 at the hardware level.  Nothing the pl330.c driver or
> dmaengine api or 8250 serial driver does will change that.  That is
> why I sent a patch to remove pause support from pl330.c.  The rest is
> just trying to fix some bugs in mainline Linux I hit when I was a
> naive youngster who thought Linux support for the computer world's
> canonical serial uart could be counted on to move data from point A to
> point B.  In truth though, I've already concluded it's not worth it to
> slog though the linux kernel development process just to clean up
> other people's messes.  I've already fixed my issues out-of-tree.  I
> don't mind answering questions if anyone else cares about the issue
> though.  Other than that, I think I'll just be ghosting out now.

~Vinod


Re: Revert "dmaengine: pl330: add DMA_PAUSE feature"

2018-05-22 Thread Vinod
On 22-05-18, 10:27, Frank Mori Hess wrote:
> On Mon, May 21, 2018 at 11:37 PM, Vinod Koul  wrote:
> >
> > Well looks like even adding support for sync_pause doesn't solve your issue 
> > on
> > pl330. Do you want to move this to PIO mode then..?

The issue for which you requested the revert of pl330 pause

> I'm not sure what you think my issue is with the pl330, are you
> confusing me with Marek?  My position is that pause is unsupported by
> the pl330 at the hardware level.  Nothing the pl330.c driver or
> dmaengine api or 8250 serial driver does will change that.  That is
> why I sent a patch to remove pause support from pl330.c.  The rest is
> just trying to fix some bugs in mainline Linux I hit when I was a
> naive youngster who thought Linux support for the computer world's
> canonical serial uart could be counted on to move data from point A to
> point B.  In truth though, I've already concluded it's not worth it to
> slog though the linux kernel development process just to clean up
> other people's messes.  I've already fixed my issues out-of-tree.  I
> don't mind answering questions if anyone else cares about the issue
> though.  Other than that, I think I'll just be ghosting out now.

~Vinod


Re: [PATCH 3/4] venus: add check to make scm calls

2018-05-22 Thread Vikash Garodia

Hi Stan,

On 2018-05-23 02:27, Stanimir Varbanov wrote:

Hi Jordan,

On 22.05.2018 22:50, Jordan Crouse wrote:

On Tue, May 22, 2018 at 04:04:51PM +0300, Stanimir Varbanov wrote:

Hi Vikash,

On 05/17/2018 02:32 PM, Vikash Garodia wrote:

In order to invoke scm calls, ensure that the platform
has the required support to invoke the scm calls in
secure world. This code is in preparation to add PIL
functionality in venus driver.

Signed-off-by: Vikash Garodia 
---
  drivers/media/platform/qcom/venus/hfi_venus.c | 26 
+++---

  1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c

index f61d34b..9bcce94 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -27,6 +27,7 @@
  #include "hfi_msgs.h"
  #include "hfi_venus.h"
  #include "hfi_venus_io.h"
+#include "firmware.h"
#define HFI_MASK_QHDR_TX_TYPE   0xff00
  #define HFI_MASK_QHDR_RX_TYPE 0x00ff
@@ -570,13 +571,19 @@ static int venus_halt_axi(struct 
venus_hfi_device *hdev)

  static int venus_power_off(struct venus_hfi_device *hdev)
  {
int ret;
+   void __iomem *reg_base;
if (!hdev->power_enabled)
return 0;
  - ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
-   if (ret)
-   return ret;
+   if (qcom_scm_is_available()) {
+   ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);


I think it will be clearer if we abstract qcom_scm_set_remote_state 
to
something like venus_set_state(SUSPEND|RESUME) in firmware.c and 
export

the functions to be used here.


This specific function is a little odd because the SCM function got 
overloaded

and used as a hardware workaround for the adreno a5xx zap shader.

When we added it for the GPU we knew the day would come that we would 
need it
for Venus so we kept the name purposely generic. You can wrap if if 
you want
but just know that there are other non video entities out there using 
it.


Sorry I wasn't clear, by abstract it I meant to introduce a new
venus_set_state function in venus/firmware.c where we'll select
tz/non-tz functions for suspend / resume depending on the
configuration.


Yes, that's a good idea to abstract the decision to use tz or non-tz way 
as much

as possible to firmware.c. Will add this in my next patch.


regards,
Stan


Re: [PATCH 3/4] venus: add check to make scm calls

2018-05-22 Thread Vikash Garodia

Hi Stan,

On 2018-05-23 02:27, Stanimir Varbanov wrote:

Hi Jordan,

On 22.05.2018 22:50, Jordan Crouse wrote:

On Tue, May 22, 2018 at 04:04:51PM +0300, Stanimir Varbanov wrote:

Hi Vikash,

On 05/17/2018 02:32 PM, Vikash Garodia wrote:

In order to invoke scm calls, ensure that the platform
has the required support to invoke the scm calls in
secure world. This code is in preparation to add PIL
functionality in venus driver.

Signed-off-by: Vikash Garodia 
---
  drivers/media/platform/qcom/venus/hfi_venus.c | 26 
+++---

  1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c

index f61d34b..9bcce94 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -27,6 +27,7 @@
  #include "hfi_msgs.h"
  #include "hfi_venus.h"
  #include "hfi_venus_io.h"
+#include "firmware.h"
#define HFI_MASK_QHDR_TX_TYPE   0xff00
  #define HFI_MASK_QHDR_RX_TYPE 0x00ff
@@ -570,13 +571,19 @@ static int venus_halt_axi(struct 
venus_hfi_device *hdev)

  static int venus_power_off(struct venus_hfi_device *hdev)
  {
int ret;
+   void __iomem *reg_base;
if (!hdev->power_enabled)
return 0;
  - ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
-   if (ret)
-   return ret;
+   if (qcom_scm_is_available()) {
+   ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);


I think it will be clearer if we abstract qcom_scm_set_remote_state 
to
something like venus_set_state(SUSPEND|RESUME) in firmware.c and 
export

the functions to be used here.


This specific function is a little odd because the SCM function got 
overloaded

and used as a hardware workaround for the adreno a5xx zap shader.

When we added it for the GPU we knew the day would come that we would 
need it
for Venus so we kept the name purposely generic. You can wrap if if 
you want
but just know that there are other non video entities out there using 
it.


Sorry I wasn't clear, by abstract it I meant to introduce a new
venus_set_state function in venus/firmware.c where we'll select
tz/non-tz functions for suspend / resume depending on the
configuration.


Yes, that's a good idea to abstract the decision to use tz or non-tz way 
as much

as possible to firmware.c. Will add this in my next patch.


regards,
Stan


[PATCH 3/6] media: staging: atomisp: Remove useless "ifndef ISP2401"

2018-05-22 Thread Pankaj Bharadiya
In atomisp_csi2_set_ffmt(), there is no reason to have
"#ifndef ISP2401" condition since code is identical in ifndef and
else sections. Hence remove redudent checks.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
index fa03b78..606ebdb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
@@ -90,11 +90,7 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd,
 {
struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd);
struct v4l2_mbus_framefmt *actual_ffmt =
-#ifndef ISP2401
__csi2_get_format(csi2, cfg, which, pad);
-#else
-   __csi2_get_format(csi2, cfg, which, pad);
-#endif
 
if (pad == CSI2_PAD_SINK) {
const struct atomisp_in_fmt_conv *ic;
@@ -121,11 +117,7 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd,
 
/* FIXME: DPCM decompression */
*actual_ffmt = *ffmt =
-#ifndef ISP2401
*__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK);
-#else
-   *__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK);
-#endif
 
return 0;
 }
-- 
2.7.4



[PATCH 3/6] media: staging: atomisp: Remove useless "ifndef ISP2401"

2018-05-22 Thread Pankaj Bharadiya
In atomisp_csi2_set_ffmt(), there is no reason to have
"#ifndef ISP2401" condition since code is identical in ifndef and
else sections. Hence remove redudent checks.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
index fa03b78..606ebdb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c
@@ -90,11 +90,7 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd,
 {
struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd);
struct v4l2_mbus_framefmt *actual_ffmt =
-#ifndef ISP2401
__csi2_get_format(csi2, cfg, which, pad);
-#else
-   __csi2_get_format(csi2, cfg, which, pad);
-#endif
 
if (pad == CSI2_PAD_SINK) {
const struct atomisp_in_fmt_conv *ic;
@@ -121,11 +117,7 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd,
 
/* FIXME: DPCM decompression */
*actual_ffmt = *ffmt =
-#ifndef ISP2401
*__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK);
-#else
-   *__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK);
-#endif
 
return 0;
 }
-- 
2.7.4



[PATCH 1/6] media: staging: atomisp: remove redundent check

2018-05-22 Thread Pankaj Bharadiya
Assignment asd = >asd[i] can never be null hence remove
redundent check.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
index f668c68..7a9f3c9 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
@@ -4592,8 +4592,6 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
 * delete wdt timer. */
for (i = 0; i < isp->num_of_streams; i++) {
asd = >asd[i];
-   if (!asd)
-   continue;
if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
continue;
if (!atomisp_buffers_queued(asd))
-- 
2.7.4



[PATCH 1/6] media: staging: atomisp: remove redundent check

2018-05-22 Thread Pankaj Bharadiya
Assignment asd = >asd[i] can never be null hence remove
redundent check.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
index f668c68..7a9f3c9 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c
@@ -4592,8 +4592,6 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
 * delete wdt timer. */
for (i = 0; i < isp->num_of_streams; i++) {
asd = >asd[i];
-   if (!asd)
-   continue;
if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
continue;
if (!atomisp_buffers_queued(asd))
-- 
2.7.4



[PATCH 5/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In sh_css_config_input_network(), "stream" is being dereferenced
before it is null checked.
Fix it by moving the "stream" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
index c771e4b..eb84d51 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
@@ -529,11 +529,12 @@ static enum ia_css_err
 sh_css_config_input_network(struct ia_css_stream *stream)
 {
unsigned int fmt_type;
-   struct ia_css_pipe *pipe = stream->last_pipe;
+   struct ia_css_pipe *pipe;
struct ia_css_binary *binary = NULL;
enum ia_css_err err = IA_CSS_SUCCESS;
 
assert(stream != NULL);
+   pipe = stream->last_pipe;
assert(pipe != NULL);
 
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
-- 
2.7.4



[PATCH 6/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In verify_copy_out_frame_format(), "pipe" is being dereferenced before
it is null checked.
Fix it by moving the "pipe" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
index eb84d51..487e768 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
@@ -455,12 +455,14 @@ static enum ia_css_frame_format yuv422_copy_formats[] = {
 static enum ia_css_err
 verify_copy_out_frame_format(struct ia_css_pipe *pipe)
 {
-   enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
+   enum ia_css_frame_format out_fmt;
unsigned int i, found = 0;
 
assert(pipe != NULL);
assert(pipe->stream != NULL);
 
+   out_fmt = pipe->output_info[0].format;
+
switch (pipe->stream->config.input_config.format) {
case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
case ATOMISP_INPUT_FORMAT_YUV420_8:
-- 
2.7.4



[PATCH 5/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In sh_css_config_input_network(), "stream" is being dereferenced
before it is null checked.
Fix it by moving the "stream" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
index c771e4b..eb84d51 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
@@ -529,11 +529,12 @@ static enum ia_css_err
 sh_css_config_input_network(struct ia_css_stream *stream)
 {
unsigned int fmt_type;
-   struct ia_css_pipe *pipe = stream->last_pipe;
+   struct ia_css_pipe *pipe;
struct ia_css_binary *binary = NULL;
enum ia_css_err err = IA_CSS_SUCCESS;
 
assert(stream != NULL);
+   pipe = stream->last_pipe;
assert(pipe != NULL);
 
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
-- 
2.7.4



[PATCH 6/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In verify_copy_out_frame_format(), "pipe" is being dereferenced before
it is null checked.
Fix it by moving the "pipe" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
index eb84d51..487e768 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c
@@ -455,12 +455,14 @@ static enum ia_css_frame_format yuv422_copy_formats[] = {
 static enum ia_css_err
 verify_copy_out_frame_format(struct ia_css_pipe *pipe)
 {
-   enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
+   enum ia_css_frame_format out_fmt;
unsigned int i, found = 0;
 
assert(pipe != NULL);
assert(pipe->stream != NULL);
 
+   out_fmt = pipe->output_info[0].format;
+
switch (pipe->stream->config.input_config.format) {
case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
case ATOMISP_INPUT_FORMAT_YUV420_8:
-- 
2.7.4



[PATCH 4/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In ia_css_pipe_get_primary_binarydesc(), "pipe" is being dereferenced
before it is null checked.
Fix it by moving the "pipe" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 .../atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git 
a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
index 98a2a3e..ca86157 100644
--- 
a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
+++ 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
@@ -554,7 +554,7 @@ void ia_css_pipe_get_primary_binarydesc(
struct ia_css_frame_info *vf_info,
unsigned int stage_idx)
 {
-   enum ia_css_pipe_version pipe_version = pipe->config.isp_pipe_version;
+   enum ia_css_pipe_version pipe_version;
int mode;
unsigned int i;
struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
@@ -567,6 +567,7 @@ void ia_css_pipe_get_primary_binarydesc(
/*assert(vf_info != NULL);*/
IA_CSS_ENTER_PRIVATE("");
 
+   pipe_version = pipe->config.isp_pipe_version;
if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
mode = primary_hq_binary_modes[stage_idx];
else
-- 
2.7.4



[PATCH 4/6] media: staging: atomisp: Fix potential NULL pointer dereference

2018-05-22 Thread Pankaj Bharadiya
In ia_css_pipe_get_primary_binarydesc(), "pipe" is being dereferenced
before it is null checked.
Fix it by moving the "pipe" pointer dereference after it has been
properly null checked.

Signed-off-by: Pankaj Bharadiya 
---
 .../atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git 
a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
index 98a2a3e..ca86157 100644
--- 
a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
+++ 
b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c
@@ -554,7 +554,7 @@ void ia_css_pipe_get_primary_binarydesc(
struct ia_css_frame_info *vf_info,
unsigned int stage_idx)
 {
-   enum ia_css_pipe_version pipe_version = pipe->config.isp_pipe_version;
+   enum ia_css_pipe_version pipe_version;
int mode;
unsigned int i;
struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
@@ -567,6 +567,7 @@ void ia_css_pipe_get_primary_binarydesc(
/*assert(vf_info != NULL);*/
IA_CSS_ENTER_PRIVATE("");
 
+   pipe_version = pipe->config.isp_pipe_version;
if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
mode = primary_hq_binary_modes[stage_idx];
else
-- 
2.7.4



[PATCH 2/6] media: staging: atomisp: Remove useless if statement

2018-05-22 Thread Pankaj Bharadiya
Local variable "requeue" is assigned only once to a constant "false"
value so "if(requeue)" condition will never be true.
Thus remove it.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
index fa6ea50..c8c4d1d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
@@ -883,7 +883,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int 
error,
struct videobuf_buffer *vb = NULL;
struct atomisp_video_pipe *pipe = NULL;
struct atomisp_css_buffer buffer;
-   bool requeue = false;
int err;
unsigned long irqflags;
struct atomisp_css_frame *frame = NULL;
@@ -1223,19 +1222,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, 
int error,
 #ifdef ISP2401
atomic_set(>wdt_count, 0);
 #endif
-   /*
-* Requeue should only be done for 3a and dis buffers.
-* Queue/dequeue order will change if driver recycles image buffers.
-*/
-   if (requeue) {
-   err = atomisp_css_queue_buffer(asd,
-  stream_id, css_pipe_id,
-  buf_type, );
-   if (err)
-   dev_err(isp->dev, "%s, q to css fails: %d\n",
-   __func__, err);
-   return;
-   }
if (!error && q_buffers)
atomisp_qbuffers_to_css(asd);
 #ifdef ISP2401
-- 
2.7.4



[PATCH 2/6] media: staging: atomisp: Remove useless if statement

2018-05-22 Thread Pankaj Bharadiya
Local variable "requeue" is assigned only once to a constant "false"
value so "if(requeue)" condition will never be true.
Thus remove it.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
index fa6ea50..c8c4d1d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c
@@ -883,7 +883,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int 
error,
struct videobuf_buffer *vb = NULL;
struct atomisp_video_pipe *pipe = NULL;
struct atomisp_css_buffer buffer;
-   bool requeue = false;
int err;
unsigned long irqflags;
struct atomisp_css_frame *frame = NULL;
@@ -1223,19 +1222,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, 
int error,
 #ifdef ISP2401
atomic_set(>wdt_count, 0);
 #endif
-   /*
-* Requeue should only be done for 3a and dis buffers.
-* Queue/dequeue order will change if driver recycles image buffers.
-*/
-   if (requeue) {
-   err = atomisp_css_queue_buffer(asd,
-  stream_id, css_pipe_id,
-  buf_type, );
-   if (err)
-   dev_err(isp->dev, "%s, q to css fails: %d\n",
-   __func__, err);
-   return;
-   }
if (!error && q_buffers)
atomisp_qbuffers_to_css(asd);
 #ifdef ISP2401
-- 
2.7.4



[PATCH 0/6] Fix issues reported by static analysis tool.

2018-05-22 Thread Pankaj Bharadiya
This patch series fixes some of the issues reported by static analysis
tool.

Pankaj Bharadiya (6):
  media: staging: atomisp: remove redundent check
  media: staging: atomisp: Remove useless if statement
  media: staging: atomisp: Remove useless "ifndef ISP2401"
  media: staging: atomisp: Fix potential NULL pointer dereference
  media: staging: atomisp: Fix potential NULL pointer dereference
  media: staging: atomisp: Fix potential NULL pointer dereference

 drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c   | 14 --
 .../media/atomisp/pci/atomisp2/atomisp_compat_css20.c  |  2 --
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c  |  8 
 .../pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c |  3 ++-
 .../staging/media/atomisp/pci/atomisp2/css2400/sh_css.c|  7 +--
 5 files changed, 7 insertions(+), 27 deletions(-)

-- 
2.7.4



[PATCH 0/6] Fix issues reported by static analysis tool.

2018-05-22 Thread Pankaj Bharadiya
This patch series fixes some of the issues reported by static analysis
tool.

Pankaj Bharadiya (6):
  media: staging: atomisp: remove redundent check
  media: staging: atomisp: Remove useless if statement
  media: staging: atomisp: Remove useless "ifndef ISP2401"
  media: staging: atomisp: Fix potential NULL pointer dereference
  media: staging: atomisp: Fix potential NULL pointer dereference
  media: staging: atomisp: Fix potential NULL pointer dereference

 drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c   | 14 --
 .../media/atomisp/pci/atomisp2/atomisp_compat_css20.c  |  2 --
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c  |  8 
 .../pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c |  3 ++-
 .../staging/media/atomisp/pci/atomisp2/css2400/sh_css.c|  7 +--
 5 files changed, 7 insertions(+), 27 deletions(-)

-- 
2.7.4



Re: [PATCH v2 2/4] drm/mediatek: Add support for mediatek SOC MT2712

2018-05-22 Thread CK Hu
Hi, Stu:

I've some inline comment.

On Wed, 2018-05-23 at 10:25 +0800, Stu Hsieh wrote:
> This patch add support for the Mediatek MT2712 DISP subsystem.
> There are two OVL engine and three disp output in MT2712.
> 
> Signed-off-by: Stu Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 50 
> +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  8 +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  7 ++--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 47 +--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  7 ++--
>  5 files changed, 108 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index 8130f3dab661..e563dedd1999 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -29,6 +29,8 @@
>  #define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN   0x084
>  #define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN   0x088
>  #define DISP_REG_CONFIG_DPI_SEL_IN   0x0ac
> +#define DISP_REG_CONFIG_DISP_RDMA2_SOUT  0x0b8
> +#define DISP_REG_CONFIG_DISP_RDMA0_MOUT_EN   0x0c4

These two definition are useless, so remove it.

>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN   0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON00x100
>  
> @@ -41,6 +43,7 @@
>  #define DISP_REG_MUTEX_RST(n)(0x28 + 0x20 * (n))
>  #define DISP_REG_MUTEX_MOD(n)(0x2c + 0x20 * (n))
>  #define DISP_REG_MUTEX_SOF(n)(0x30 + 0x20 * (n))
> +#define DISP_REG_MUTEX_MOD2(n)   (0x34 + 0x20 * (n))

Move this to the patch 'drm/mediatek: support maximum 64 mutex mod' and
that patch should be applied before this patch.

>  
>  #define INT_MUTEXBIT(1)
>  
> @@ -60,6 +63,25 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2712_MUTEX_MOD_DISP_OVL0   BIT(11)
> +#define MT2712_MUTEX_MOD_DISP_OVL1   BIT(12)
> +#define MT2712_MUTEX_MOD_DISP_RDMA0  BIT(13)
> +#define MT2712_MUTEX_MOD_DISP_RDMA1  BIT(14)
> +#define MT2712_MUTEX_MOD_DISP_RDMA2  BIT(15)
> +#define MT2712_MUTEX_MOD_DISP_WDMA0  BIT(16)
> +#define MT2712_MUTEX_MOD_DISP_WDMA1  BIT(17)
> +#define MT2712_MUTEX_MOD_DISP_COLOR0 BIT(18)
> +#define MT2712_MUTEX_MOD_DISP_COLOR1 BIT(19)
> +#define MT2712_MUTEX_MOD_DISP_AAL0   BIT(20)
> +#define MT2712_MUTEX_MOD_DISP_UFOE   BIT(22)
> +#define MT2712_MUTEX_MOD_DISP_PWM0   BIT(23)
> +#define MT2712_MUTEX_MOD_DISP_PWM1   BIT(24)
> +#define MT2712_MUTEX_MOD_DISP_PWM2   BIT(10)
> +#define MT2712_MUTEX_MOD_DISP_OD0BIT(25)
> +/* modules more than 32, add BIT(31) when using DISP_REG_MUTEX_MOD2 bit */
> +#define MT2712_MUTEX_MOD2_DISP_AAL1  (BIT(1) | BIT(31))

I think a better definition is

#define MT2712_MUTEX_MOD2_DISP_AAL1 BIT(33)

when you need to access this register,

if (ddp->mutex_mod[id] < BIT(32)) {
offset = DISP_REG_MUTEX_MOD(mutex->id);
reg = readl_relaxed(ddp->regs + offset);
reg |= ddp->mutex_mod[id];
writel_relaxed(reg, ddp->regs + offset);
} else {
offset = DISP_REG_MUTEX_MOD2(mutex->id);
reg = readl_relaxed(ddp->regs + offset);
reg |= (ddp->mutex_mod[id] >> 32);
writel_relaxed(reg, ddp->regs + offset);
}

because DISP_REG_MUTEX_MOD BIT(31) could be used for some module.

> +#define MT2712_MUTEX_MOD2_DISP_OD1   (BIT(2) | BIT(31))
> +
>  #define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
>  #define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
>  #define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> @@ -74,6 +96,7 @@
>  
>  #define OVL0_MOUT_EN_COLOR0  0x1
>  #define OD_MOUT_EN_RDMA0 0x1
> +#define OD1_MOUT_EN_RDMA1BIT(16)
>  #define UFOE_MOUT_EN_DSI00x1
>  #define COLOR0_SEL_IN_OVL0   0x1
>  #define OVL1_MOUT_EN_COLOR1  0x1
> @@ -108,12 +131,32 @@ static const unsigned int 
> mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
>  };
>  
> +static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
> + [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
> + [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
> + [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
> + [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
> + [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
> + [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
> + [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
> + [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
> + [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
> + [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
> + 

Re: [PATCH v2 2/4] drm/mediatek: Add support for mediatek SOC MT2712

2018-05-22 Thread CK Hu
Hi, Stu:

I've some inline comment.

On Wed, 2018-05-23 at 10:25 +0800, Stu Hsieh wrote:
> This patch add support for the Mediatek MT2712 DISP subsystem.
> There are two OVL engine and three disp output in MT2712.
> 
> Signed-off-by: Stu Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 50 
> +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  8 +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  7 ++--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 47 +--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  7 ++--
>  5 files changed, 108 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index 8130f3dab661..e563dedd1999 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -29,6 +29,8 @@
>  #define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN   0x084
>  #define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN   0x088
>  #define DISP_REG_CONFIG_DPI_SEL_IN   0x0ac
> +#define DISP_REG_CONFIG_DISP_RDMA2_SOUT  0x0b8
> +#define DISP_REG_CONFIG_DISP_RDMA0_MOUT_EN   0x0c4

These two definition are useless, so remove it.

>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN   0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON00x100
>  
> @@ -41,6 +43,7 @@
>  #define DISP_REG_MUTEX_RST(n)(0x28 + 0x20 * (n))
>  #define DISP_REG_MUTEX_MOD(n)(0x2c + 0x20 * (n))
>  #define DISP_REG_MUTEX_SOF(n)(0x30 + 0x20 * (n))
> +#define DISP_REG_MUTEX_MOD2(n)   (0x34 + 0x20 * (n))

Move this to the patch 'drm/mediatek: support maximum 64 mutex mod' and
that patch should be applied before this patch.

>  
>  #define INT_MUTEXBIT(1)
>  
> @@ -60,6 +63,25 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2712_MUTEX_MOD_DISP_OVL0   BIT(11)
> +#define MT2712_MUTEX_MOD_DISP_OVL1   BIT(12)
> +#define MT2712_MUTEX_MOD_DISP_RDMA0  BIT(13)
> +#define MT2712_MUTEX_MOD_DISP_RDMA1  BIT(14)
> +#define MT2712_MUTEX_MOD_DISP_RDMA2  BIT(15)
> +#define MT2712_MUTEX_MOD_DISP_WDMA0  BIT(16)
> +#define MT2712_MUTEX_MOD_DISP_WDMA1  BIT(17)
> +#define MT2712_MUTEX_MOD_DISP_COLOR0 BIT(18)
> +#define MT2712_MUTEX_MOD_DISP_COLOR1 BIT(19)
> +#define MT2712_MUTEX_MOD_DISP_AAL0   BIT(20)
> +#define MT2712_MUTEX_MOD_DISP_UFOE   BIT(22)
> +#define MT2712_MUTEX_MOD_DISP_PWM0   BIT(23)
> +#define MT2712_MUTEX_MOD_DISP_PWM1   BIT(24)
> +#define MT2712_MUTEX_MOD_DISP_PWM2   BIT(10)
> +#define MT2712_MUTEX_MOD_DISP_OD0BIT(25)
> +/* modules more than 32, add BIT(31) when using DISP_REG_MUTEX_MOD2 bit */
> +#define MT2712_MUTEX_MOD2_DISP_AAL1  (BIT(1) | BIT(31))

I think a better definition is

#define MT2712_MUTEX_MOD2_DISP_AAL1 BIT(33)

when you need to access this register,

if (ddp->mutex_mod[id] < BIT(32)) {
offset = DISP_REG_MUTEX_MOD(mutex->id);
reg = readl_relaxed(ddp->regs + offset);
reg |= ddp->mutex_mod[id];
writel_relaxed(reg, ddp->regs + offset);
} else {
offset = DISP_REG_MUTEX_MOD2(mutex->id);
reg = readl_relaxed(ddp->regs + offset);
reg |= (ddp->mutex_mod[id] >> 32);
writel_relaxed(reg, ddp->regs + offset);
}

because DISP_REG_MUTEX_MOD BIT(31) could be used for some module.

> +#define MT2712_MUTEX_MOD2_DISP_OD1   (BIT(2) | BIT(31))
> +
>  #define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
>  #define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
>  #define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> @@ -74,6 +96,7 @@
>  
>  #define OVL0_MOUT_EN_COLOR0  0x1
>  #define OD_MOUT_EN_RDMA0 0x1
> +#define OD1_MOUT_EN_RDMA1BIT(16)
>  #define UFOE_MOUT_EN_DSI00x1
>  #define COLOR0_SEL_IN_OVL0   0x1
>  #define OVL1_MOUT_EN_COLOR1  0x1
> @@ -108,12 +131,32 @@ static const unsigned int 
> mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
>  };
>  
> +static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
> + [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
> + [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
> + [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
> + [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
> + [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
> + [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
> + [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
> + [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
> + [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
> + [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
> + [DDP_COMPONENT_RDMA0] = 

Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Gustavo A. R. Silva



On 05/23/2018 12:15 AM, Dan Williams wrote:


OK. How about this:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..498995b 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,21 @@ static inline unsigned long
array_index_mask_nospec(unsigned long index,
\
 (typeof(_i)) (_i & _mask); \
  })
+
+#define validate_index_nospec(index, size)\
+({\
+   bool ret = true;   \
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   if (*ptr >= size)  \


I'll change the line above by this one:

if (*ptr >= _s)


+   ret = false;   \
+  \
+   *ptr = array_index_nospec(*ptr, _s);   \
+  \
+   ret;   \

+})
  #endif /* _LINUX_NOSPEC_H */


Assuming the assembly generation is comparable with the open coded
version, this looks ok to me.



OK. I'll send a proper patch tomorrow morning.

Thanks for the feedback, Dan.
--
Gustavo


Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Gustavo A. R. Silva



On 05/23/2018 12:15 AM, Dan Williams wrote:


OK. How about this:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..498995b 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,21 @@ static inline unsigned long
array_index_mask_nospec(unsigned long index,
\
 (typeof(_i)) (_i & _mask); \
  })
+
+#define validate_index_nospec(index, size)\
+({\
+   bool ret = true;   \
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   if (*ptr >= size)  \


I'll change the line above by this one:

if (*ptr >= _s)


+   ret = false;   \
+  \
+   *ptr = array_index_nospec(*ptr, _s);   \
+  \
+   ret;   \

+})
  #endif /* _LINUX_NOSPEC_H */


Assuming the assembly generation is comparable with the open coded
version, this looks ok to me.



OK. I'll send a proper patch tomorrow morning.

Thanks for the feedback, Dan.
--
Gustavo


[PATCH v2 4/7] mm, devm_memremap_pages: Add MEMORY_DEVICE_PRIVATE support

2018-05-22 Thread Dan Williams
In preparation for consolidating all ZONE_DEVICE enabling via
devm_memremap_pages(), teach it how to handle the constraints of
MEMORY_DEVICE_PRIVATE ranges.

Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Reported-by: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |   38 --
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index dfec0801f652..89eed25e2a80 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -303,8 +303,13 @@ static void devm_memremap_pages_release(void *data)
- align_start;
 
mem_hotplug_begin();
-   arch_remove_memory(align_start, align_size, pgmap->altmap_valid ?
-   >altmap : NULL);
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   pfn = align_start >> PAGE_SHIFT;
+   __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
+   align_size >> PAGE_SHIFT, NULL);
+   } else
+   arch_remove_memory(align_start, align_size,
+   pgmap->altmap_valid ? >altmap : NULL);
mem_hotplug_done();
 
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
@@ -388,11 +393,32 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap,
goto err_pfn_remap;
 
mem_hotplug_begin();
-   error = arch_add_memory(nid, align_start, align_size, altmap, false);
-   if (!error)
-   move_pfn_range_to_zone(_DATA(nid)->node_zones[ZONE_DEVICE],
-   align_start >> PAGE_SHIFT,
+
+   /*
+* For device private memory we call add_pages() as we only need to
+* allocate and initialize struct page for the device memory. More-
+* over the device memory is un-accessible thus we do not want to
+* create a linear mapping for the memory like arch_add_memory()
+* would do.
+*
+* For all other device memory types, which are accessible by
+* the CPU, we do want the linear mapping and thus use
+* arch_add_memory().
+*/
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   error = add_pages(nid, align_start >> PAGE_SHIFT,
+   align_size >> PAGE_SHIFT, NULL, false);
+   } else {
+   struct zone *zone;
+
+   error = arch_add_memory(nid, align_start, align_size, altmap,
+   false);
+   zone = _DATA(nid)->node_zones[ZONE_DEVICE];
+   if (!error)
+   move_pfn_range_to_zone(zone, align_start >> PAGE_SHIFT,
align_size >> PAGE_SHIFT, altmap);
+   }
+
mem_hotplug_done();
if (error)
goto err_add_memory;



[PATCH v2 4/7] mm, devm_memremap_pages: Add MEMORY_DEVICE_PRIVATE support

2018-05-22 Thread Dan Williams
In preparation for consolidating all ZONE_DEVICE enabling via
devm_memremap_pages(), teach it how to handle the constraints of
MEMORY_DEVICE_PRIVATE ranges.

Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Reported-by: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |   38 --
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index dfec0801f652..89eed25e2a80 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -303,8 +303,13 @@ static void devm_memremap_pages_release(void *data)
- align_start;
 
mem_hotplug_begin();
-   arch_remove_memory(align_start, align_size, pgmap->altmap_valid ?
-   >altmap : NULL);
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   pfn = align_start >> PAGE_SHIFT;
+   __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
+   align_size >> PAGE_SHIFT, NULL);
+   } else
+   arch_remove_memory(align_start, align_size,
+   pgmap->altmap_valid ? >altmap : NULL);
mem_hotplug_done();
 
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
@@ -388,11 +393,32 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap,
goto err_pfn_remap;
 
mem_hotplug_begin();
-   error = arch_add_memory(nid, align_start, align_size, altmap, false);
-   if (!error)
-   move_pfn_range_to_zone(_DATA(nid)->node_zones[ZONE_DEVICE],
-   align_start >> PAGE_SHIFT,
+
+   /*
+* For device private memory we call add_pages() as we only need to
+* allocate and initialize struct page for the device memory. More-
+* over the device memory is un-accessible thus we do not want to
+* create a linear mapping for the memory like arch_add_memory()
+* would do.
+*
+* For all other device memory types, which are accessible by
+* the CPU, we do want the linear mapping and thus use
+* arch_add_memory().
+*/
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   error = add_pages(nid, align_start >> PAGE_SHIFT,
+   align_size >> PAGE_SHIFT, NULL, false);
+   } else {
+   struct zone *zone;
+
+   error = arch_add_memory(nid, align_start, align_size, altmap,
+   false);
+   zone = _DATA(nid)->node_zones[ZONE_DEVICE];
+   if (!error)
+   move_pfn_range_to_zone(zone, align_start >> PAGE_SHIFT,
align_size >> PAGE_SHIFT, altmap);
+   }
+
mem_hotplug_done();
if (error)
goto err_add_memory;



[PATCH v2 6/7] mm, hmm: Replace hmm_devmem_pages_create() with devm_memremap_pages()

2018-05-22 Thread Dan Williams
Commit e8d513483300 "memremap: change devm_memremap_pages interface to
use struct dev_pagemap" refactored devm_memremap_pages() to allow a
dev_pagemap instance to be supplied. Passing in a dev_pagemap interface
simplifies the design of pgmap type drivers in that they can rely on
container_of() to lookup any private data associated with the given
dev_pagemap instance.

In addition to the cleanups this also gives hmm users multi-order-radix
improvements that arrived with commit ab1b597ee0e4 "mm,
devm_memremap_pages: use multi-order radix for ZONE_DEVICE lookups"

As part of the conversion to the devm_memremap_pages() method of
handling the percpu_ref relative to when pages are put, the percpu_ref
completion needs to move to hmm_devmem_ref_exit(). See commit
71389703839e ("mm, zone_device: Replace {get, put}_zone_device_page...")
for details.

Reviewed-by: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 mm/hmm.c |  198 --
 1 file changed, 26 insertions(+), 172 deletions(-)

diff --git a/mm/hmm.c b/mm/hmm.c
index d081857f29b5..5723331f6910 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -927,7 +927,6 @@ struct page *hmm_vma_alloc_locked_page(struct 
vm_area_struct *vma,
 }
 EXPORT_SYMBOL(hmm_vma_alloc_locked_page);
 
-
 static void hmm_devmem_ref_release(struct percpu_ref *ref)
 {
struct hmm_devmem *devmem;
@@ -942,17 +941,16 @@ static void hmm_devmem_ref_exit(void *data)
struct hmm_devmem *devmem;
 
devmem = container_of(ref, struct hmm_devmem, ref);
+   wait_for_completion(>completion);
percpu_ref_exit(ref);
 }
 
-static void hmm_devmem_ref_kill(void *data)
+static void hmm_devmem_ref_kill(struct percpu_ref *ref)
 {
-   struct percpu_ref *ref = data;
struct hmm_devmem *devmem;
 
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_kill(ref);
-   wait_for_completion(>completion);
 }
 
 static int hmm_devmem_fault(struct vm_area_struct *vma,
@@ -973,155 +971,6 @@ static void hmm_devmem_free(struct page *page, void *data)
devmem->ops->free(devmem, page);
 }
 
-static DEFINE_MUTEX(hmm_devmem_lock);
-static RADIX_TREE(hmm_devmem_radix, GFP_KERNEL);
-
-static void hmm_devmem_radix_release(struct resource *resource)
-{
-   resource_size_t key, align_start, align_size;
-
-   align_start = resource->start & ~(PA_SECTION_SIZE - 1);
-   align_size = ALIGN(resource_size(resource), PA_SECTION_SIZE);
-
-   mutex_lock(_devmem_lock);
-   for (key = resource->start;
-key <= resource->end;
-key += PA_SECTION_SIZE)
-   radix_tree_delete(_devmem_radix, key >> PA_SECTION_SHIFT);
-   mutex_unlock(_devmem_lock);
-}
-
-static void hmm_devmem_release(void *data)
-{
-   struct hmm_devmem *devmem = data;
-   struct resource *resource = devmem->resource;
-   unsigned long start_pfn, npages;
-   struct zone *zone;
-   struct page *page;
-
-   /* pages are dead and unused, undo the arch mapping */
-   start_pfn = (resource->start & ~(PA_SECTION_SIZE - 1)) >> PAGE_SHIFT;
-   npages = ALIGN(resource_size(resource), PA_SECTION_SIZE) >> PAGE_SHIFT;
-
-   page = pfn_to_page(start_pfn);
-   zone = page_zone(page);
-
-   mem_hotplug_begin();
-   if (resource->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY)
-   __remove_pages(zone, start_pfn, npages, NULL);
-   else
-   arch_remove_memory(start_pfn << PAGE_SHIFT,
-  npages << PAGE_SHIFT, NULL);
-   mem_hotplug_done();
-
-   hmm_devmem_radix_release(resource);
-}
-
-static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
-{
-   resource_size_t key, align_start, align_size, align_end;
-   struct device *device = devmem->device;
-   int ret, nid, is_ram;
-   unsigned long pfn;
-
-   align_start = devmem->resource->start & ~(PA_SECTION_SIZE - 1);
-   align_size = ALIGN(devmem->resource->start +
-  resource_size(devmem->resource),
-  PA_SECTION_SIZE) - align_start;
-
-   is_ram = region_intersects(align_start, align_size,
-  IORESOURCE_SYSTEM_RAM,
-  IORES_DESC_NONE);
-   if (is_ram == REGION_MIXED) {
-   WARN_ONCE(1, "%s attempted on mixed region %pr\n",
-   __func__, devmem->resource);
-   return -ENXIO;
-   }
-   if (is_ram == REGION_INTERSECTS)
-   return -ENXIO;
-
-   if (devmem->resource->desc == IORES_DESC_DEVICE_PUBLIC_MEMORY)
-   devmem->pagemap.type = MEMORY_DEVICE_PUBLIC;
-   else
-   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
-
-   devmem->pagemap.res = *devmem->resource;
-   

[PATCH v2 6/7] mm, hmm: Replace hmm_devmem_pages_create() with devm_memremap_pages()

2018-05-22 Thread Dan Williams
Commit e8d513483300 "memremap: change devm_memremap_pages interface to
use struct dev_pagemap" refactored devm_memremap_pages() to allow a
dev_pagemap instance to be supplied. Passing in a dev_pagemap interface
simplifies the design of pgmap type drivers in that they can rely on
container_of() to lookup any private data associated with the given
dev_pagemap instance.

In addition to the cleanups this also gives hmm users multi-order-radix
improvements that arrived with commit ab1b597ee0e4 "mm,
devm_memremap_pages: use multi-order radix for ZONE_DEVICE lookups"

As part of the conversion to the devm_memremap_pages() method of
handling the percpu_ref relative to when pages are put, the percpu_ref
completion needs to move to hmm_devmem_ref_exit(). See commit
71389703839e ("mm, zone_device: Replace {get, put}_zone_device_page...")
for details.

Reviewed-by: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 mm/hmm.c |  198 --
 1 file changed, 26 insertions(+), 172 deletions(-)

diff --git a/mm/hmm.c b/mm/hmm.c
index d081857f29b5..5723331f6910 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -927,7 +927,6 @@ struct page *hmm_vma_alloc_locked_page(struct 
vm_area_struct *vma,
 }
 EXPORT_SYMBOL(hmm_vma_alloc_locked_page);
 
-
 static void hmm_devmem_ref_release(struct percpu_ref *ref)
 {
struct hmm_devmem *devmem;
@@ -942,17 +941,16 @@ static void hmm_devmem_ref_exit(void *data)
struct hmm_devmem *devmem;
 
devmem = container_of(ref, struct hmm_devmem, ref);
+   wait_for_completion(>completion);
percpu_ref_exit(ref);
 }
 
-static void hmm_devmem_ref_kill(void *data)
+static void hmm_devmem_ref_kill(struct percpu_ref *ref)
 {
-   struct percpu_ref *ref = data;
struct hmm_devmem *devmem;
 
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_kill(ref);
-   wait_for_completion(>completion);
 }
 
 static int hmm_devmem_fault(struct vm_area_struct *vma,
@@ -973,155 +971,6 @@ static void hmm_devmem_free(struct page *page, void *data)
devmem->ops->free(devmem, page);
 }
 
-static DEFINE_MUTEX(hmm_devmem_lock);
-static RADIX_TREE(hmm_devmem_radix, GFP_KERNEL);
-
-static void hmm_devmem_radix_release(struct resource *resource)
-{
-   resource_size_t key, align_start, align_size;
-
-   align_start = resource->start & ~(PA_SECTION_SIZE - 1);
-   align_size = ALIGN(resource_size(resource), PA_SECTION_SIZE);
-
-   mutex_lock(_devmem_lock);
-   for (key = resource->start;
-key <= resource->end;
-key += PA_SECTION_SIZE)
-   radix_tree_delete(_devmem_radix, key >> PA_SECTION_SHIFT);
-   mutex_unlock(_devmem_lock);
-}
-
-static void hmm_devmem_release(void *data)
-{
-   struct hmm_devmem *devmem = data;
-   struct resource *resource = devmem->resource;
-   unsigned long start_pfn, npages;
-   struct zone *zone;
-   struct page *page;
-
-   /* pages are dead and unused, undo the arch mapping */
-   start_pfn = (resource->start & ~(PA_SECTION_SIZE - 1)) >> PAGE_SHIFT;
-   npages = ALIGN(resource_size(resource), PA_SECTION_SIZE) >> PAGE_SHIFT;
-
-   page = pfn_to_page(start_pfn);
-   zone = page_zone(page);
-
-   mem_hotplug_begin();
-   if (resource->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY)
-   __remove_pages(zone, start_pfn, npages, NULL);
-   else
-   arch_remove_memory(start_pfn << PAGE_SHIFT,
-  npages << PAGE_SHIFT, NULL);
-   mem_hotplug_done();
-
-   hmm_devmem_radix_release(resource);
-}
-
-static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
-{
-   resource_size_t key, align_start, align_size, align_end;
-   struct device *device = devmem->device;
-   int ret, nid, is_ram;
-   unsigned long pfn;
-
-   align_start = devmem->resource->start & ~(PA_SECTION_SIZE - 1);
-   align_size = ALIGN(devmem->resource->start +
-  resource_size(devmem->resource),
-  PA_SECTION_SIZE) - align_start;
-
-   is_ram = region_intersects(align_start, align_size,
-  IORESOURCE_SYSTEM_RAM,
-  IORES_DESC_NONE);
-   if (is_ram == REGION_MIXED) {
-   WARN_ONCE(1, "%s attempted on mixed region %pr\n",
-   __func__, devmem->resource);
-   return -ENXIO;
-   }
-   if (is_ram == REGION_INTERSECTS)
-   return -ENXIO;
-
-   if (devmem->resource->desc == IORES_DESC_DEVICE_PUBLIC_MEMORY)
-   devmem->pagemap.type = MEMORY_DEVICE_PUBLIC;
-   else
-   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
-
-   devmem->pagemap.res = *devmem->resource;
-   devmem->pagemap.page_fault = hmm_devmem_fault;
-   devmem->pagemap.page_free = hmm_devmem_free;
- 

[RFC PATCH 2/5] remoteproc: q6v5: Extract common resource handling

2018-05-22 Thread Bjorn Andersson
Shared between all Hexagon V5 based remoteprocs is the handling of the 5
interrupts and the SMP2P stop request, so break this out into a separate
function in order to allow these drivers to be cleaned up.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   5 +
 drivers/remoteproc/Makefile|   1 +
 drivers/remoteproc/qcom_q6v5.c | 243 +
 drivers/remoteproc/qcom_q6v5.h |  46 +++
 4 files changed, 295 insertions(+)
 create mode 100644 drivers/remoteproc/qcom_q6v5.c
 create mode 100644 drivers/remoteproc/qcom_q6v5.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index cd1c168fd188..63b79ea91a21 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -102,6 +102,11 @@ config QCOM_ADSP_PIL
 config QCOM_RPROC_COMMON
tristate
 
+config QCOM_Q6V5_COMMON
+   tristate
+   depends on ARCH_QCOM
+   depends on QCOM_SMEM
+
 config QCOM_Q6V5_PIL
tristate "Qualcomm Hexagon V5 Peripherial Image Loader"
depends on OF && ARCH_QCOM
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 02627ede8d4a..5dd0249cf76a 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)+= 
da8xx_remoteproc.o
 obj-$(CONFIG_KEYSTONE_REMOTEPROC)  += keystone_remoteproc.o
 obj-$(CONFIG_QCOM_ADSP_PIL)+= qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)+= qcom_common.o
+obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)+= qcom_q6v5_pil.o
 obj-$(CONFIG_QCOM_SYSMON)  += qcom_sysmon.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)   += qcom_wcnss_pil.o
diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c
new file mode 100644
index ..9076537a1671
--- /dev/null
+++ b/drivers/remoteproc/qcom_q6v5.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm Peripheral Image Loader for Q6V5 WCSS
+ *
+ * Copyright (C) 2016-2018 Linaro Ltd.
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qcom_q6v5.h"
+
+/**
+ * qcom_q6v5_prepare() - reinitialize the qcom_q6v5 context before start
+ * @q6v5:  reference to qcom_q6v5 context to be reinitialized
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int qcom_q6v5_prepare(struct qcom_q6v5 *q6v5)
+{
+   reinit_completion(>start_done);
+   reinit_completion(>stop_done);
+
+   q6v5->running = true;
+   q6v5->handover_issued = false;
+
+   enable_irq(q6v5->handover_irq);
+
+   return 0;
+}
+
+/**
+ * qcom_q6v5_unprepare() - unprepare the qcom_q6v5 context after stop
+ * @q6v5:  reference to qcom_q6v5 context to be unprepared
+ *
+ * Return: 0 on success, 1 if handover hasn't yet been called
+ */
+int qcom_q6v5_unprepare(struct qcom_q6v5 *q6v5)
+{
+   disable_irq(q6v5->handover_irq);
+
+   return !q6v5->handover_issued;
+}
+
+static irqreturn_t q6v5_wdog_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+   size_t len;
+   char *msg;
+
+   /* Sometimes the stop triggers a watchdog rather than a stop-ack */
+   if (!q6v5->running) {
+   complete(>stop_done);
+   return IRQ_HANDLED;
+   }
+
+   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, );
+   if (!IS_ERR(msg) && len > 0 && msg[0])
+   dev_err(q6v5->dev, "watchdog received: %s\n", msg);
+   else
+   dev_err(q6v5->dev, "watchdog without message\n");
+
+   rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
+
+   return IRQ_HANDLED;
+}
+
+static irqreturn_t q6v5_fatal_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+   size_t len;
+   char *msg;
+
+   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, );
+   if (!IS_ERR(msg) && len > 0 && msg[0])
+   dev_err(q6v5->dev, "fatal error received: %s\n", msg);
+   else
+   dev_err(q6v5->dev, "fatal error without message\n");
+
+   rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
+
+   return IRQ_HANDLED;
+}
+
+static irqreturn_t q6v5_ready_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+
+   complete(>start_done);
+
+   return IRQ_HANDLED;
+}
+
+/**
+ * qcom_q6v5_wait_for_start() - wait for remote processor start signal
+ * @q6v5:  reference to qcom_q6v5 context
+ * @timeout:   timeout to wait for the event, in jiffies
+ *
+ * qcom_q6v5_unprepare() should not be called when this function fails.
+ *
+ * Return: 0 on success, -ETIMEDOUT on timeout
+ */
+int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout)
+{
+   int ret;
+
+   ret = 

[RFC PATCH 2/5] remoteproc: q6v5: Extract common resource handling

2018-05-22 Thread Bjorn Andersson
Shared between all Hexagon V5 based remoteprocs is the handling of the 5
interrupts and the SMP2P stop request, so break this out into a separate
function in order to allow these drivers to be cleaned up.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   5 +
 drivers/remoteproc/Makefile|   1 +
 drivers/remoteproc/qcom_q6v5.c | 243 +
 drivers/remoteproc/qcom_q6v5.h |  46 +++
 4 files changed, 295 insertions(+)
 create mode 100644 drivers/remoteproc/qcom_q6v5.c
 create mode 100644 drivers/remoteproc/qcom_q6v5.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index cd1c168fd188..63b79ea91a21 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -102,6 +102,11 @@ config QCOM_ADSP_PIL
 config QCOM_RPROC_COMMON
tristate
 
+config QCOM_Q6V5_COMMON
+   tristate
+   depends on ARCH_QCOM
+   depends on QCOM_SMEM
+
 config QCOM_Q6V5_PIL
tristate "Qualcomm Hexagon V5 Peripherial Image Loader"
depends on OF && ARCH_QCOM
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 02627ede8d4a..5dd0249cf76a 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)+= 
da8xx_remoteproc.o
 obj-$(CONFIG_KEYSTONE_REMOTEPROC)  += keystone_remoteproc.o
 obj-$(CONFIG_QCOM_ADSP_PIL)+= qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)+= qcom_common.o
+obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)+= qcom_q6v5_pil.o
 obj-$(CONFIG_QCOM_SYSMON)  += qcom_sysmon.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)   += qcom_wcnss_pil.o
diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c
new file mode 100644
index ..9076537a1671
--- /dev/null
+++ b/drivers/remoteproc/qcom_q6v5.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm Peripheral Image Loader for Q6V5 WCSS
+ *
+ * Copyright (C) 2016-2018 Linaro Ltd.
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qcom_q6v5.h"
+
+/**
+ * qcom_q6v5_prepare() - reinitialize the qcom_q6v5 context before start
+ * @q6v5:  reference to qcom_q6v5 context to be reinitialized
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int qcom_q6v5_prepare(struct qcom_q6v5 *q6v5)
+{
+   reinit_completion(>start_done);
+   reinit_completion(>stop_done);
+
+   q6v5->running = true;
+   q6v5->handover_issued = false;
+
+   enable_irq(q6v5->handover_irq);
+
+   return 0;
+}
+
+/**
+ * qcom_q6v5_unprepare() - unprepare the qcom_q6v5 context after stop
+ * @q6v5:  reference to qcom_q6v5 context to be unprepared
+ *
+ * Return: 0 on success, 1 if handover hasn't yet been called
+ */
+int qcom_q6v5_unprepare(struct qcom_q6v5 *q6v5)
+{
+   disable_irq(q6v5->handover_irq);
+
+   return !q6v5->handover_issued;
+}
+
+static irqreturn_t q6v5_wdog_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+   size_t len;
+   char *msg;
+
+   /* Sometimes the stop triggers a watchdog rather than a stop-ack */
+   if (!q6v5->running) {
+   complete(>stop_done);
+   return IRQ_HANDLED;
+   }
+
+   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, );
+   if (!IS_ERR(msg) && len > 0 && msg[0])
+   dev_err(q6v5->dev, "watchdog received: %s\n", msg);
+   else
+   dev_err(q6v5->dev, "watchdog without message\n");
+
+   rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
+
+   return IRQ_HANDLED;
+}
+
+static irqreturn_t q6v5_fatal_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+   size_t len;
+   char *msg;
+
+   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, );
+   if (!IS_ERR(msg) && len > 0 && msg[0])
+   dev_err(q6v5->dev, "fatal error received: %s\n", msg);
+   else
+   dev_err(q6v5->dev, "fatal error without message\n");
+
+   rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
+
+   return IRQ_HANDLED;
+}
+
+static irqreturn_t q6v5_ready_interrupt(int irq, void *data)
+{
+   struct qcom_q6v5 *q6v5 = data;
+
+   complete(>start_done);
+
+   return IRQ_HANDLED;
+}
+
+/**
+ * qcom_q6v5_wait_for_start() - wait for remote processor start signal
+ * @q6v5:  reference to qcom_q6v5 context
+ * @timeout:   timeout to wait for the event, in jiffies
+ *
+ * qcom_q6v5_unprepare() should not be called when this function fails.
+ *
+ * Return: 0 on success, -ETIMEDOUT on timeout
+ */
+int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout)
+{
+   int ret;
+
+   ret = wait_for_completion_timeout(>start_done, timeout);
+   if 

[RFC PATCH 4/5] remoteproc: qcom: q6v5-pil: Use common q6v5 helpers

2018-05-22 Thread Bjorn Andersson
Migrate the MSS remoteproc driver to use the newly extracted helper
functions.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   4 +
 drivers/remoteproc/qcom_q6v5_pil.c | 157 +++--
 2 files changed, 19 insertions(+), 142 deletions(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index d51d155cf8bd..2316908e9788 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -116,6 +116,10 @@ config QCOM_Q6V5_PIL
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON
+   select QCOM_Q6V5_COMMON
+   select QCOM_RPROC_COMMON
+   select QCOM_SCM
+   select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c 
b/drivers/remoteproc/qcom_q6v5_pil.c
index 2bf8e7c49f2a..e04319573c91 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -30,12 +30,11 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
 
 #include "remoteproc_internal.h"
 #include "qcom_common.h"
+#include "qcom_q6v5.h"
 
 #include 
 
@@ -151,12 +150,7 @@ struct q6v5 {
 
struct reset_control *mss_restart;
 
-   struct qcom_smem_state *state;
-   unsigned stop_bit;
-
-   int handover_irq;
-
-   bool proxy_unvoted;
+   struct qcom_q6v5 q6v5;
 
struct clk *active_clks[8];
struct clk *reset_clks[4];
@@ -170,8 +164,6 @@ struct q6v5 {
int active_reg_count;
int proxy_reg_count;
 
-   struct completion start_done;
-   struct completion stop_done;
bool running;
 
phys_addr_t mba_phys;
@@ -798,9 +790,7 @@ static int q6v5_start(struct rproc *rproc)
int xfermemop_ret;
int ret;
 
-   qproc->proxy_unvoted = false;
-
-   enable_irq(qproc->handover_irq);
+   qcom_q6v5_prepare(>q6v5);
 
ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
@@ -875,11 +865,9 @@ static int q6v5_start(struct rproc *rproc)
if (ret)
goto reclaim_mpss;
 
-   ret = wait_for_completion_timeout(>start_done,
- msecs_to_jiffies(5000));
-   if (ret == 0) {
+   ret = qcom_q6v5_wait_for_start(>q6v5, msecs_to_jiffies(5000));
+   if (ret == -ETIMEDOUT) {
dev_err(qproc->dev, "start timed out\n");
-   ret = -ETIMEDOUT;
goto reclaim_mpss;
}
 
@@ -933,7 +921,7 @@ static int q6v5_start(struct rproc *rproc)
   qproc->proxy_reg_count);
 
 disable_irqs:
-   disable_irq(qproc->handover_irq);
+   qcom_q6v5_unprepare(>q6v5);
 
return ret;
 }
@@ -946,16 +934,10 @@ static int q6v5_stop(struct rproc *rproc)
 
qproc->running = false;
 
-   qcom_smem_state_update_bits(qproc->state,
-   BIT(qproc->stop_bit), BIT(qproc->stop_bit));
-
-   ret = wait_for_completion_timeout(>stop_done,
- msecs_to_jiffies(5000));
-   if (ret == 0)
+   ret = qcom_q6v5_request_stop(>q6v5);
+   if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "timed out on wait\n");
 
-   qcom_smem_state_update_bits(qproc->state, BIT(qproc->stop_bit), 0);
-
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
@@ -976,9 +958,8 @@ static int q6v5_stop(struct rproc *rproc)
 
q6v5_reset_assert(qproc);
 
-   disable_irq(qproc->handover_irq);
-
-   if (!qproc->proxy_unvoted) {
+   ret = qcom_q6v5_unprepare(>q6v5);
+   if (ret) {
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
 qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
@@ -1014,74 +995,14 @@ static const struct rproc_ops q6v5_ops = {
.load = q6v5_load,
 };
 
-static irqreturn_t q6v5_wdog_interrupt(int irq, void *dev)
-{
-   struct q6v5 *qproc = dev;
-   size_t len;
-   char *msg;
-
-   /* Sometimes the stop triggers a watchdog rather than a stop-ack */
-   if (!qproc->running) {
-   complete(>stop_done);
-   return IRQ_HANDLED;
-   }
-
-   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, );
-   if (!IS_ERR(msg) && len > 0 && msg[0])
-   dev_err(qproc->dev, "watchdog received: %s\n", msg);
-   else
-   dev_err(qproc->dev, "watchdog without message\n");
-
-   rproc_report_crash(qproc->rproc, RPROC_WATCHDOG);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
-{
-   

[RFC PATCH 3/5] remoteproc: qcom: adsp: Use common q6v5 helpers

2018-05-22 Thread Bjorn Andersson
Migrate the Hexagon V5 PAS (ADSP) driver to using the newly extracted
helper functions. The use of the handover callback does introduce latent
disabling of proxy resources. But apart from this there should be no
change in functionality.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   1 +
 drivers/remoteproc/qcom_adsp_pil.c | 156 +
 2 files changed, 28 insertions(+), 129 deletions(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 63b79ea91a21..d51d155cf8bd 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -93,6 +93,7 @@ config QCOM_ADSP_PIL
depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON
select QCOM_MDT_LOADER
+   select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
diff --git a/drivers/remoteproc/qcom_adsp_pil.c 
b/drivers/remoteproc/qcom_adsp_pil.c
index 89a86ce07f99..d4339a6da616 100644
--- a/drivers/remoteproc/qcom_adsp_pil.c
+++ b/drivers/remoteproc/qcom_adsp_pil.c
@@ -31,6 +31,7 @@
 #include 
 
 #include "qcom_common.h"
+#include "qcom_q6v5.h"
 #include "remoteproc_internal.h"
 
 struct adsp_data {
@@ -48,14 +49,7 @@ struct qcom_adsp {
struct device *dev;
struct rproc *rproc;
 
-   int wdog_irq;
-   int fatal_irq;
-   int ready_irq;
-   int handover_irq;
-   int stop_ack_irq;
-
-   struct qcom_smem_state *state;
-   unsigned stop_bit;
+   struct qcom_q6v5 q6v5;
 
struct clk *xo;
struct clk *aggre2_clk;
@@ -96,6 +90,8 @@ static int adsp_start(struct rproc *rproc)
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int ret;
 
+   qcom_q6v5_prepare(>q6v5);
+
ret = clk_prepare_enable(adsp->xo);
if (ret)
return ret;
@@ -119,16 +115,14 @@ static int adsp_start(struct rproc *rproc)
goto disable_px_supply;
}
 
-   ret = wait_for_completion_timeout(>start_done,
- msecs_to_jiffies(5000));
-   if (!ret) {
+   ret = qcom_q6v5_wait_for_start(>q6v5, msecs_to_jiffies(5000));
+   if (ret == -ETIMEDOUT) {
dev_err(adsp->dev, "start timed out\n");
qcom_scm_pas_shutdown(adsp->pas_id);
-   ret = -ETIMEDOUT;
goto disable_px_supply;
}
 
-   ret = 0;
+   return 0;
 
 disable_px_supply:
regulator_disable(adsp->px_supply);
@@ -142,28 +136,34 @@ static int adsp_start(struct rproc *rproc)
return ret;
 }
 
+static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
+{
+   struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
+
+   regulator_disable(adsp->px_supply);
+   regulator_disable(adsp->cx_supply);
+   clk_disable_unprepare(adsp->aggre2_clk);
+   clk_disable_unprepare(adsp->xo);
+}
+
 static int adsp_stop(struct rproc *rproc)
 {
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+   int handover;
int ret;
 
-   qcom_smem_state_update_bits(adsp->state,
-   BIT(adsp->stop_bit),
-   BIT(adsp->stop_bit));
-
-   ret = wait_for_completion_timeout(>stop_done,
- msecs_to_jiffies(5000));
-   if (ret == 0)
+   ret = qcom_q6v5_request_stop(>q6v5);
+   if (ret == -ETIMEDOUT)
dev_err(adsp->dev, "timed out on wait\n");
 
-   qcom_smem_state_update_bits(adsp->state,
-   BIT(adsp->stop_bit),
-   0);
-
ret = qcom_scm_pas_shutdown(adsp->pas_id);
if (ret)
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 
+   handover = qcom_q6v5_unprepare(>q6v5);
+   if (handover)
+   qcom_pas_handover(>q6v5);
+
return ret;
 }
 
@@ -187,53 +187,6 @@ static const struct rproc_ops adsp_ops = {
.load = adsp_load,
 };
 
-static irqreturn_t adsp_wdog_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-
-   rproc_report_crash(adsp->rproc, RPROC_WATCHDOG);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_fatal_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-   size_t len;
-   char *msg;
-
-   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, adsp->crash_reason_smem, );
-   if (!IS_ERR(msg) && len > 0 && msg[0])
-   dev_err(adsp->dev, "fatal error received: %s\n", msg);
-
-   rproc_report_crash(adsp->rproc, RPROC_FATAL_ERROR);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_ready_interrupt(int irq, void *dev)
-{
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_handover_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-
-   complete(>start_done);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t 

[RFC PATCH 4/5] remoteproc: qcom: q6v5-pil: Use common q6v5 helpers

2018-05-22 Thread Bjorn Andersson
Migrate the MSS remoteproc driver to use the newly extracted helper
functions.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   4 +
 drivers/remoteproc/qcom_q6v5_pil.c | 157 +++--
 2 files changed, 19 insertions(+), 142 deletions(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index d51d155cf8bd..2316908e9788 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -116,6 +116,10 @@ config QCOM_Q6V5_PIL
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON
+   select QCOM_Q6V5_COMMON
+   select QCOM_RPROC_COMMON
+   select QCOM_SCM
+   select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c 
b/drivers/remoteproc/qcom_q6v5_pil.c
index 2bf8e7c49f2a..e04319573c91 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -30,12 +30,11 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
 
 #include "remoteproc_internal.h"
 #include "qcom_common.h"
+#include "qcom_q6v5.h"
 
 #include 
 
@@ -151,12 +150,7 @@ struct q6v5 {
 
struct reset_control *mss_restart;
 
-   struct qcom_smem_state *state;
-   unsigned stop_bit;
-
-   int handover_irq;
-
-   bool proxy_unvoted;
+   struct qcom_q6v5 q6v5;
 
struct clk *active_clks[8];
struct clk *reset_clks[4];
@@ -170,8 +164,6 @@ struct q6v5 {
int active_reg_count;
int proxy_reg_count;
 
-   struct completion start_done;
-   struct completion stop_done;
bool running;
 
phys_addr_t mba_phys;
@@ -798,9 +790,7 @@ static int q6v5_start(struct rproc *rproc)
int xfermemop_ret;
int ret;
 
-   qproc->proxy_unvoted = false;
-
-   enable_irq(qproc->handover_irq);
+   qcom_q6v5_prepare(>q6v5);
 
ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
@@ -875,11 +865,9 @@ static int q6v5_start(struct rproc *rproc)
if (ret)
goto reclaim_mpss;
 
-   ret = wait_for_completion_timeout(>start_done,
- msecs_to_jiffies(5000));
-   if (ret == 0) {
+   ret = qcom_q6v5_wait_for_start(>q6v5, msecs_to_jiffies(5000));
+   if (ret == -ETIMEDOUT) {
dev_err(qproc->dev, "start timed out\n");
-   ret = -ETIMEDOUT;
goto reclaim_mpss;
}
 
@@ -933,7 +921,7 @@ static int q6v5_start(struct rproc *rproc)
   qproc->proxy_reg_count);
 
 disable_irqs:
-   disable_irq(qproc->handover_irq);
+   qcom_q6v5_unprepare(>q6v5);
 
return ret;
 }
@@ -946,16 +934,10 @@ static int q6v5_stop(struct rproc *rproc)
 
qproc->running = false;
 
-   qcom_smem_state_update_bits(qproc->state,
-   BIT(qproc->stop_bit), BIT(qproc->stop_bit));
-
-   ret = wait_for_completion_timeout(>stop_done,
- msecs_to_jiffies(5000));
-   if (ret == 0)
+   ret = qcom_q6v5_request_stop(>q6v5);
+   if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "timed out on wait\n");
 
-   qcom_smem_state_update_bits(qproc->state, BIT(qproc->stop_bit), 0);
-
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
@@ -976,9 +958,8 @@ static int q6v5_stop(struct rproc *rproc)
 
q6v5_reset_assert(qproc);
 
-   disable_irq(qproc->handover_irq);
-
-   if (!qproc->proxy_unvoted) {
+   ret = qcom_q6v5_unprepare(>q6v5);
+   if (ret) {
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
 qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
@@ -1014,74 +995,14 @@ static const struct rproc_ops q6v5_ops = {
.load = q6v5_load,
 };
 
-static irqreturn_t q6v5_wdog_interrupt(int irq, void *dev)
-{
-   struct q6v5 *qproc = dev;
-   size_t len;
-   char *msg;
-
-   /* Sometimes the stop triggers a watchdog rather than a stop-ack */
-   if (!qproc->running) {
-   complete(>stop_done);
-   return IRQ_HANDLED;
-   }
-
-   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, );
-   if (!IS_ERR(msg) && len > 0 && msg[0])
-   dev_err(qproc->dev, "watchdog received: %s\n", msg);
-   else
-   dev_err(qproc->dev, "watchdog without message\n");
-
-   rproc_report_crash(qproc->rproc, RPROC_WATCHDOG);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
-{
-   struct q6v5 *qproc = dev;
-

[RFC PATCH 3/5] remoteproc: qcom: adsp: Use common q6v5 helpers

2018-05-22 Thread Bjorn Andersson
Migrate the Hexagon V5 PAS (ADSP) driver to using the newly extracted
helper functions. The use of the handover callback does introduce latent
disabling of proxy resources. But apart from this there should be no
change in functionality.

Signed-off-by: Bjorn Andersson 
---
 drivers/remoteproc/Kconfig |   1 +
 drivers/remoteproc/qcom_adsp_pil.c | 156 +
 2 files changed, 28 insertions(+), 129 deletions(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 63b79ea91a21..d51d155cf8bd 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -93,6 +93,7 @@ config QCOM_ADSP_PIL
depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON
select QCOM_MDT_LOADER
+   select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
diff --git a/drivers/remoteproc/qcom_adsp_pil.c 
b/drivers/remoteproc/qcom_adsp_pil.c
index 89a86ce07f99..d4339a6da616 100644
--- a/drivers/remoteproc/qcom_adsp_pil.c
+++ b/drivers/remoteproc/qcom_adsp_pil.c
@@ -31,6 +31,7 @@
 #include 
 
 #include "qcom_common.h"
+#include "qcom_q6v5.h"
 #include "remoteproc_internal.h"
 
 struct adsp_data {
@@ -48,14 +49,7 @@ struct qcom_adsp {
struct device *dev;
struct rproc *rproc;
 
-   int wdog_irq;
-   int fatal_irq;
-   int ready_irq;
-   int handover_irq;
-   int stop_ack_irq;
-
-   struct qcom_smem_state *state;
-   unsigned stop_bit;
+   struct qcom_q6v5 q6v5;
 
struct clk *xo;
struct clk *aggre2_clk;
@@ -96,6 +90,8 @@ static int adsp_start(struct rproc *rproc)
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int ret;
 
+   qcom_q6v5_prepare(>q6v5);
+
ret = clk_prepare_enable(adsp->xo);
if (ret)
return ret;
@@ -119,16 +115,14 @@ static int adsp_start(struct rproc *rproc)
goto disable_px_supply;
}
 
-   ret = wait_for_completion_timeout(>start_done,
- msecs_to_jiffies(5000));
-   if (!ret) {
+   ret = qcom_q6v5_wait_for_start(>q6v5, msecs_to_jiffies(5000));
+   if (ret == -ETIMEDOUT) {
dev_err(adsp->dev, "start timed out\n");
qcom_scm_pas_shutdown(adsp->pas_id);
-   ret = -ETIMEDOUT;
goto disable_px_supply;
}
 
-   ret = 0;
+   return 0;
 
 disable_px_supply:
regulator_disable(adsp->px_supply);
@@ -142,28 +136,34 @@ static int adsp_start(struct rproc *rproc)
return ret;
 }
 
+static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
+{
+   struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
+
+   regulator_disable(adsp->px_supply);
+   regulator_disable(adsp->cx_supply);
+   clk_disable_unprepare(adsp->aggre2_clk);
+   clk_disable_unprepare(adsp->xo);
+}
+
 static int adsp_stop(struct rproc *rproc)
 {
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+   int handover;
int ret;
 
-   qcom_smem_state_update_bits(adsp->state,
-   BIT(adsp->stop_bit),
-   BIT(adsp->stop_bit));
-
-   ret = wait_for_completion_timeout(>stop_done,
- msecs_to_jiffies(5000));
-   if (ret == 0)
+   ret = qcom_q6v5_request_stop(>q6v5);
+   if (ret == -ETIMEDOUT)
dev_err(adsp->dev, "timed out on wait\n");
 
-   qcom_smem_state_update_bits(adsp->state,
-   BIT(adsp->stop_bit),
-   0);
-
ret = qcom_scm_pas_shutdown(adsp->pas_id);
if (ret)
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 
+   handover = qcom_q6v5_unprepare(>q6v5);
+   if (handover)
+   qcom_pas_handover(>q6v5);
+
return ret;
 }
 
@@ -187,53 +187,6 @@ static const struct rproc_ops adsp_ops = {
.load = adsp_load,
 };
 
-static irqreturn_t adsp_wdog_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-
-   rproc_report_crash(adsp->rproc, RPROC_WATCHDOG);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_fatal_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-   size_t len;
-   char *msg;
-
-   msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, adsp->crash_reason_smem, );
-   if (!IS_ERR(msg) && len > 0 && msg[0])
-   dev_err(adsp->dev, "fatal error received: %s\n", msg);
-
-   rproc_report_crash(adsp->rproc, RPROC_FATAL_ERROR);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_ready_interrupt(int irq, void *dev)
-{
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_handover_interrupt(int irq, void *dev)
-{
-   struct qcom_adsp *adsp = dev;
-
-   complete(>start_done);
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t adsp_stop_ack_interrupt(int irq, 

[RFC PATCH 0/5] Hexagon remoteproc spring cleaning

2018-05-22 Thread Bjorn Andersson
With the introduction of support for the non-MSA Hexagon WCSS driver from
Sricharan and the non-PAS ADSP driver from Rohit it makes sense to overhaul the
structure of the Qualcomm "Q6V5 drivers".

The first patch is from Sricharan's series and included here for completeness.
The second patch introduces a set of helper functions, based on the current
state of the qcom_q6v5_pil driver. The third and forth patch migrates the PAS
and the MSA drivers over to using these helpers. Finally a (completely)
reworked version of Sricharan's WCSS remoteproc driver is introduced.


With this in place I suggest that we rename qcom_adsp_pil.c to qcom_q6v5_pas.c,
qcom_q6v5_pil.c to qcom_q6v5_msa.c and depending on the details of the non-PAS
ADSP we could potentially combine that into a qcom_q6v5_pil.c - or we carry
them as separate files.

Looking at the remaining non-essential parts of these drivers we have
memory-region handling and halt_axi handling. The prior is actively being
worked on and the latter should (if no better abstraction is presented) be
possible to just put in the new qcom_q6v5.c.

Bjorn Andersson (3):
  remoteproc: q6v5: Extract common resource handling
  remoteproc: qcom: adsp: Use common q6v5 helpers
  remoteproc: qcom: q6v5-pil: Use common q6v5 helpers

Sricharan R (2):
  remoteproc: qcom: mdt_loader: Make the firmware authentication
optional
  remoteproc: qcom: Introduce Hexagon V5 based WCSS driver

 drivers/remoteproc/Kconfig  |  23 ++
 drivers/remoteproc/Makefile |   2 +
 drivers/remoteproc/qcom_adsp_pil.c  | 156 ++--
 drivers/remoteproc/qcom_q6v5.c  | 243 
 drivers/remoteproc/qcom_q6v5.h  |  46 +++
 drivers/remoteproc/qcom_q6v5_pil.c  | 157 +---
 drivers/remoteproc/qcom_q6v5_wcss.c | 580 
 drivers/soc/qcom/mdt_loader.c   |  87 +++--
 include/linux/soc/qcom/mdt_loader.h |   4 +
 9 files changed, 1002 insertions(+), 296 deletions(-)
 create mode 100644 drivers/remoteproc/qcom_q6v5.c
 create mode 100644 drivers/remoteproc/qcom_q6v5.h
 create mode 100644 drivers/remoteproc/qcom_q6v5_wcss.c

-- 
2.17.0



[RFC PATCH 0/5] Hexagon remoteproc spring cleaning

2018-05-22 Thread Bjorn Andersson
With the introduction of support for the non-MSA Hexagon WCSS driver from
Sricharan and the non-PAS ADSP driver from Rohit it makes sense to overhaul the
structure of the Qualcomm "Q6V5 drivers".

The first patch is from Sricharan's series and included here for completeness.
The second patch introduces a set of helper functions, based on the current
state of the qcom_q6v5_pil driver. The third and forth patch migrates the PAS
and the MSA drivers over to using these helpers. Finally a (completely)
reworked version of Sricharan's WCSS remoteproc driver is introduced.


With this in place I suggest that we rename qcom_adsp_pil.c to qcom_q6v5_pas.c,
qcom_q6v5_pil.c to qcom_q6v5_msa.c and depending on the details of the non-PAS
ADSP we could potentially combine that into a qcom_q6v5_pil.c - or we carry
them as separate files.

Looking at the remaining non-essential parts of these drivers we have
memory-region handling and halt_axi handling. The prior is actively being
worked on and the latter should (if no better abstraction is presented) be
possible to just put in the new qcom_q6v5.c.

Bjorn Andersson (3):
  remoteproc: q6v5: Extract common resource handling
  remoteproc: qcom: adsp: Use common q6v5 helpers
  remoteproc: qcom: q6v5-pil: Use common q6v5 helpers

Sricharan R (2):
  remoteproc: qcom: mdt_loader: Make the firmware authentication
optional
  remoteproc: qcom: Introduce Hexagon V5 based WCSS driver

 drivers/remoteproc/Kconfig  |  23 ++
 drivers/remoteproc/Makefile |   2 +
 drivers/remoteproc/qcom_adsp_pil.c  | 156 ++--
 drivers/remoteproc/qcom_q6v5.c  | 243 
 drivers/remoteproc/qcom_q6v5.h  |  46 +++
 drivers/remoteproc/qcom_q6v5_pil.c  | 157 +---
 drivers/remoteproc/qcom_q6v5_wcss.c | 580 
 drivers/soc/qcom/mdt_loader.c   |  87 +++--
 include/linux/soc/qcom/mdt_loader.h |   4 +
 9 files changed, 1002 insertions(+), 296 deletions(-)
 create mode 100644 drivers/remoteproc/qcom_q6v5.c
 create mode 100644 drivers/remoteproc/qcom_q6v5.h
 create mode 100644 drivers/remoteproc/qcom_q6v5_wcss.c

-- 
2.17.0



[RFC PATCH 5/5] remoteproc: qcom: Introduce Hexagon V5 based WCSS driver

2018-05-22 Thread Bjorn Andersson
From: Sricharan R 

IPQ8074 has an integrated Hexagon dsp core q6v5 and a wireless lan
(Lithium) IP. An mdt type single image format is used for the
firmware. So the mdt_load function can be directly used to load
the firmware. Also add the relevant resets required for this core.

Signed-off-by: Sricharan R 
[bjorn: Rewrote as a separate driver, intead of extending q6v5_pil.c]
Signed-off-by: Bjorn Andersson 
---

Due to lack of hardware this is only compile tested. So I'm interested in both
feedback on the approach and testing of this.

 drivers/remoteproc/Kconfig  |  15 +-
 drivers/remoteproc/Makefile |   1 +
 drivers/remoteproc/qcom_q6v5_wcss.c | 580 
 3 files changed, 595 insertions(+), 1 deletion(-)
 create mode 100644 drivers/remoteproc/qcom_q6v5_wcss.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 2316908e9788..4b55bfcfc8e1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -119,12 +119,25 @@ config QCOM_Q6V5_PIL
select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
+   help
+ Say y here to support the Qualcomm Peripherial Image Loader for the
+ Hexagon V5 based remote processors.
+
+config QCOM_Q6V5_WCSS
+   tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader"
+   depends on OF && ARCH_QCOM
+   depends on QCOM_SMEM
+   depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
+   depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
+   depends on QCOM_SYSMON || QCOM_SYSMON=n
+   select MFD_SYSCON
+   select QCOM_MDT_LOADER
select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
  Say y here to support the Qualcomm Peripherial Image Loader for the
- Hexagon V5 based remote processors.
+ Hexagon V5 based WCSS remote processors.
 
 config QCOM_SYSMON
tristate "Qualcomm sysmon driver"
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 5dd0249cf76a..03332fa7e2ee 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_QCOM_ADSP_PIL)   += qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)+= qcom_common.o
 obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)+= qcom_q6v5_pil.o
+obj-$(CONFIG_QCOM_Q6V5_WCSS)   += qcom_q6v5_wcss.o
 obj-$(CONFIG_QCOM_SYSMON)  += qcom_sysmon.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)   += qcom_wcnss_pil.o
 qcom_wcnss_pil-y   += qcom_wcnss.o
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
new file mode 100644
index ..f0b38eae52df
--- /dev/null
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -0,0 +1,580 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Linaro Ltd.
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qcom_common.h"
+#include "qcom_q6v5.h"
+
+#define WCSS_CRASH_REASON  421
+
+/* QDSP6SS Register Offsets */
+#define QDSP6SS_RESET_REG  0x014
+#define QDSP6SS_GFMUX_CTL_REG  0x020
+#define QDSP6SS_PWR_CTL_REG0x030
+#define QDSP6SS_MEM_PWR_CTL0x0B0
+
+/* AXI Halt Register Offsets */
+#define AXI_HALTREQ_REG0x0
+#define AXI_HALTACK_REG0x4
+#define AXI_IDLE_REG   0x8
+
+#define HALT_ACK_TIMEOUT_MS100
+
+/* QDSP6SS_RESET */
+#define Q6SS_STOP_CORE BIT(0)
+#define Q6SS_CORE_ARES BIT(1)
+#define Q6SS_BUS_ARES_ENABLE   BIT(2)
+
+/* QDSP6SS_GFMUX_CTL */
+#define Q6SS_CLK_ENABLEBIT(1)
+
+/* QDSP6SS_PWR_CTL */
+#define Q6SS_L2DATA_STBY_N BIT(18)
+#define Q6SS_SLP_RET_N BIT(19)
+#define Q6SS_CLAMP_IO  BIT(20)
+#define QDSS_BHS_ONBIT(21)
+
+/* QDSP6v56 parameters */
+#define QDSP6v56_LDO_BYP   BIT(25)
+#define QDSP6v56_BHS_ONBIT(24)
+#define QDSP6v56_CLAMP_WL  BIT(21)
+#define QDSP6v56_CLAMP_QMC_MEM BIT(22)
+#define HALT_CHECK_MAX_LOOPS   200
+#define QDSP6SS_XO_CBCR0x0038
+
+/* QDSP6v5-WCSS config/status registers */
+#define TCSR_GLOBAL_CFG0   0x0
+#define TCSR_GLOBAL_CFG1   0x4
+#define SSCAON_CONFIG  0x8
+#define SSCAON_STATUS  0xc
+#define QDSP6SS_BHS_STATUS 0x78
+#define QDSP6SS_RST_EVB0x10
+
+#define BHS_EN_REST_ACKBIT(0)
+#define SSCAON_ENABLE  BIT(13)
+
+
+struct q6v5_wcss {
+   struct 

[RFC PATCH 1/5] remoteproc: qcom: mdt_loader: Make the firmware authentication optional

2018-05-22 Thread Bjorn Andersson
From: Sricharan R 

qcom_mdt_load function loads the mdt type firmware and
initialises the secure memory as well. Make the initialisation only
when requested by the caller, so that the function can be used
by self-authenticating remoteproc as well.

Acked-by: Bjorn Andersson 
Signed-off-by: Sricharan R 
Signed-off-by: Bjorn Andersson 
---

No changes from Sricharan's V6.

 drivers/soc/qcom/mdt_loader.c   | 87 -
 include/linux/soc/qcom/mdt_loader.h |  4 ++
 2 files changed, 66 insertions(+), 25 deletions(-)

diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index dc09d7ac905f..1c488024c698 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -74,23 +74,10 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
 }
 EXPORT_SYMBOL_GPL(qcom_mdt_get_size);
 
-/**
- * qcom_mdt_load() - load the firmware which header is loaded as fw
- * @dev:   device handle to associate resources with
- * @fw:firmware object for the mdt file
- * @firmware:  name of the firmware, for construction of segment file names
- * @pas_id:PAS identifier
- * @mem_region:allocated memory region to load firmware into
- * @mem_phys:  physical address of allocated memory region
- * @mem_size:  size of the allocated memory region
- * @reloc_base:adjusted physical address after relocation
- *
- * Returns 0 on success, negative errno otherwise.
- */
-int qcom_mdt_load(struct device *dev, const struct firmware *fw,
- const char *firmware, int pas_id, void *mem_region,
- phys_addr_t mem_phys, size_t mem_size,
- phys_addr_t *reloc_base)
+static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
+  const char *firmware, int pas_id, void *mem_region,
+  phys_addr_t mem_phys, size_t mem_size,
+  phys_addr_t *reloc_base, bool pas_init)
 {
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
@@ -121,10 +108,12 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
if (!fw_name)
return -ENOMEM;
 
-   ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
-   if (ret) {
-   dev_err(dev, "invalid firmware metadata\n");
-   goto out;
+   if (pas_init) {
+   ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
+   if (ret) {
+   dev_err(dev, "invalid firmware metadata\n");
+   goto out;
+   }
}
 
for (i = 0; i < ehdr->e_phnum; i++) {
@@ -144,10 +133,13 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
}
 
if (relocate) {
-   ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - 
min_addr);
-   if (ret) {
-   dev_err(dev, "unable to setup relocation\n");
-   goto out;
+   if (pas_init) {
+   ret = qcom_scm_pas_mem_setup(pas_id, mem_phys,
+max_addr - min_addr);
+   if (ret) {
+   dev_err(dev, "unable to setup relocation\n");
+   goto out;
+   }
}
 
/*
@@ -202,7 +194,52 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
 
return ret;
 }
+
+/**
+ * qcom_mdt_load() - load the firmware which header is loaded as fw
+ * @dev:   device handle to associate resources with
+ * @fw:firmware object for the mdt file
+ * @firmware:  name of the firmware, for construction of segment file names
+ * @pas_id:PAS identifier
+ * @mem_region:allocated memory region to load firmware into
+ * @mem_phys:  physical address of allocated memory region
+ * @mem_size:  size of the allocated memory region
+ * @reloc_base:adjusted physical address after relocation
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+int qcom_mdt_load(struct device *dev, const struct firmware *fw,
+ const char *firmware, int pas_id, void *mem_region,
+ phys_addr_t mem_phys, size_t mem_size,
+ phys_addr_t *reloc_base)
+{
+   return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
+  mem_size, reloc_base, true);
+}
 EXPORT_SYMBOL_GPL(qcom_mdt_load);
 
+/**
+ * qcom_mdt_load_no_init() - load the firmware which header is loaded as fw
+ * @dev:   device handle to associate resources with
+ * @fw:firmware object for the mdt file
+ * @firmware:  name of the firmware, for construction of segment file names
+ * @pas_id:PAS identifier
+ * @mem_region:

[RFC PATCH 1/5] remoteproc: qcom: mdt_loader: Make the firmware authentication optional

2018-05-22 Thread Bjorn Andersson
From: Sricharan R 

qcom_mdt_load function loads the mdt type firmware and
initialises the secure memory as well. Make the initialisation only
when requested by the caller, so that the function can be used
by self-authenticating remoteproc as well.

Acked-by: Bjorn Andersson 
Signed-off-by: Sricharan R 
Signed-off-by: Bjorn Andersson 
---

No changes from Sricharan's V6.

 drivers/soc/qcom/mdt_loader.c   | 87 -
 include/linux/soc/qcom/mdt_loader.h |  4 ++
 2 files changed, 66 insertions(+), 25 deletions(-)

diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index dc09d7ac905f..1c488024c698 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -74,23 +74,10 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
 }
 EXPORT_SYMBOL_GPL(qcom_mdt_get_size);
 
-/**
- * qcom_mdt_load() - load the firmware which header is loaded as fw
- * @dev:   device handle to associate resources with
- * @fw:firmware object for the mdt file
- * @firmware:  name of the firmware, for construction of segment file names
- * @pas_id:PAS identifier
- * @mem_region:allocated memory region to load firmware into
- * @mem_phys:  physical address of allocated memory region
- * @mem_size:  size of the allocated memory region
- * @reloc_base:adjusted physical address after relocation
- *
- * Returns 0 on success, negative errno otherwise.
- */
-int qcom_mdt_load(struct device *dev, const struct firmware *fw,
- const char *firmware, int pas_id, void *mem_region,
- phys_addr_t mem_phys, size_t mem_size,
- phys_addr_t *reloc_base)
+static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
+  const char *firmware, int pas_id, void *mem_region,
+  phys_addr_t mem_phys, size_t mem_size,
+  phys_addr_t *reloc_base, bool pas_init)
 {
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
@@ -121,10 +108,12 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
if (!fw_name)
return -ENOMEM;
 
-   ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
-   if (ret) {
-   dev_err(dev, "invalid firmware metadata\n");
-   goto out;
+   if (pas_init) {
+   ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
+   if (ret) {
+   dev_err(dev, "invalid firmware metadata\n");
+   goto out;
+   }
}
 
for (i = 0; i < ehdr->e_phnum; i++) {
@@ -144,10 +133,13 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
}
 
if (relocate) {
-   ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - 
min_addr);
-   if (ret) {
-   dev_err(dev, "unable to setup relocation\n");
-   goto out;
+   if (pas_init) {
+   ret = qcom_scm_pas_mem_setup(pas_id, mem_phys,
+max_addr - min_addr);
+   if (ret) {
+   dev_err(dev, "unable to setup relocation\n");
+   goto out;
+   }
}
 
/*
@@ -202,7 +194,52 @@ int qcom_mdt_load(struct device *dev, const struct 
firmware *fw,
 
return ret;
 }
+
+/**
+ * qcom_mdt_load() - load the firmware which header is loaded as fw
+ * @dev:   device handle to associate resources with
+ * @fw:firmware object for the mdt file
+ * @firmware:  name of the firmware, for construction of segment file names
+ * @pas_id:PAS identifier
+ * @mem_region:allocated memory region to load firmware into
+ * @mem_phys:  physical address of allocated memory region
+ * @mem_size:  size of the allocated memory region
+ * @reloc_base:adjusted physical address after relocation
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+int qcom_mdt_load(struct device *dev, const struct firmware *fw,
+ const char *firmware, int pas_id, void *mem_region,
+ phys_addr_t mem_phys, size_t mem_size,
+ phys_addr_t *reloc_base)
+{
+   return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
+  mem_size, reloc_base, true);
+}
 EXPORT_SYMBOL_GPL(qcom_mdt_load);
 
+/**
+ * qcom_mdt_load_no_init() - load the firmware which header is loaded as fw
+ * @dev:   device handle to associate resources with
+ * @fw:firmware object for the mdt file
+ * @firmware:  name of the firmware, for construction of segment file names
+ * @pas_id:PAS identifier
+ * @mem_region:allocated memory region to load firmware into
+ * @mem_phys:  physical address of allocated memory region
+ 

[RFC PATCH 5/5] remoteproc: qcom: Introduce Hexagon V5 based WCSS driver

2018-05-22 Thread Bjorn Andersson
From: Sricharan R 

IPQ8074 has an integrated Hexagon dsp core q6v5 and a wireless lan
(Lithium) IP. An mdt type single image format is used for the
firmware. So the mdt_load function can be directly used to load
the firmware. Also add the relevant resets required for this core.

Signed-off-by: Sricharan R 
[bjorn: Rewrote as a separate driver, intead of extending q6v5_pil.c]
Signed-off-by: Bjorn Andersson 
---

Due to lack of hardware this is only compile tested. So I'm interested in both
feedback on the approach and testing of this.

 drivers/remoteproc/Kconfig  |  15 +-
 drivers/remoteproc/Makefile |   1 +
 drivers/remoteproc/qcom_q6v5_wcss.c | 580 
 3 files changed, 595 insertions(+), 1 deletion(-)
 create mode 100644 drivers/remoteproc/qcom_q6v5_wcss.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 2316908e9788..4b55bfcfc8e1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -119,12 +119,25 @@ config QCOM_Q6V5_PIL
select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
+   help
+ Say y here to support the Qualcomm Peripherial Image Loader for the
+ Hexagon V5 based remote processors.
+
+config QCOM_Q6V5_WCSS
+   tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader"
+   depends on OF && ARCH_QCOM
+   depends on QCOM_SMEM
+   depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
+   depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
+   depends on QCOM_SYSMON || QCOM_SYSMON=n
+   select MFD_SYSCON
+   select QCOM_MDT_LOADER
select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
  Say y here to support the Qualcomm Peripherial Image Loader for the
- Hexagon V5 based remote processors.
+ Hexagon V5 based WCSS remote processors.
 
 config QCOM_SYSMON
tristate "Qualcomm sysmon driver"
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 5dd0249cf76a..03332fa7e2ee 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_QCOM_ADSP_PIL)   += qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)+= qcom_common.o
 obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)+= qcom_q6v5_pil.o
+obj-$(CONFIG_QCOM_Q6V5_WCSS)   += qcom_q6v5_wcss.o
 obj-$(CONFIG_QCOM_SYSMON)  += qcom_sysmon.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)   += qcom_wcnss_pil.o
 qcom_wcnss_pil-y   += qcom_wcnss.o
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
new file mode 100644
index ..f0b38eae52df
--- /dev/null
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -0,0 +1,580 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Linaro Ltd.
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qcom_common.h"
+#include "qcom_q6v5.h"
+
+#define WCSS_CRASH_REASON  421
+
+/* QDSP6SS Register Offsets */
+#define QDSP6SS_RESET_REG  0x014
+#define QDSP6SS_GFMUX_CTL_REG  0x020
+#define QDSP6SS_PWR_CTL_REG0x030
+#define QDSP6SS_MEM_PWR_CTL0x0B0
+
+/* AXI Halt Register Offsets */
+#define AXI_HALTREQ_REG0x0
+#define AXI_HALTACK_REG0x4
+#define AXI_IDLE_REG   0x8
+
+#define HALT_ACK_TIMEOUT_MS100
+
+/* QDSP6SS_RESET */
+#define Q6SS_STOP_CORE BIT(0)
+#define Q6SS_CORE_ARES BIT(1)
+#define Q6SS_BUS_ARES_ENABLE   BIT(2)
+
+/* QDSP6SS_GFMUX_CTL */
+#define Q6SS_CLK_ENABLEBIT(1)
+
+/* QDSP6SS_PWR_CTL */
+#define Q6SS_L2DATA_STBY_N BIT(18)
+#define Q6SS_SLP_RET_N BIT(19)
+#define Q6SS_CLAMP_IO  BIT(20)
+#define QDSS_BHS_ONBIT(21)
+
+/* QDSP6v56 parameters */
+#define QDSP6v56_LDO_BYP   BIT(25)
+#define QDSP6v56_BHS_ONBIT(24)
+#define QDSP6v56_CLAMP_WL  BIT(21)
+#define QDSP6v56_CLAMP_QMC_MEM BIT(22)
+#define HALT_CHECK_MAX_LOOPS   200
+#define QDSP6SS_XO_CBCR0x0038
+
+/* QDSP6v5-WCSS config/status registers */
+#define TCSR_GLOBAL_CFG0   0x0
+#define TCSR_GLOBAL_CFG1   0x4
+#define SSCAON_CONFIG  0x8
+#define SSCAON_STATUS  0xc
+#define QDSP6SS_BHS_STATUS 0x78
+#define QDSP6SS_RST_EVB0x10
+
+#define BHS_EN_REST_ACKBIT(0)
+#define SSCAON_ENABLE  BIT(13)
+
+
+struct q6v5_wcss {
+   struct device *dev;
+
+   void __iomem *reg_base;
+   void __iomem *rmb_base;
+
+

[PATCH v2 5/7] mm, hmm: Use devm semantics for hmm_devmem_{add, remove}

2018-05-22 Thread Dan Williams
devm semantics arrange for resources to be torn down when
device-driver-probe fails or when device-driver-release completes.
Similar to devm_memremap_pages() there is no need to support an explicit
remove operation when the users properly adhere to devm semantics.

Reviewed-by: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 Documentation/vm/hmm.txt |1 
 include/linux/hmm.h  |4 -
 mm/hmm.c |  127 +-
 3 files changed, 25 insertions(+), 107 deletions(-)

diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt
index 2d1d6f69e91b..b2f944b87c5e 100644
--- a/Documentation/vm/hmm.txt
+++ b/Documentation/vm/hmm.txt
@@ -285,7 +285,6 @@ region needing a struct page. This is offered through a 
very simple API:
  struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
struct device *device,
unsigned long size);
- void hmm_devmem_remove(struct hmm_devmem *devmem);
 
 The hmm_devmem_ops is where most of the important things are:
 
diff --git a/include/linux/hmm.h b/include/linux/hmm.h
index 39988924de3a..880f6bb9485c 100644
--- a/include/linux/hmm.h
+++ b/include/linux/hmm.h
@@ -499,8 +499,7 @@ struct hmm_devmem {
  * enough and allocate struct page for it.
  *
  * The device driver can wrap the hmm_devmem struct inside a private device
- * driver struct. The device driver must call hmm_devmem_remove() before the
- * device goes away and before freeing the hmm_devmem struct memory.
+ * driver struct.
  */
 struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
  struct device *device,
@@ -508,7 +507,6 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
 struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
   struct device *device,
   struct resource *res);
-void hmm_devmem_remove(struct hmm_devmem *devmem);
 
 /*
  * hmm_devmem_page_set_drvdata - set per-page driver data field
diff --git a/mm/hmm.c b/mm/hmm.c
index 486dc394a5a3..d081857f29b5 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -943,7 +943,6 @@ static void hmm_devmem_ref_exit(void *data)
 
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_exit(ref);
-   devm_remove_action(devmem->device, _devmem_ref_exit, data);
 }
 
 static void hmm_devmem_ref_kill(void *data)
@@ -954,7 +953,6 @@ static void hmm_devmem_ref_kill(void *data)
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_kill(ref);
wait_for_completion(>completion);
-   devm_remove_action(devmem->device, _devmem_ref_kill, data);
 }
 
 static int hmm_devmem_fault(struct vm_area_struct *vma,
@@ -993,7 +991,7 @@ static void hmm_devmem_radix_release(struct resource 
*resource)
mutex_unlock(_devmem_lock);
 }
 
-static void hmm_devmem_release(struct device *dev, void *data)
+static void hmm_devmem_release(void *data)
 {
struct hmm_devmem *devmem = data;
struct resource *resource = devmem->resource;
@@ -1001,11 +999,6 @@ static void hmm_devmem_release(struct device *dev, void 
*data)
struct zone *zone;
struct page *page;
 
-   if (percpu_ref_tryget_live(>ref)) {
-   dev_WARN(dev, "%s: page mapping is still live!\n", __func__);
-   percpu_ref_put(>ref);
-   }
-
/* pages are dead and unused, undo the arch mapping */
start_pfn = (resource->start & ~(PA_SECTION_SIZE - 1)) >> PAGE_SHIFT;
npages = ALIGN(resource_size(resource), PA_SECTION_SIZE) >> PAGE_SHIFT;
@@ -1129,19 +1122,6 @@ static int hmm_devmem_pages_create(struct hmm_devmem 
*devmem)
return ret;
 }
 
-static int hmm_devmem_match(struct device *dev, void *data, void *match_data)
-{
-   struct hmm_devmem *devmem = data;
-
-   return devmem->resource == match_data;
-}
-
-static void hmm_devmem_pages_remove(struct hmm_devmem *devmem)
-{
-   devres_release(devmem->device, _devmem_release,
-  _devmem_match, devmem->resource);
-}
-
 /*
  * hmm_devmem_add() - hotplug ZONE_DEVICE memory for device memory
  *
@@ -1169,8 +1149,7 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
 
static_branch_enable(_private_key);
 
-   devmem = devres_alloc_node(_devmem_release, sizeof(*devmem),
-  GFP_KERNEL, dev_to_node(device));
+   devmem = devm_kzalloc(device, sizeof(*devmem), GFP_KERNEL);
if (!devmem)
return ERR_PTR(-ENOMEM);
 
@@ -1184,11 +1163,11 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
ret = percpu_ref_init(>ref, _devmem_ref_release,
  0, GFP_KERNEL);
if (ret)

[PATCH v2 2/7] mm, devm_memremap_pages: Kill mapping "System RAM" support

2018-05-22 Thread Dan Williams
Given the fact that devm_memremap_pages() requires a percpu_ref that is
torn down by devm_memremap_pages_release() the current support for
mapping RAM is broken.

This has been broken since forever and there is no use case to map RAM
in this way, so just kill the support and make it an explicit error.

Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index c614645227a7..dd11607671eb 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -355,15 +355,12 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap)
is_ram = region_intersects(align_start, align_size,
IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
 
-   if (is_ram == REGION_MIXED) {
-   WARN_ONCE(1, "%s attempted on mixed region %pr\n",
-   __func__, res);
+   if (is_ram != REGION_DISJOINT) {
+   WARN_ONCE(1, "%s attempted on %s region %pr\n", __func__,
+   is_ram == REGION_MIXED ? "mixed" : "ram", res);
return ERR_PTR(-ENXIO);
}
 
-   if (is_ram == REGION_INTERSECTS)
-   return __va(res->start);
-
if (!pgmap->ref)
return ERR_PTR(-EINVAL);
 



[PATCH v2 1/7] mm, devm_memremap_pages: Mark devm_memremap_pages() EXPORT_SYMBOL_GPL

2018-05-22 Thread Dan Williams
The devm_memremap_pages() facility is tightly integrated with the
kernel's memory hotplug functionality. It injects an altmap argument
deep into the architecture specific vmemmap implementation to allow
allocating from specific reserved pages, and it has Linux specific
assumptions about page structure reference counting relative to
get_user_pages() and get_user_pages_fast(). It was an oversight that
this was not marked EXPORT_SYMBOL_GPL from the outset.

Cc: Michal Hocko 
Cc: "Jérôme Glisse" 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index 895e6b76b25e..c614645227a7 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -429,7 +429,7 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap)
pgmap_radix_release(res, pgoff);
return ERR_PTR(error);
 }
-EXPORT_SYMBOL(devm_memremap_pages);
+EXPORT_SYMBOL_GPL(devm_memremap_pages);
 
 unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
 {



[PATCH v2 7/7] mm, hmm: Mark hmm_devmem_{add, add_resource} EXPORT_SYMBOL_GPL

2018-05-22 Thread Dan Williams
The routines hmm_devmem_add(), and hmm_devmem_add_resource() are small
wrappers around devm_memremap_pages(). The devm_memremap_pages()
interface is a subset of the hmm functionality which has more and deeper
ties into the kernel memory management implementation. It was an
oversight that these symbols were not marked EXPORT_SYMBOL_GPL from the
outset due to how they originally copied (and now reuse)
devm_memremap_pages().

Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Dan Williams 
---
 mm/hmm.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/hmm.c b/mm/hmm.c
index 5723331f6910..25c338d46576 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -1063,7 +1063,7 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
return result;
return devmem;
 }
-EXPORT_SYMBOL(hmm_devmem_add);
+EXPORT_SYMBOL_GPL(hmm_devmem_add);
 
 struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
   struct device *device,
@@ -1117,7 +1117,7 @@ struct hmm_devmem *hmm_devmem_add_resource(const struct 
hmm_devmem_ops *ops,
return result;
return devmem;
 }
-EXPORT_SYMBOL(hmm_devmem_add_resource);
+EXPORT_SYMBOL_GPL(hmm_devmem_add_resource);
 
 /*
  * A device driver that wants to handle multiple devices memory through a



[PATCH v2 3/7] mm, devm_memremap_pages: Fix shutdown handling

2018-05-22 Thread Dan Williams
The last step before devm_memremap_pages() returns success is to
allocate a release action, devm_memremap_pages_release(), to tear the
entire setup down. However, the result from devm_add_action() is not
checked.

Checking the error from devm_add_action() is not enough. The api
currently relies on the fact that the percpu_ref it is using is killed
by the time the devm_memremap_pages_release() is run. Rather than
continue this awkward situation, offload the responsibility of killing
the percpu_ref to devm_memremap_pages_release() directly. This allows
devm_memremap_pages() to do the right thing  relative to init failures
and shutdown.

Without this change we could fail to register the teardown of
devm_memremap_pages(). The likelihood of hitting this failure is tiny as
small memory allocations almost always succeed. However, the impact of
the failure is large given any future reconfiguration, or
disable/enable, of an nvdimm namespace will fail forever as subsequent
calls to devm_memremap_pages() will fail to setup the pgmap_radix since
there will be stale entries for the physical address range.

Cc: 
Fixes: e8d513483300 ("memremap: change devm_memremap_pages interface...")
Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Reported-by: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 drivers/dax/pmem.c|   10 ++
 drivers/nvdimm/pmem.c |   18 --
 include/linux/memremap.h  |7 +--
 kernel/memremap.c |   36 +++-
 tools/testing/nvdimm/test/iomap.c |   21 ++---
 5 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index fd49b24fd6af..54cba20c8ba6 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -48,9 +48,8 @@ static void dax_pmem_percpu_exit(void *data)
percpu_ref_exit(ref);
 }
 
-static void dax_pmem_percpu_kill(void *data)
+static void dax_pmem_percpu_kill(struct percpu_ref *ref)
 {
-   struct percpu_ref *ref = data;
struct dax_pmem *dax_pmem = to_dax_pmem(ref);
 
dev_dbg(dax_pmem->dev, "trace\n");
@@ -111,15 +110,10 @@ static int dax_pmem_probe(struct device *dev)
return rc;
 
dax_pmem->pgmap.ref = _pmem->ref;
-   addr = devm_memremap_pages(dev, _pmem->pgmap);
+   addr = devm_memremap_pages(dev, _pmem->pgmap, dax_pmem_percpu_kill);
if (IS_ERR(addr))
return PTR_ERR(addr);
 
-   rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill,
-   _pmem->ref);
-   if (rc)
-   return rc;
-
/* adjust the dax_region resource to the start of data */
memcpy(, _pmem->pgmap.res, sizeof(res));
res.start += le64_to_cpu(pfn_sb->dataoff);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 9d714926ecf5..49c9c1bab438 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -279,8 +279,11 @@ static void pmem_release_queue(void *q)
blk_cleanup_queue(q);
 }
 
-static void pmem_freeze_queue(void *q)
+static void pmem_freeze_queue(struct percpu_ref *ref)
 {
+   struct request_queue *q;
+
+   q = container_of(ref, typeof(*q), q_usage_counter);
blk_freeze_queue_start(q);
 }
 
@@ -353,7 +356,8 @@ static int pmem_attach_disk(struct device *dev,
pmem->pfn_flags = PFN_DEV;
pmem->pgmap.ref = >q_usage_counter;
if (is_nd_pfn(dev)) {
-   addr = devm_memremap_pages(dev, >pgmap);
+   addr = devm_memremap_pages(dev, >pgmap,
+   pmem_freeze_queue);
pfn_sb = nd_pfn->pfn_sb;
pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
pmem->pfn_pad = resource_size(res) -
@@ -364,20 +368,14 @@ static int pmem_attach_disk(struct device *dev,
} else if (pmem_should_map_pages(dev)) {
memcpy(>pgmap.res, >res, sizeof(pmem->pgmap.res));
pmem->pgmap.altmap_valid = false;
-   addr = devm_memremap_pages(dev, >pgmap);
+   addr = devm_memremap_pages(dev, >pgmap,
+   pmem_freeze_queue);
pmem->pfn_flags |= PFN_MAP;
memcpy(_res, >pgmap.res, sizeof(bb_res));
} else
addr = devm_memremap(dev, pmem->phys_addr,
pmem->size, ARCH_MEMREMAP_PMEM);
 
-   /*
-* At release time the queue must be frozen before
-* devm_memremap_pages is unwound
-*/
-   if (devm_add_action_or_reset(dev, pmem_freeze_queue, q))
-   return -ENOMEM;
-
if (IS_ERR(addr))
return PTR_ERR(addr);
pmem->virt_addr = addr;
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 7b4899c06f49..b5e894133cf6 100644
--- 

[PATCH v2 1/7] mm, devm_memremap_pages: Mark devm_memremap_pages() EXPORT_SYMBOL_GPL

2018-05-22 Thread Dan Williams
The devm_memremap_pages() facility is tightly integrated with the
kernel's memory hotplug functionality. It injects an altmap argument
deep into the architecture specific vmemmap implementation to allow
allocating from specific reserved pages, and it has Linux specific
assumptions about page structure reference counting relative to
get_user_pages() and get_user_pages_fast(). It was an oversight that
this was not marked EXPORT_SYMBOL_GPL from the outset.

Cc: Michal Hocko 
Cc: "Jérôme Glisse" 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index 895e6b76b25e..c614645227a7 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -429,7 +429,7 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap)
pgmap_radix_release(res, pgoff);
return ERR_PTR(error);
 }
-EXPORT_SYMBOL(devm_memremap_pages);
+EXPORT_SYMBOL_GPL(devm_memremap_pages);
 
 unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
 {



[PATCH v2 7/7] mm, hmm: Mark hmm_devmem_{add, add_resource} EXPORT_SYMBOL_GPL

2018-05-22 Thread Dan Williams
The routines hmm_devmem_add(), and hmm_devmem_add_resource() are small
wrappers around devm_memremap_pages(). The devm_memremap_pages()
interface is a subset of the hmm functionality which has more and deeper
ties into the kernel memory management implementation. It was an
oversight that these symbols were not marked EXPORT_SYMBOL_GPL from the
outset due to how they originally copied (and now reuse)
devm_memremap_pages().

Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Dan Williams 
---
 mm/hmm.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/hmm.c b/mm/hmm.c
index 5723331f6910..25c338d46576 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -1063,7 +1063,7 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
return result;
return devmem;
 }
-EXPORT_SYMBOL(hmm_devmem_add);
+EXPORT_SYMBOL_GPL(hmm_devmem_add);
 
 struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
   struct device *device,
@@ -1117,7 +1117,7 @@ struct hmm_devmem *hmm_devmem_add_resource(const struct 
hmm_devmem_ops *ops,
return result;
return devmem;
 }
-EXPORT_SYMBOL(hmm_devmem_add_resource);
+EXPORT_SYMBOL_GPL(hmm_devmem_add_resource);
 
 /*
  * A device driver that wants to handle multiple devices memory through a



[PATCH v2 3/7] mm, devm_memremap_pages: Fix shutdown handling

2018-05-22 Thread Dan Williams
The last step before devm_memremap_pages() returns success is to
allocate a release action, devm_memremap_pages_release(), to tear the
entire setup down. However, the result from devm_add_action() is not
checked.

Checking the error from devm_add_action() is not enough. The api
currently relies on the fact that the percpu_ref it is using is killed
by the time the devm_memremap_pages_release() is run. Rather than
continue this awkward situation, offload the responsibility of killing
the percpu_ref to devm_memremap_pages_release() directly. This allows
devm_memremap_pages() to do the right thing  relative to init failures
and shutdown.

Without this change we could fail to register the teardown of
devm_memremap_pages(). The likelihood of hitting this failure is tiny as
small memory allocations almost always succeed. However, the impact of
the failure is large given any future reconfiguration, or
disable/enable, of an nvdimm namespace will fail forever as subsequent
calls to devm_memremap_pages() will fail to setup the pgmap_radix since
there will be stale entries for the physical address range.

Cc: 
Fixes: e8d513483300 ("memremap: change devm_memremap_pages interface...")
Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Reported-by: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 drivers/dax/pmem.c|   10 ++
 drivers/nvdimm/pmem.c |   18 --
 include/linux/memremap.h  |7 +--
 kernel/memremap.c |   36 +++-
 tools/testing/nvdimm/test/iomap.c |   21 ++---
 5 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index fd49b24fd6af..54cba20c8ba6 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -48,9 +48,8 @@ static void dax_pmem_percpu_exit(void *data)
percpu_ref_exit(ref);
 }
 
-static void dax_pmem_percpu_kill(void *data)
+static void dax_pmem_percpu_kill(struct percpu_ref *ref)
 {
-   struct percpu_ref *ref = data;
struct dax_pmem *dax_pmem = to_dax_pmem(ref);
 
dev_dbg(dax_pmem->dev, "trace\n");
@@ -111,15 +110,10 @@ static int dax_pmem_probe(struct device *dev)
return rc;
 
dax_pmem->pgmap.ref = _pmem->ref;
-   addr = devm_memremap_pages(dev, _pmem->pgmap);
+   addr = devm_memremap_pages(dev, _pmem->pgmap, dax_pmem_percpu_kill);
if (IS_ERR(addr))
return PTR_ERR(addr);
 
-   rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill,
-   _pmem->ref);
-   if (rc)
-   return rc;
-
/* adjust the dax_region resource to the start of data */
memcpy(, _pmem->pgmap.res, sizeof(res));
res.start += le64_to_cpu(pfn_sb->dataoff);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 9d714926ecf5..49c9c1bab438 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -279,8 +279,11 @@ static void pmem_release_queue(void *q)
blk_cleanup_queue(q);
 }
 
-static void pmem_freeze_queue(void *q)
+static void pmem_freeze_queue(struct percpu_ref *ref)
 {
+   struct request_queue *q;
+
+   q = container_of(ref, typeof(*q), q_usage_counter);
blk_freeze_queue_start(q);
 }
 
@@ -353,7 +356,8 @@ static int pmem_attach_disk(struct device *dev,
pmem->pfn_flags = PFN_DEV;
pmem->pgmap.ref = >q_usage_counter;
if (is_nd_pfn(dev)) {
-   addr = devm_memremap_pages(dev, >pgmap);
+   addr = devm_memremap_pages(dev, >pgmap,
+   pmem_freeze_queue);
pfn_sb = nd_pfn->pfn_sb;
pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
pmem->pfn_pad = resource_size(res) -
@@ -364,20 +368,14 @@ static int pmem_attach_disk(struct device *dev,
} else if (pmem_should_map_pages(dev)) {
memcpy(>pgmap.res, >res, sizeof(pmem->pgmap.res));
pmem->pgmap.altmap_valid = false;
-   addr = devm_memremap_pages(dev, >pgmap);
+   addr = devm_memremap_pages(dev, >pgmap,
+   pmem_freeze_queue);
pmem->pfn_flags |= PFN_MAP;
memcpy(_res, >pgmap.res, sizeof(bb_res));
} else
addr = devm_memremap(dev, pmem->phys_addr,
pmem->size, ARCH_MEMREMAP_PMEM);
 
-   /*
-* At release time the queue must be frozen before
-* devm_memremap_pages is unwound
-*/
-   if (devm_add_action_or_reset(dev, pmem_freeze_queue, q))
-   return -ENOMEM;
-
if (IS_ERR(addr))
return PTR_ERR(addr);
pmem->virt_addr = addr;
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 7b4899c06f49..b5e894133cf6 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -106,6 +106,7 @@ typedef void 

[PATCH v2 5/7] mm, hmm: Use devm semantics for hmm_devmem_{add, remove}

2018-05-22 Thread Dan Williams
devm semantics arrange for resources to be torn down when
device-driver-probe fails or when device-driver-release completes.
Similar to devm_memremap_pages() there is no need to support an explicit
remove operation when the users properly adhere to devm semantics.

Reviewed-by: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 Documentation/vm/hmm.txt |1 
 include/linux/hmm.h  |4 -
 mm/hmm.c |  127 +-
 3 files changed, 25 insertions(+), 107 deletions(-)

diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt
index 2d1d6f69e91b..b2f944b87c5e 100644
--- a/Documentation/vm/hmm.txt
+++ b/Documentation/vm/hmm.txt
@@ -285,7 +285,6 @@ region needing a struct page. This is offered through a 
very simple API:
  struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
struct device *device,
unsigned long size);
- void hmm_devmem_remove(struct hmm_devmem *devmem);
 
 The hmm_devmem_ops is where most of the important things are:
 
diff --git a/include/linux/hmm.h b/include/linux/hmm.h
index 39988924de3a..880f6bb9485c 100644
--- a/include/linux/hmm.h
+++ b/include/linux/hmm.h
@@ -499,8 +499,7 @@ struct hmm_devmem {
  * enough and allocate struct page for it.
  *
  * The device driver can wrap the hmm_devmem struct inside a private device
- * driver struct. The device driver must call hmm_devmem_remove() before the
- * device goes away and before freeing the hmm_devmem struct memory.
+ * driver struct.
  */
 struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
  struct device *device,
@@ -508,7 +507,6 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
 struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
   struct device *device,
   struct resource *res);
-void hmm_devmem_remove(struct hmm_devmem *devmem);
 
 /*
  * hmm_devmem_page_set_drvdata - set per-page driver data field
diff --git a/mm/hmm.c b/mm/hmm.c
index 486dc394a5a3..d081857f29b5 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -943,7 +943,6 @@ static void hmm_devmem_ref_exit(void *data)
 
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_exit(ref);
-   devm_remove_action(devmem->device, _devmem_ref_exit, data);
 }
 
 static void hmm_devmem_ref_kill(void *data)
@@ -954,7 +953,6 @@ static void hmm_devmem_ref_kill(void *data)
devmem = container_of(ref, struct hmm_devmem, ref);
percpu_ref_kill(ref);
wait_for_completion(>completion);
-   devm_remove_action(devmem->device, _devmem_ref_kill, data);
 }
 
 static int hmm_devmem_fault(struct vm_area_struct *vma,
@@ -993,7 +991,7 @@ static void hmm_devmem_radix_release(struct resource 
*resource)
mutex_unlock(_devmem_lock);
 }
 
-static void hmm_devmem_release(struct device *dev, void *data)
+static void hmm_devmem_release(void *data)
 {
struct hmm_devmem *devmem = data;
struct resource *resource = devmem->resource;
@@ -1001,11 +999,6 @@ static void hmm_devmem_release(struct device *dev, void 
*data)
struct zone *zone;
struct page *page;
 
-   if (percpu_ref_tryget_live(>ref)) {
-   dev_WARN(dev, "%s: page mapping is still live!\n", __func__);
-   percpu_ref_put(>ref);
-   }
-
/* pages are dead and unused, undo the arch mapping */
start_pfn = (resource->start & ~(PA_SECTION_SIZE - 1)) >> PAGE_SHIFT;
npages = ALIGN(resource_size(resource), PA_SECTION_SIZE) >> PAGE_SHIFT;
@@ -1129,19 +1122,6 @@ static int hmm_devmem_pages_create(struct hmm_devmem 
*devmem)
return ret;
 }
 
-static int hmm_devmem_match(struct device *dev, void *data, void *match_data)
-{
-   struct hmm_devmem *devmem = data;
-
-   return devmem->resource == match_data;
-}
-
-static void hmm_devmem_pages_remove(struct hmm_devmem *devmem)
-{
-   devres_release(devmem->device, _devmem_release,
-  _devmem_match, devmem->resource);
-}
-
 /*
  * hmm_devmem_add() - hotplug ZONE_DEVICE memory for device memory
  *
@@ -1169,8 +1149,7 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
 
static_branch_enable(_private_key);
 
-   devmem = devres_alloc_node(_devmem_release, sizeof(*devmem),
-  GFP_KERNEL, dev_to_node(device));
+   devmem = devm_kzalloc(device, sizeof(*devmem), GFP_KERNEL);
if (!devmem)
return ERR_PTR(-ENOMEM);
 
@@ -1184,11 +1163,11 @@ struct hmm_devmem *hmm_devmem_add(const struct 
hmm_devmem_ops *ops,
ret = percpu_ref_init(>ref, _devmem_ref_release,
  0, GFP_KERNEL);
if (ret)
-   goto error_percpu_ref;
+   return ERR_PTR(ret);
 
-  

[PATCH v2 2/7] mm, devm_memremap_pages: Kill mapping "System RAM" support

2018-05-22 Thread Dan Williams
Given the fact that devm_memremap_pages() requires a percpu_ref that is
torn down by devm_memremap_pages_release() the current support for
mapping RAM is broken.

This has been broken since forever and there is no use case to map RAM
in this way, so just kill the support and make it an explicit error.

Cc: Christoph Hellwig 
Cc: "Jérôme Glisse" 
Cc: Logan Gunthorpe 
Signed-off-by: Dan Williams 
---
 kernel/memremap.c |9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/kernel/memremap.c b/kernel/memremap.c
index c614645227a7..dd11607671eb 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -355,15 +355,12 @@ void *devm_memremap_pages(struct device *dev, struct 
dev_pagemap *pgmap)
is_ram = region_intersects(align_start, align_size,
IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
 
-   if (is_ram == REGION_MIXED) {
-   WARN_ONCE(1, "%s attempted on mixed region %pr\n",
-   __func__, res);
+   if (is_ram != REGION_DISJOINT) {
+   WARN_ONCE(1, "%s attempted on %s region %pr\n", __func__,
+   is_ram == REGION_MIXED ? "mixed" : "ram", res);
return ERR_PTR(-ENXIO);
}
 
-   if (is_ram == REGION_INTERSECTS)
-   return __va(res->start);
-
if (!pgmap->ref)
return ERR_PTR(-EINVAL);
 



[PATCH v2 0/7] mm: Rework hmm to use devm_memremap_pages

2018-05-22 Thread Dan Williams
Changes since v1: [1]
* Kill support for mapping System RAM as a nop. No one uses this
  functionality and it is broken relative to percpu_ref management.

* Fix percpu_ref teardown. Given that devm_memremap_pages() has strict
  assumptions about when the percpu_ref is killed, give it
  responsibility to make the live-dead transition explicitly. (Logan)

* Split the patch that adds HMM support to devm_memremap_pages() from
  the patch that converts HMM to use devm_memremap_pages(). This caught
  an incomplete conversion in v1. (Logan)

* Collect Christoph's reviewed-by.

[1]: https://lkml.org/lkml/2018/5/21/1109

---

Hi Andrew, here's v2 to replace the 5 currently in mm. The first and
last patch did not change.

For maintainability, as ZONE_DEVICE continues to attract new users,
it is useful to keep all users consolidated on devm_memremap_pages() as
the interface for create "device pages".

The devm_memremap_pages() implementation was recently reworked to make
it more generic for arbitrary users, like the proposed peer-to-peer
PCI-E enabling. HMM pre-dated this rework and opted to duplicate
devm_memremap_pages() as hmm_devmem_pages_create().

Rework HMM to be a consumer of devm_memremap_pages() directly and fix up
the licensing on the exports given the deep dependencies on the mm.

Patches based on v4.17-rc6 where there are no upstream consumers of the
HMM functionality.

---

Dan Williams (7):
  mm, devm_memremap_pages: Mark devm_memremap_pages() EXPORT_SYMBOL_GPL
  mm, devm_memremap_pages: Kill mapping "System RAM" support
  mm, devm_memremap_pages: Fix shutdown handling
  mm, devm_memremap_pages: Add MEMORY_DEVICE_PRIVATE support
  mm, hmm: Use devm semantics for hmm_devmem_{add,remove}
  mm, hmm: Replace hmm_devmem_pages_create() with devm_memremap_pages()
  mm, hmm: Mark hmm_devmem_{add,add_resource} EXPORT_SYMBOL_GPL


 Documentation/vm/hmm.txt  |1 
 drivers/dax/pmem.c|   10 -
 drivers/nvdimm/pmem.c |   18 +-
 include/linux/hmm.h   |4 
 include/linux/memremap.h  |7 +
 kernel/memremap.c |   85 +++---
 mm/hmm.c  |  307 +
 tools/testing/nvdimm/test/iomap.c |   21 ++-
 8 files changed, 130 insertions(+), 323 deletions(-)


[PATCH v2 0/7] mm: Rework hmm to use devm_memremap_pages

2018-05-22 Thread Dan Williams
Changes since v1: [1]
* Kill support for mapping System RAM as a nop. No one uses this
  functionality and it is broken relative to percpu_ref management.

* Fix percpu_ref teardown. Given that devm_memremap_pages() has strict
  assumptions about when the percpu_ref is killed, give it
  responsibility to make the live-dead transition explicitly. (Logan)

* Split the patch that adds HMM support to devm_memremap_pages() from
  the patch that converts HMM to use devm_memremap_pages(). This caught
  an incomplete conversion in v1. (Logan)

* Collect Christoph's reviewed-by.

[1]: https://lkml.org/lkml/2018/5/21/1109

---

Hi Andrew, here's v2 to replace the 5 currently in mm. The first and
last patch did not change.

For maintainability, as ZONE_DEVICE continues to attract new users,
it is useful to keep all users consolidated on devm_memremap_pages() as
the interface for create "device pages".

The devm_memremap_pages() implementation was recently reworked to make
it more generic for arbitrary users, like the proposed peer-to-peer
PCI-E enabling. HMM pre-dated this rework and opted to duplicate
devm_memremap_pages() as hmm_devmem_pages_create().

Rework HMM to be a consumer of devm_memremap_pages() directly and fix up
the licensing on the exports given the deep dependencies on the mm.

Patches based on v4.17-rc6 where there are no upstream consumers of the
HMM functionality.

---

Dan Williams (7):
  mm, devm_memremap_pages: Mark devm_memremap_pages() EXPORT_SYMBOL_GPL
  mm, devm_memremap_pages: Kill mapping "System RAM" support
  mm, devm_memremap_pages: Fix shutdown handling
  mm, devm_memremap_pages: Add MEMORY_DEVICE_PRIVATE support
  mm, hmm: Use devm semantics for hmm_devmem_{add,remove}
  mm, hmm: Replace hmm_devmem_pages_create() with devm_memremap_pages()
  mm, hmm: Mark hmm_devmem_{add,add_resource} EXPORT_SYMBOL_GPL


 Documentation/vm/hmm.txt  |1 
 drivers/dax/pmem.c|   10 -
 drivers/nvdimm/pmem.c |   18 +-
 include/linux/hmm.h   |4 
 include/linux/memremap.h  |7 +
 kernel/memremap.c |   85 +++---
 mm/hmm.c  |  307 +
 tools/testing/nvdimm/test/iomap.c |   21 ++-
 8 files changed, 130 insertions(+), 323 deletions(-)


Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Dan Williams
On Tue, May 22, 2018 at 10:03 PM, Gustavo A. R. Silva
 wrote:
>
>
> On 05/22/2018 03:50 PM, Dan Williams wrote:


 Dan,

 What do you think about this first draft:

 diff --git a/include/linux/nospec.h b/include/linux/nospec.h
 index e791ebc..6154183 100644
 --- a/include/linux/nospec.h
 +++ b/include/linux/nospec.h
 @@ -55,4 +55,16 @@ static inline unsigned long
 array_index_mask_nospec(unsigned long index,

 \
   (typeof(_i)) (_i & _mask);
 \
})
 +
 +#define validate_index_nospec(index, size)\
 +({\
 +   typeof(index) *ptr = &(index); \
 +   typeof(size) _s = (size);  \
 +  \
 +   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
 +   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
 +  \
 +   *ptr >= _s ? false :   \
 +   (*ptr = array_index_nospec(*ptr, _s) ? true : true);   \
>>>
>>>
>>>
>>> This actually should be:
>>>
>>> ((*ptr = array_index_nospec(*ptr, _s)) ? true : true);
>>>
>>
>> Let's not use ternary conditionals at all to make this more readable.
>>
>
> OK. How about this:
>
> diff --git a/include/linux/nospec.h b/include/linux/nospec.h
> index e791ebc..498995b 100644
> --- a/include/linux/nospec.h
> +++ b/include/linux/nospec.h
> @@ -55,4 +55,21 @@ static inline unsigned long
> array_index_mask_nospec(unsigned long index,
>\
> (typeof(_i)) (_i & _mask); \
>  })
> +
> +#define validate_index_nospec(index, size)\
> +({\
> +   bool ret = true;   \
> +   typeof(index) *ptr = &(index); \
> +   typeof(size) _s = (size);  \
> +  \
> +   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
> +   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
> +  \
> +   if (*ptr >= size)  \
> +   ret = false;   \
> +  \
> +   *ptr = array_index_nospec(*ptr, _s);   \
> +  \
> +   ret;   \
>
> +})
>  #endif /* _LINUX_NOSPEC_H */

Assuming the assembly generation is comparable with the open coded
version, this looks ok to me.


Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Dan Williams
On Tue, May 22, 2018 at 10:03 PM, Gustavo A. R. Silva
 wrote:
>
>
> On 05/22/2018 03:50 PM, Dan Williams wrote:


 Dan,

 What do you think about this first draft:

 diff --git a/include/linux/nospec.h b/include/linux/nospec.h
 index e791ebc..6154183 100644
 --- a/include/linux/nospec.h
 +++ b/include/linux/nospec.h
 @@ -55,4 +55,16 @@ static inline unsigned long
 array_index_mask_nospec(unsigned long index,

 \
   (typeof(_i)) (_i & _mask);
 \
})
 +
 +#define validate_index_nospec(index, size)\
 +({\
 +   typeof(index) *ptr = &(index); \
 +   typeof(size) _s = (size);  \
 +  \
 +   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
 +   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
 +  \
 +   *ptr >= _s ? false :   \
 +   (*ptr = array_index_nospec(*ptr, _s) ? true : true);   \
>>>
>>>
>>>
>>> This actually should be:
>>>
>>> ((*ptr = array_index_nospec(*ptr, _s)) ? true : true);
>>>
>>
>> Let's not use ternary conditionals at all to make this more readable.
>>
>
> OK. How about this:
>
> diff --git a/include/linux/nospec.h b/include/linux/nospec.h
> index e791ebc..498995b 100644
> --- a/include/linux/nospec.h
> +++ b/include/linux/nospec.h
> @@ -55,4 +55,21 @@ static inline unsigned long
> array_index_mask_nospec(unsigned long index,
>\
> (typeof(_i)) (_i & _mask); \
>  })
> +
> +#define validate_index_nospec(index, size)\
> +({\
> +   bool ret = true;   \
> +   typeof(index) *ptr = &(index); \
> +   typeof(size) _s = (size);  \
> +  \
> +   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
> +   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
> +  \
> +   if (*ptr >= size)  \
> +   ret = false;   \
> +  \
> +   *ptr = array_index_nospec(*ptr, _s);   \
> +  \
> +   ret;   \
>
> +})
>  #endif /* _LINUX_NOSPEC_H */

Assuming the assembly generation is comparable with the open coded
version, this looks ok to me.


Re: [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings

2018-05-22 Thread Doug Anderson
Hi,

On Tue, May 22, 2018 at 6:19 PM, David Collins  wrote:
 OK, so how's this for a proposal then:

 1. For RPMh-regulator whenever we see a "set voltage" but Linux hasn't
 specified that the regulator is enabled then we don't send the
 voltage, we just cache it.

 2. When we see the first enable then we first send the cached voltage
 and then do the enable.

 3. We don't need an "initial voltage" because any rails that are
 expected to be variable voltage the client should be choosing a
 voltage.


 ...taking the SD card case as an example: if the regulator framework
 says "set to the minimum: 1.8V" we'll cache this but not apply it yet
 because the rail is off as far as Linux is concerned.  Then when the
 SD card framework starts up it will set the voltage to 3.3V which will
 overwrite the cache.  Then the SD card framework will enable the
 regulator and RPMh will set the voltage to 3.3V and enable.
>>>
>>> I am ok with implementing this feature.
>>>
>>> However, should the voltage be cached instead of sent immediately any time
>>> that Linux has not explicitly requested the regulator to be enabled, or
>>> only before the first time that an enable request is sent?
>>>
>>> 1. regulator_set_voltage(reg, 296, 296)
>>>--> cache voltage=2960 mV
>>> 2. regulator_enable(reg)
>>>--> Send voltage=2960 then enable=1
>>> 3. regulator_disable(reg)
>>>--> Send enable=0
>>> 4. regulator_set_voltage(reg, 180, 296)
>>>--> A. Send voltage=1800 OR B. cache voltage=1800?
>>>
>>> Option A is used on the downstream rpmh-regulator driver in order to avoid
>>> cases where AP votes to disable a regulator that is kept enabled by
>>> another subsystem but then does not lower the voltage requested thanks to
>>> regulator_set_voltage() being called after regulator_disable().  I plan to
>>> go with option A for qcom-rpmh-regulator unless there are objections.
>>
>> So one client's vote for a voltage continues to be in effect even if
>> that client votes to have the regulator disabled?  That seems
>> fundamentally broken in RPMh.  I guess my take would be to work around
>> this RPMh misfeature by saying that whenever Linux votes to disable a
>> regulator it also votes for a voltage of 0.  Then another client of
>> RPMh won't be affected.
>>
>> That seems like it would be beneficial in any case.  If the AP always
>> asks for 1.3 V and the modem always asks for 1.1 V for the same rail
>> then the rail should go down to 1.1 V when the AP says to disable the
>> rail.
>
> The VRM in RPMh hardware aggregates enable state, output voltage, mode,
> and headroom voltage requests independently for each regulator.  This
> allows for maximum request flexibility and makes no assumptions about
> consumer use cases.  There is nothing inherently wrong about this approach.

Just to confirm I'm understanding correctly:

1. AP: request that regulator A be at 1.3 V and enabled
==> actual output: regulator A is 1.3 V and enabled

2. modem: requests that regulator A be at 1.1 V and enabled
==> actual output: regulator A is 1.3 V and enabled

3. AP: request that regulator A be disabled

You're saying that here the output of regulator A will be "1.3 V" and
"enabled".

I just can't see how that can be correct behavior.  A given client's
vote for the voltage should really only make sense if that client
wants the regulator enabled.  In the case above the kernel would have
no idea that someone else might have the regulator enabled.  Why would
it care if that other user gets it at 1.3 V or at 1.1 V?

You have some use case in mind where the kernel would need to have
control over the voltage of a regulator that it thinks is disabled?

Now obviously if the kernel re-enables the regulator then its old
voltage vote should be re-instated right away, but until then its vote
about the voltage shouldn't count.  If that means that the kernel has
to "vote" for 0V then I guess that's the way the API works.


> I'm concerned about a blanket policy of setting voltage=0 when issuing
> disable requests.  That seems to violate the semantics of the
> regulator_set_voltage() API which enforces the requested voltage range
> until a new range is specified.  There may be workarounds that require a
> regulator to operate at a specific voltage even when no Linux consumers
> explicitly need the regulator enabled.
>
> Given that not masking the voltage on disable is guaranteed to be safe and
> does not silently break potential use cases, I plan to stick with this
> approach.  Therefore, the question about option A or B for voltage caching
> is still relevant.  I think that option A is safer/more API conforming so
> I plan to implement that.

I still can't understand how it ever makes sense to vote for a voltage
for a regulator that you think is disabled.  ...but if there's some
reason it does then I guess I'm OK with A.


 This whole thing makes 

Re: [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings

2018-05-22 Thread Doug Anderson
Hi,

On Tue, May 22, 2018 at 6:19 PM, David Collins  wrote:
 OK, so how's this for a proposal then:

 1. For RPMh-regulator whenever we see a "set voltage" but Linux hasn't
 specified that the regulator is enabled then we don't send the
 voltage, we just cache it.

 2. When we see the first enable then we first send the cached voltage
 and then do the enable.

 3. We don't need an "initial voltage" because any rails that are
 expected to be variable voltage the client should be choosing a
 voltage.


 ...taking the SD card case as an example: if the regulator framework
 says "set to the minimum: 1.8V" we'll cache this but not apply it yet
 because the rail is off as far as Linux is concerned.  Then when the
 SD card framework starts up it will set the voltage to 3.3V which will
 overwrite the cache.  Then the SD card framework will enable the
 regulator and RPMh will set the voltage to 3.3V and enable.
>>>
>>> I am ok with implementing this feature.
>>>
>>> However, should the voltage be cached instead of sent immediately any time
>>> that Linux has not explicitly requested the regulator to be enabled, or
>>> only before the first time that an enable request is sent?
>>>
>>> 1. regulator_set_voltage(reg, 296, 296)
>>>--> cache voltage=2960 mV
>>> 2. regulator_enable(reg)
>>>--> Send voltage=2960 then enable=1
>>> 3. regulator_disable(reg)
>>>--> Send enable=0
>>> 4. regulator_set_voltage(reg, 180, 296)
>>>--> A. Send voltage=1800 OR B. cache voltage=1800?
>>>
>>> Option A is used on the downstream rpmh-regulator driver in order to avoid
>>> cases where AP votes to disable a regulator that is kept enabled by
>>> another subsystem but then does not lower the voltage requested thanks to
>>> regulator_set_voltage() being called after regulator_disable().  I plan to
>>> go with option A for qcom-rpmh-regulator unless there are objections.
>>
>> So one client's vote for a voltage continues to be in effect even if
>> that client votes to have the regulator disabled?  That seems
>> fundamentally broken in RPMh.  I guess my take would be to work around
>> this RPMh misfeature by saying that whenever Linux votes to disable a
>> regulator it also votes for a voltage of 0.  Then another client of
>> RPMh won't be affected.
>>
>> That seems like it would be beneficial in any case.  If the AP always
>> asks for 1.3 V and the modem always asks for 1.1 V for the same rail
>> then the rail should go down to 1.1 V when the AP says to disable the
>> rail.
>
> The VRM in RPMh hardware aggregates enable state, output voltage, mode,
> and headroom voltage requests independently for each regulator.  This
> allows for maximum request flexibility and makes no assumptions about
> consumer use cases.  There is nothing inherently wrong about this approach.

Just to confirm I'm understanding correctly:

1. AP: request that regulator A be at 1.3 V and enabled
==> actual output: regulator A is 1.3 V and enabled

2. modem: requests that regulator A be at 1.1 V and enabled
==> actual output: regulator A is 1.3 V and enabled

3. AP: request that regulator A be disabled

You're saying that here the output of regulator A will be "1.3 V" and
"enabled".

I just can't see how that can be correct behavior.  A given client's
vote for the voltage should really only make sense if that client
wants the regulator enabled.  In the case above the kernel would have
no idea that someone else might have the regulator enabled.  Why would
it care if that other user gets it at 1.3 V or at 1.1 V?

You have some use case in mind where the kernel would need to have
control over the voltage of a regulator that it thinks is disabled?

Now obviously if the kernel re-enables the regulator then its old
voltage vote should be re-instated right away, but until then its vote
about the voltage shouldn't count.  If that means that the kernel has
to "vote" for 0V then I guess that's the way the API works.


> I'm concerned about a blanket policy of setting voltage=0 when issuing
> disable requests.  That seems to violate the semantics of the
> regulator_set_voltage() API which enforces the requested voltage range
> until a new range is specified.  There may be workarounds that require a
> regulator to operate at a specific voltage even when no Linux consumers
> explicitly need the regulator enabled.
>
> Given that not masking the voltage on disable is guaranteed to be safe and
> does not silently break potential use cases, I plan to stick with this
> approach.  Therefore, the question about option A or B for voltage caching
> is still relevant.  I think that option A is safer/more API conforming so
> I plan to implement that.

I still can't understand how it ever makes sense to vote for a voltage
for a regulator that you think is disabled.  ...but if there's some
reason it does then I guess I'm OK with A.


 This whole thing makes me worry about another 

Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Gustavo A. R. Silva



On 05/22/2018 03:50 PM, Dan Williams wrote:


Dan,

What do you think about this first draft:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..6154183 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,16 @@ static inline unsigned long
array_index_mask_nospec(unsigned long index,
 \
  (typeof(_i)) (_i & _mask); \
   })
+
+#define validate_index_nospec(index, size)\
+({\
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   *ptr >= _s ? false :   \
+   (*ptr = array_index_nospec(*ptr, _s) ? true : true);   \



This actually should be:

((*ptr = array_index_nospec(*ptr, _s)) ? true : true);



Let's not use ternary conditionals at all to make this more readable.



OK. How about this:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..498995b 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,21 @@ static inline unsigned long 
array_index_mask_nospec(unsigned long index,

   \
(typeof(_i)) (_i & _mask); \
 })
+
+#define validate_index_nospec(index, size)\
+({\
+   bool ret = true;   \
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   if (*ptr >= size)  \
+   ret = false;   \
+  \
+   *ptr = array_index_nospec(*ptr, _s);   \
+  \
+   ret;   \
+})
 #endif /* _LINUX_NOSPEC_H */

Thanks
--
Gustavo


Re: [PATCH] kernel: sys: fix potential Spectre v1

2018-05-22 Thread Gustavo A. R. Silva



On 05/22/2018 03:50 PM, Dan Williams wrote:


Dan,

What do you think about this first draft:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..6154183 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,16 @@ static inline unsigned long
array_index_mask_nospec(unsigned long index,
 \
  (typeof(_i)) (_i & _mask); \
   })
+
+#define validate_index_nospec(index, size)\
+({\
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   *ptr >= _s ? false :   \
+   (*ptr = array_index_nospec(*ptr, _s) ? true : true);   \



This actually should be:

((*ptr = array_index_nospec(*ptr, _s)) ? true : true);



Let's not use ternary conditionals at all to make this more readable.



OK. How about this:

diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index e791ebc..498995b 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,21 @@ static inline unsigned long 
array_index_mask_nospec(unsigned long index,

   \
(typeof(_i)) (_i & _mask); \
 })
+
+#define validate_index_nospec(index, size)\
+({\
+   bool ret = true;   \
+   typeof(index) *ptr = &(index); \
+   typeof(size) _s = (size);  \
+  \
+   BUILD_BUG_ON(sizeof(*ptr) > sizeof(long)); \
+   BUILD_BUG_ON(sizeof(_s) > sizeof(long));   \
+  \
+   if (*ptr >= size)  \
+   ret = false;   \
+  \
+   *ptr = array_index_nospec(*ptr, _s);   \
+  \
+   ret;   \
+})
 #endif /* _LINUX_NOSPEC_H */

Thanks
--
Gustavo


Re: [PATCH v4 1/2] vfio/mdev: Check globally for duplicate devices

2018-05-22 Thread Zhenyu Wang
On 2018.05.22 09:53:37 -0600, Alex Williamson wrote:
> [Cc +GVT-g maintainers/lists]
> 
> On Tue, 22 May 2018 10:13:46 +0200
> Cornelia Huck  wrote:
> 
> > On Fri, 18 May 2018 13:10:25 -0600
> > Alex Williamson  wrote:
> > 
> > > When we create an mdev device, we check for duplicates against the
> > > parent device and return -EEXIST if found, but the mdev device
> > > namespace is global since we'll link all devices from the bus.  We do
> > > catch this later in sysfs_do_create_link_sd() to return -EEXIST, but
> > > with it comes a kernel warning and stack trace for trying to create
> > > duplicate sysfs links, which makes it an undesirable response.
> > > 
> > > Therefore we should really be looking for duplicates across all mdev
> > > parent devices, or as implemented here, against our mdev device list.
> > > Using mdev_list to prevent duplicates means that we can remove
> > > mdev_parent.lock, but in order not to serialize mdev device creation
> > > and removal globally, we add mdev_device.active which allows UUIDs to
> > > be reserved such that we can drop the mdev_list_lock before the mdev
> > > device is fully in place.
> > > 
> > > Two behavioral notes; first, mdev_parent.lock had the side-effect of
> > > serializing mdev create and remove ops per parent device.  This was
> > > an implementation detail, not an intentional guarantee provided to
> > > the mdev vendor drivers.  Vendor drivers can trivially provide this
> > > serialization internally if necessary.  Second, review comments note
> > > the new -EAGAIN behavior when the device, and in particular the remove
> > > attribute, becomes visible in sysfs.  If a remove is triggered prior
> > > to completion of mdev_device_create() the user will see a -EAGAIN
> > > error.  While the errno is different, receiving an error during this
> > > period is not, the previous implementation returned -ENODEV for the
> > > same condition.  Furthermore, the consistency to the user is improved
> > > in the case where mdev_device_remove_ops() returns error.  Previously
> > > concurrent calls to mdev_device_remove() could see the device
> > > disappear with -ENODEV and return in the case of error.  Now a user
> > > would see -EAGAIN while the device is in this transitory state.
> > > 
> > > Signed-off-by: Alex Williamson 
> > > ---
> > >  Documentation/vfio-mediated-device.txt |5 ++
> > >  drivers/vfio/mdev/mdev_core.c  |  102 
> > > +++-
> > >  drivers/vfio/mdev/mdev_private.h   |2 -
> > >  3 files changed, 42 insertions(+), 67 deletions(-)  
> > 
> > Reviewed-by: Cornelia Huck 
> > 
> > I think it is better to deal with any possible vendor driver
> > implications on top of this (I still believe that vfio-ccw is fine).
> 
> Thanks Cornelia.  So if vfio-ccw is fine, presumably NVIDIA is fine,
> then this leaves GVT-g to see if there's any fallout.  Zhenyu & Zhi,
> I've linked the series under discussion here below[1].  The question to
> you is the first of the two behavioral notes listed above, does GVT-g
> have any dependency on the mdev core providing serialization per mdev
> parent device for the create and remove callbacks within the
> mdev_parent_ops?  This was never an intended feature of the
> implementation and as noted it should be trivial for for an mdev vendor
> driver to provide equivalent course grained serialization if
> necessary.  Of course it would be better to implement that sooner
> rather than later if required.
> 
> I see that __intel_gvt_create_vgpu() makes use of gvt->lock, which
> would seem to already provide this level of per-parent locking. The
> remove path makes use of this same lock, so I think we're ok, but
> looking for an explicit ack so there are no surprises.  I'd like
> to queue this series for v4.18.  Thanks,
> 

yeah, we don't expect mdev core for parent serialization for create and
remove of mdev device. Series look good to me.

Acked-by: Zhenyu Wang 


> Alex
> 
> [1] https://lkml.org/lkml/2018/5/18/1035

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827


signature.asc
Description: PGP signature


Re: [PATCH v4 1/2] vfio/mdev: Check globally for duplicate devices

2018-05-22 Thread Zhenyu Wang
On 2018.05.22 09:53:37 -0600, Alex Williamson wrote:
> [Cc +GVT-g maintainers/lists]
> 
> On Tue, 22 May 2018 10:13:46 +0200
> Cornelia Huck  wrote:
> 
> > On Fri, 18 May 2018 13:10:25 -0600
> > Alex Williamson  wrote:
> > 
> > > When we create an mdev device, we check for duplicates against the
> > > parent device and return -EEXIST if found, but the mdev device
> > > namespace is global since we'll link all devices from the bus.  We do
> > > catch this later in sysfs_do_create_link_sd() to return -EEXIST, but
> > > with it comes a kernel warning and stack trace for trying to create
> > > duplicate sysfs links, which makes it an undesirable response.
> > > 
> > > Therefore we should really be looking for duplicates across all mdev
> > > parent devices, or as implemented here, against our mdev device list.
> > > Using mdev_list to prevent duplicates means that we can remove
> > > mdev_parent.lock, but in order not to serialize mdev device creation
> > > and removal globally, we add mdev_device.active which allows UUIDs to
> > > be reserved such that we can drop the mdev_list_lock before the mdev
> > > device is fully in place.
> > > 
> > > Two behavioral notes; first, mdev_parent.lock had the side-effect of
> > > serializing mdev create and remove ops per parent device.  This was
> > > an implementation detail, not an intentional guarantee provided to
> > > the mdev vendor drivers.  Vendor drivers can trivially provide this
> > > serialization internally if necessary.  Second, review comments note
> > > the new -EAGAIN behavior when the device, and in particular the remove
> > > attribute, becomes visible in sysfs.  If a remove is triggered prior
> > > to completion of mdev_device_create() the user will see a -EAGAIN
> > > error.  While the errno is different, receiving an error during this
> > > period is not, the previous implementation returned -ENODEV for the
> > > same condition.  Furthermore, the consistency to the user is improved
> > > in the case where mdev_device_remove_ops() returns error.  Previously
> > > concurrent calls to mdev_device_remove() could see the device
> > > disappear with -ENODEV and return in the case of error.  Now a user
> > > would see -EAGAIN while the device is in this transitory state.
> > > 
> > > Signed-off-by: Alex Williamson 
> > > ---
> > >  Documentation/vfio-mediated-device.txt |5 ++
> > >  drivers/vfio/mdev/mdev_core.c  |  102 
> > > +++-
> > >  drivers/vfio/mdev/mdev_private.h   |2 -
> > >  3 files changed, 42 insertions(+), 67 deletions(-)  
> > 
> > Reviewed-by: Cornelia Huck 
> > 
> > I think it is better to deal with any possible vendor driver
> > implications on top of this (I still believe that vfio-ccw is fine).
> 
> Thanks Cornelia.  So if vfio-ccw is fine, presumably NVIDIA is fine,
> then this leaves GVT-g to see if there's any fallout.  Zhenyu & Zhi,
> I've linked the series under discussion here below[1].  The question to
> you is the first of the two behavioral notes listed above, does GVT-g
> have any dependency on the mdev core providing serialization per mdev
> parent device for the create and remove callbacks within the
> mdev_parent_ops?  This was never an intended feature of the
> implementation and as noted it should be trivial for for an mdev vendor
> driver to provide equivalent course grained serialization if
> necessary.  Of course it would be better to implement that sooner
> rather than later if required.
> 
> I see that __intel_gvt_create_vgpu() makes use of gvt->lock, which
> would seem to already provide this level of per-parent locking. The
> remove path makes use of this same lock, so I think we're ok, but
> looking for an explicit ack so there are no surprises.  I'd like
> to queue this series for v4.18.  Thanks,
> 

yeah, we don't expect mdev core for parent serialization for create and
remove of mdev device. Series look good to me.

Acked-by: Zhenyu Wang 


> Alex
> 
> [1] https://lkml.org/lkml/2018/5/18/1035

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827


signature.asc
Description: PGP signature


Re: [PATCH] cpufreq / CPPC: Add cpuinfo_cur_freq support for CPPC

2018-05-22 Thread Viresh Kumar
On 22-05-18, 04:42, George Cherian wrote:
> Per Section 8.4.7.1.3 of ACPI 6.2, The platform provides performance
> feedback via set of performance counters. To determine the actual
> performance level delivered over time, OSPM may read a set of
> performance counters from the Reference Performance Counter Register
> and the Delivered Performance Counter Register.
> 
> OSPM calculates the delivered performance over a given time period by
> taking a beginning and ending snapshot of both the reference and
> delivered performance counters, and calculating:
> 
> delivered_perf = reference_perf X (delta of delivered_perf counter / delta of 
> reference_perf counter).
> 
> Implement the above and hook this to the cpufreq->get method.
> 
> Signed-off-by: George Cherian 
> ---
>  drivers/cpufreq/cppc_cpufreq.c | 44 
> ++
>  1 file changed, 44 insertions(+)

Acked-by: Viresh Kumar 

-- 
viresh


Re: [PATCH] cpufreq / CPPC: Add cpuinfo_cur_freq support for CPPC

2018-05-22 Thread Viresh Kumar
On 22-05-18, 04:42, George Cherian wrote:
> Per Section 8.4.7.1.3 of ACPI 6.2, The platform provides performance
> feedback via set of performance counters. To determine the actual
> performance level delivered over time, OSPM may read a set of
> performance counters from the Reference Performance Counter Register
> and the Delivered Performance Counter Register.
> 
> OSPM calculates the delivered performance over a given time period by
> taking a beginning and ending snapshot of both the reference and
> delivered performance counters, and calculating:
> 
> delivered_perf = reference_perf X (delta of delivered_perf counter / delta of 
> reference_perf counter).
> 
> Implement the above and hook this to the cpufreq->get method.
> 
> Signed-off-by: George Cherian 
> ---
>  drivers/cpufreq/cppc_cpufreq.c | 44 
> ++
>  1 file changed, 44 insertions(+)

Acked-by: Viresh Kumar 

-- 
viresh


Re: [PATCH 8/9] PM / Domains: Add support for multi PM domains per device to genpd

2018-05-22 Thread Rajendra Nayak


On 05/23/2018 02:25 AM, Jon Hunter wrote:
> 
> On 22/05/18 15:47, Ulf Hansson wrote:
>> [...]
>>

 +/**
 + * genpd_dev_pm_attach_by_id() - Attach a device to one of its PM domain.
 + * @dev: Device to attach.
 + * @index: The index of the PM domain.
 + *
 + * Parse device's OF node to find a PM domain specifier at the provided 
 @index.
 + * If such is found, allocates a new device and attaches it to retrieved
 + * pm_domain ops.
 + *
 + * Returns the allocated device if successfully attached PM domain, NULL 
 when
 + * the device don't need a PM domain or have a single PM domain, else 
 PTR_ERR()
 + * in case of failures. Note that if a power-domain exists for the 
 device, but
 + * cannot be found or turned on, then return PTR_ERR(-EPROBE_DEFER) to 
 ensure
 + * that the device is not probed and to re-try again later.
 + */
 +struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 +  unsigned int index)
 +{
 + struct device *genpd_dev;
 + int num_domains;
 + int ret;
 +
 + if (!dev->of_node)
 + return NULL;
 +
 + /* Deal only with devices using multiple PM domains. */
 + num_domains = of_count_phandle_with_args(dev->of_node, 
 "power-domains",
 +  "#power-domain-cells");
 + if (num_domains < 2 || index >= num_domains)
 + return NULL;
 +
 + /* Allocate and register device on the genpd bus. */
 + genpd_dev = kzalloc(sizeof(*genpd_dev), GFP_KERNEL);
 + if (!genpd_dev)
 + return ERR_PTR(-ENOMEM);
 +
 + dev_set_name(genpd_dev, "genpd:%u:%s", index, dev_name(dev));
 + genpd_dev->bus = _bus_type;
 + genpd_dev->release = genpd_release_dev;
 +
 + ret = device_register(genpd_dev);
 + if (ret) {
 + kfree(genpd_dev);
 + return ERR_PTR(ret);
 + }
 +
 + /* Try to attach the device to the PM domain at the specified index. 
 */
 + ret = __genpd_dev_pm_attach(genpd_dev, dev->of_node, index);
 + if (ret < 1) {
 + device_unregister(genpd_dev);
 + return ret ? ERR_PTR(ret) : NULL;
 + }
 +
 + pm_runtime_set_active(genpd_dev);
 + pm_runtime_enable(genpd_dev);
 +
 + return genpd_dev;
 +}
 +EXPORT_SYMBOL_GPL(genpd_dev_pm_attach_by_id);
>>>
>>> Thanks for sending this. Believe it or not this has still been on my to-do 
>>> list
>>> and so we definitely need a solution for Tegra.
>>>
>>> Looking at the above it appears that additional power-domains exposed as 
>>> devices
>>> to the client device. So I assume that this means that the drivers for 
>>> devices
>>> with multiple power-domains will need to call RPM APIs for each of these
>>> additional power-domains. Is that correct?
>>
>> They can, but should not!
>>
>> Instead, the driver shall use device_link_add() and device_link_del(),
>> dynamically, depending on what PM domain that their original device
>> needs for the current running use case.
>>
>> In that way, they keep existing runtime PM deployment, operating on
>> its original device.
> 
> OK, sounds good. Any reason why the linking cannot be handled by the above 
> API? Is there a use-case where you would not want it linked?

I am guessing the linking is what would give the driver the ability to decide 
which subset of powerdomains it actually wants to control
at any point using runtime PM. If we have cases wherein the driver would want 
to turn on/off _all_ its associated powerdomains _always_
then a default linking of all would help.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation


Re: [PATCH 8/9] PM / Domains: Add support for multi PM domains per device to genpd

2018-05-22 Thread Rajendra Nayak


On 05/23/2018 02:25 AM, Jon Hunter wrote:
> 
> On 22/05/18 15:47, Ulf Hansson wrote:
>> [...]
>>

 +/**
 + * genpd_dev_pm_attach_by_id() - Attach a device to one of its PM domain.
 + * @dev: Device to attach.
 + * @index: The index of the PM domain.
 + *
 + * Parse device's OF node to find a PM domain specifier at the provided 
 @index.
 + * If such is found, allocates a new device and attaches it to retrieved
 + * pm_domain ops.
 + *
 + * Returns the allocated device if successfully attached PM domain, NULL 
 when
 + * the device don't need a PM domain or have a single PM domain, else 
 PTR_ERR()
 + * in case of failures. Note that if a power-domain exists for the 
 device, but
 + * cannot be found or turned on, then return PTR_ERR(-EPROBE_DEFER) to 
 ensure
 + * that the device is not probed and to re-try again later.
 + */
 +struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 +  unsigned int index)
 +{
 + struct device *genpd_dev;
 + int num_domains;
 + int ret;
 +
 + if (!dev->of_node)
 + return NULL;
 +
 + /* Deal only with devices using multiple PM domains. */
 + num_domains = of_count_phandle_with_args(dev->of_node, 
 "power-domains",
 +  "#power-domain-cells");
 + if (num_domains < 2 || index >= num_domains)
 + return NULL;
 +
 + /* Allocate and register device on the genpd bus. */
 + genpd_dev = kzalloc(sizeof(*genpd_dev), GFP_KERNEL);
 + if (!genpd_dev)
 + return ERR_PTR(-ENOMEM);
 +
 + dev_set_name(genpd_dev, "genpd:%u:%s", index, dev_name(dev));
 + genpd_dev->bus = _bus_type;
 + genpd_dev->release = genpd_release_dev;
 +
 + ret = device_register(genpd_dev);
 + if (ret) {
 + kfree(genpd_dev);
 + return ERR_PTR(ret);
 + }
 +
 + /* Try to attach the device to the PM domain at the specified index. 
 */
 + ret = __genpd_dev_pm_attach(genpd_dev, dev->of_node, index);
 + if (ret < 1) {
 + device_unregister(genpd_dev);
 + return ret ? ERR_PTR(ret) : NULL;
 + }
 +
 + pm_runtime_set_active(genpd_dev);
 + pm_runtime_enable(genpd_dev);
 +
 + return genpd_dev;
 +}
 +EXPORT_SYMBOL_GPL(genpd_dev_pm_attach_by_id);
>>>
>>> Thanks for sending this. Believe it or not this has still been on my to-do 
>>> list
>>> and so we definitely need a solution for Tegra.
>>>
>>> Looking at the above it appears that additional power-domains exposed as 
>>> devices
>>> to the client device. So I assume that this means that the drivers for 
>>> devices
>>> with multiple power-domains will need to call RPM APIs for each of these
>>> additional power-domains. Is that correct?
>>
>> They can, but should not!
>>
>> Instead, the driver shall use device_link_add() and device_link_del(),
>> dynamically, depending on what PM domain that their original device
>> needs for the current running use case.
>>
>> In that way, they keep existing runtime PM deployment, operating on
>> its original device.
> 
> OK, sounds good. Any reason why the linking cannot be handled by the above 
> API? Is there a use-case where you would not want it linked?

I am guessing the linking is what would give the driver the ability to decide 
which subset of powerdomains it actually wants to control
at any point using runtime PM. If we have cases wherein the driver would want 
to turn on/off _all_ its associated powerdomains _always_
then a default linking of all would help.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation


Re: B53 DSA switch problem on Banana Pi-R1 on Fedora 26

2018-05-22 Thread Gerhard Wiesinger

On 22.05.2018 22:42, Florian Fainelli wrote:

On 05/22/2018 01:16 PM, Andrew Lunn wrote:

Planned network structure will be as with 4.7.x kernels:

br0 <=> eth0.101 <=> eth0 (vlan 101 tagged) <=> lan 1-lan4 (vlan 101
untagged pvid)

br1 <=> eth0.102 <=> eth0 (vlan 102 tagged) <=> wan (vlan 102 untagged pvid)

Do you even need these vlans?

Yes, remember, b53 does not currently turn on Broadcom tags, so the only
way to segregate traffic is to have VLANs for that.


Are you doing this for port separation? To keep lan1-4 traffic
separate from wan? DSA does that by default, no vlan needed.

So you can just do

ip link add name br0 type bridge
ip link set dev br0 up
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0
ip link set dev lan4 master br0

and use interface wan directly, no bridge needed.

That would work once Broadcom tags are turned on which requires turning
on managed mode, which requires work that I have not been able to get
done :)


Setup with swconfig:

#!/usr/bin/bash


INTERFACE=eth0

# Delete all IP addresses and get link up
ip addr flush dev ${INTERFACE}
ip link set ${INTERFACE} up

# Lamobo R1 aka BPi R1 Routerboard
#
# Speaker | LAN1 | LAN2 | LAN3 | LAN4 || LAN5 | HDMI
# SW-Port |  P2  |  P1  |  P0  |  P4  ||  P3  |
# VLAN    |  11  |  12  |  13  |  14  ||ALL(t)|
#
# Switch-Port P8 - ALL(t) boards internal CPU Port

# Setup switch
swconfig dev ${INTERFACE} set reset 1
swconfig dev ${INTERFACE} set enable_vlan 1
swconfig dev ${INTERFACE} vlan 101 set ports '3 8t'
swconfig dev ${INTERFACE} vlan 102 set ports '4 0 1 2 8t'
swconfig dev ${INTERFACE} set apply 1

How to achieve this setup CURRENTLY with DSA?

And in the future (time plan)?

Thank you.

Ciao,
Gerhard



Re: B53 DSA switch problem on Banana Pi-R1 on Fedora 26

2018-05-22 Thread Gerhard Wiesinger

On 22.05.2018 22:42, Florian Fainelli wrote:

On 05/22/2018 01:16 PM, Andrew Lunn wrote:

Planned network structure will be as with 4.7.x kernels:

br0 <=> eth0.101 <=> eth0 (vlan 101 tagged) <=> lan 1-lan4 (vlan 101
untagged pvid)

br1 <=> eth0.102 <=> eth0 (vlan 102 tagged) <=> wan (vlan 102 untagged pvid)

Do you even need these vlans?

Yes, remember, b53 does not currently turn on Broadcom tags, so the only
way to segregate traffic is to have VLANs for that.


Are you doing this for port separation? To keep lan1-4 traffic
separate from wan? DSA does that by default, no vlan needed.

So you can just do

ip link add name br0 type bridge
ip link set dev br0 up
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0
ip link set dev lan4 master br0

and use interface wan directly, no bridge needed.

That would work once Broadcom tags are turned on which requires turning
on managed mode, which requires work that I have not been able to get
done :)


Setup with swconfig:

#!/usr/bin/bash


INTERFACE=eth0

# Delete all IP addresses and get link up
ip addr flush dev ${INTERFACE}
ip link set ${INTERFACE} up

# Lamobo R1 aka BPi R1 Routerboard
#
# Speaker | LAN1 | LAN2 | LAN3 | LAN4 || LAN5 | HDMI
# SW-Port |  P2  |  P1  |  P0  |  P4  ||  P3  |
# VLAN    |  11  |  12  |  13  |  14  ||ALL(t)|
#
# Switch-Port P8 - ALL(t) boards internal CPU Port

# Setup switch
swconfig dev ${INTERFACE} set reset 1
swconfig dev ${INTERFACE} set enable_vlan 1
swconfig dev ${INTERFACE} vlan 101 set ports '3 8t'
swconfig dev ${INTERFACE} vlan 102 set ports '4 0 1 2 8t'
swconfig dev ${INTERFACE} set apply 1

How to achieve this setup CURRENTLY with DSA?

And in the future (time plan)?

Thank you.

Ciao,
Gerhard



Re: [PATCH] fixup! kconfig: refactor ncurses package checks for building mconf and nconf

2018-05-22 Thread Sam Ravnborg
On Wed, May 23, 2018 at 11:11:31AM +0900, Masahiro Yamada wrote:
> It is redundant to pass -DNCURSES_WIDECHAR=1 explicitly; when we use
> 'pkg-config --cflags', it takes care of appropriate flags.
> 
> Actually, 'pkg-config --cflags' will add -D_GNU_SOURCE, which will
> define _XOPEN_SOURCE_EXTENDED, and NCURSES_WIDECHAR=1, anyway.
> 
> I added -D_GNU_SOURCE to follow the suggestion of pkg-config
> for cases where pkg-config is not useful.
> 
> Signed-off-by: Masahiro Yamada 
> ---
> 
> The v3 (https://patchwork.kernel.org/patch/10417413/) was
> reviewed and tested.
> 
> I'd like to squash this into it.

Looks good.
Reviewed-off-by: Sam Ravnborg 

Sam


Re: [PATCH] fixup! kconfig: refactor ncurses package checks for building mconf and nconf

2018-05-22 Thread Sam Ravnborg
On Wed, May 23, 2018 at 11:11:31AM +0900, Masahiro Yamada wrote:
> It is redundant to pass -DNCURSES_WIDECHAR=1 explicitly; when we use
> 'pkg-config --cflags', it takes care of appropriate flags.
> 
> Actually, 'pkg-config --cflags' will add -D_GNU_SOURCE, which will
> define _XOPEN_SOURCE_EXTENDED, and NCURSES_WIDECHAR=1, anyway.
> 
> I added -D_GNU_SOURCE to follow the suggestion of pkg-config
> for cases where pkg-config is not useful.
> 
> Signed-off-by: Masahiro Yamada 
> ---
> 
> The v3 (https://patchwork.kernel.org/patch/10417413/) was
> reviewed and tested.
> 
> I'd like to squash this into it.

Looks good.
Reviewed-off-by: Sam Ravnborg 

Sam


Re: INFO: task hung in xlog_grant_head_check

2018-05-22 Thread Dave Chinner
On Tue, May 22, 2018 at 03:52:08PM -0700, Eric Biggers wrote:
> On Wed, May 23, 2018 at 08:26:20AM +1000, Dave Chinner wrote:
> > On Tue, May 22, 2018 at 08:31:08AM -0400, Brian Foster wrote:
> > > On Mon, May 21, 2018 at 10:55:02AM -0700, syzbot wrote:
> > > > Hello,
> > > > 
> > > > syzbot found the following crash on:
> > > > 
> > > > HEAD commit:203ec2fed17a Merge tag 'armsoc-fixes' of 
> > > > git://git.kernel...
> > > > git tree:   upstream
> > > > console output: https://syzkaller.appspot.com/x/log.txt?x=11c1ad7780
> > > > kernel config:  
> > > > https://syzkaller.appspot.com/x/.config?x=f3b4e30da84ec1ed
> > > > dashboard link: 
> > > > https://syzkaller.appspot.com/bug?extid=568245b88fbaedcb1959
> > > > compiler:   gcc (GCC) 8.0.1 20180413 (experimental)
> > > > syzkaller 
> > > > repro:https://syzkaller.appspot.com/x/repro.syz?x=122c742780
> > > > C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=1038705780
> > > > 
> > > > IMPORTANT: if you fix the bug, please add the following tag to the 
> > > > commit:
> > > > Reported-by: syzbot+568245b88fbaedcb1...@syzkaller.appspotmail.com
> > > > 
> > > > (ptrval): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > 
> > > > (ptrval): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > 
> > > > XFS (loop0): metadata I/O error in "xfs_trans_read_buf_map" at daddr 
> > > > 0x2 len
> > > > 1 error 117
> > > > XFS (loop0): xfs_imap_lookup: xfs_ialloc_read_agi() returned error -117,
> > > > agno 0
> > > > XFS (loop0): failed to read root inode
> > > 
> > > FWIW, the initial console output is actually:
> > > 
> > > [  448.028253] XFS (loop0): Mounting V4 Filesystem
> > > [  448.033540] XFS (loop0): Log size 9371840 blocks too large, maximum 
> > > size is 1048576 blocks
> > > [  448.042287] XFS (loop0): Log size out of supported range.
> > > [  448.047841] XFS (loop0): Continuing onwards, but if log hangs are 
> > > experienced then please report this message in the bug report.
> > > [  448.060712] XFS (loop0): totally zeroed log
> > > 
> > > ... which warns about an oversized log and resulting log hangs. Not
> > > having dug into the details of why this occurs so quickly in this mount
> > > failure path,
> > 
> > I suspect that it is a head and/or log tail pointer overflow, so when it
> > tries to do the first trans reserve of the mount - to write the
> > unmount record - it says "no log space available, please wait".
> > 
> > > it does look like we'd never have got past this point on a
> > > v5 fs (i.e., the above warning would become an error and we'd not enter
> > > the xfs_log_mount_cancel() path).
> > 
> > And this comes back to my repeated comments about fuzzers needing
> > to fuzz properly made V5 filesystems as we catch and error out on
> > things like this. Fuzzing random collections of v4 filesystem
> > fragments will continue to trip over problems we've avoided with v5
> > filesystems, and this is further evidence to point to that.
> >
> > 
> > I'd suggest that at this point, syzbot XFS reports should be
> > redirected to /dev/null. It's not worth our time to triage
> > unreviewed bot generated bug reports until the syzbot developers
> > start listening and acting on what we have been telling them
> > about fuzzing filesystems and reproducing bugs that are meaningful
> > and useful to us.
> 
> The whole point of fuzzing is to provide improper inputs.

Eric, we know what fuzzing is.

If people listened to us rather just throwing stuff over the wall at
us, they'd already know that our own fuzzing code works on v5
filesystems and that it has found a lot more problems in recent
times than syzbot has.

And they'd also know that our own fuzzing stuff provides us with
easily debuggable, reproducable test cases instead of opaque,
difficult to analyse reports of things we already know about and
can't fix in a legacy on-disk format. i.e. it already does all the
things we're asking from the syzbot fuzzing.

> A kernel bug is a
> kernel bug, even if it's in deprecated/unmaintained code, or involves 
> userspace
> doing something unexpected.

Yup, but then the severity and impact of the problem the bug exposes
has to weighed against the risk it poses to the userbase, and the
impact the fix will have on the userbase. We went through this
process several years ago for this specific problem, like we do for
all on-disk format bugs.

Keep in mind that filesystems are persistent structures that have
lifetimes of tens of years. We have to support users with old
formats, regardless of the unfixable problems they may have. We do
what we can to mitigate those issues for them and encourage users to
upgrade their kernels and on-disk formats, but we can't just shut
off access to the old formats in new kernels because a new fuzzer
found an old problem we've known about for years.

[ FYI, this report is for an on-disk v4 format bug that was
introduced into mkfs about 15 years ago.  It has 

Re: INFO: task hung in xlog_grant_head_check

2018-05-22 Thread Dave Chinner
On Tue, May 22, 2018 at 03:52:08PM -0700, Eric Biggers wrote:
> On Wed, May 23, 2018 at 08:26:20AM +1000, Dave Chinner wrote:
> > On Tue, May 22, 2018 at 08:31:08AM -0400, Brian Foster wrote:
> > > On Mon, May 21, 2018 at 10:55:02AM -0700, syzbot wrote:
> > > > Hello,
> > > > 
> > > > syzbot found the following crash on:
> > > > 
> > > > HEAD commit:203ec2fed17a Merge tag 'armsoc-fixes' of 
> > > > git://git.kernel...
> > > > git tree:   upstream
> > > > console output: https://syzkaller.appspot.com/x/log.txt?x=11c1ad7780
> > > > kernel config:  
> > > > https://syzkaller.appspot.com/x/.config?x=f3b4e30da84ec1ed
> > > > dashboard link: 
> > > > https://syzkaller.appspot.com/bug?extid=568245b88fbaedcb1959
> > > > compiler:   gcc (GCC) 8.0.1 20180413 (experimental)
> > > > syzkaller 
> > > > repro:https://syzkaller.appspot.com/x/repro.syz?x=122c742780
> > > > C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=1038705780
> > > > 
> > > > IMPORTANT: if you fix the bug, please add the following tag to the 
> > > > commit:
> > > > Reported-by: syzbot+568245b88fbaedcb1...@syzkaller.appspotmail.com
> > > > 
> > > > (ptrval): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > 
> > > > (ptrval): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > 
> > > > XFS (loop0): metadata I/O error in "xfs_trans_read_buf_map" at daddr 
> > > > 0x2 len
> > > > 1 error 117
> > > > XFS (loop0): xfs_imap_lookup: xfs_ialloc_read_agi() returned error -117,
> > > > agno 0
> > > > XFS (loop0): failed to read root inode
> > > 
> > > FWIW, the initial console output is actually:
> > > 
> > > [  448.028253] XFS (loop0): Mounting V4 Filesystem
> > > [  448.033540] XFS (loop0): Log size 9371840 blocks too large, maximum 
> > > size is 1048576 blocks
> > > [  448.042287] XFS (loop0): Log size out of supported range.
> > > [  448.047841] XFS (loop0): Continuing onwards, but if log hangs are 
> > > experienced then please report this message in the bug report.
> > > [  448.060712] XFS (loop0): totally zeroed log
> > > 
> > > ... which warns about an oversized log and resulting log hangs. Not
> > > having dug into the details of why this occurs so quickly in this mount
> > > failure path,
> > 
> > I suspect that it is a head and/or log tail pointer overflow, so when it
> > tries to do the first trans reserve of the mount - to write the
> > unmount record - it says "no log space available, please wait".
> > 
> > > it does look like we'd never have got past this point on a
> > > v5 fs (i.e., the above warning would become an error and we'd not enter
> > > the xfs_log_mount_cancel() path).
> > 
> > And this comes back to my repeated comments about fuzzers needing
> > to fuzz properly made V5 filesystems as we catch and error out on
> > things like this. Fuzzing random collections of v4 filesystem
> > fragments will continue to trip over problems we've avoided with v5
> > filesystems, and this is further evidence to point to that.
> >
> > 
> > I'd suggest that at this point, syzbot XFS reports should be
> > redirected to /dev/null. It's not worth our time to triage
> > unreviewed bot generated bug reports until the syzbot developers
> > start listening and acting on what we have been telling them
> > about fuzzing filesystems and reproducing bugs that are meaningful
> > and useful to us.
> 
> The whole point of fuzzing is to provide improper inputs.

Eric, we know what fuzzing is.

If people listened to us rather just throwing stuff over the wall at
us, they'd already know that our own fuzzing code works on v5
filesystems and that it has found a lot more problems in recent
times than syzbot has.

And they'd also know that our own fuzzing stuff provides us with
easily debuggable, reproducable test cases instead of opaque,
difficult to analyse reports of things we already know about and
can't fix in a legacy on-disk format. i.e. it already does all the
things we're asking from the syzbot fuzzing.

> A kernel bug is a
> kernel bug, even if it's in deprecated/unmaintained code, or involves 
> userspace
> doing something unexpected.

Yup, but then the severity and impact of the problem the bug exposes
has to weighed against the risk it poses to the userbase, and the
impact the fix will have on the userbase. We went through this
process several years ago for this specific problem, like we do for
all on-disk format bugs.

Keep in mind that filesystems are persistent structures that have
lifetimes of tens of years. We have to support users with old
formats, regardless of the unfixable problems they may have. We do
what we can to mitigate those issues for them and encourage users to
upgrade their kernels and on-disk formats, but we can't just shut
off access to the old formats in new kernels because a new fuzzer
found an old problem we've known about for years.

[ FYI, this report is for an on-disk v4 format bug that was
introduced into mkfs about 15 years ago.  It has 

Re: [PATCH v2] pinctrl: cherryview: limit Strago DMI workarounds to version 1.0

2018-05-22 Thread Guenter Roeck

On 05/22/2018 01:47 PM, Dmitry Torokhov wrote:

As Google/Intel will fix the BIOS/Coreboot issues with hardcoding
virtual interrupt numbers for keyboard/touchpad/touchscreen controllers
in ACPI tables, they will also update BOARD version number from 1.0
to 1.1. Let's limit the DMI quirks that try to preserve virtual IRQ
numbers on Strago boards to those that still carry older BIOSes.

Note that ideally not BOARD but BIOS version should have been updated.
However the BIOS version used by Chrome devices has format of
Google_BUILD.BRANCH.PATCH which is not well suited for DMI matching as
we do not have "less than" match mode for DMI data.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197953
Signed-off-by: Dmitry Torokhov 


Reviewed-by: Guenter Roeck 


---

v1->v2:

- switch from matching on DMI_BIOS_VERSION to DMI_BOARD_VERSION


  drivers/pinctrl/intel/pinctrl-cherryview.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c 
b/drivers/pinctrl/intel/pinctrl-cherryview.c
index b1ae1618fefea..44133e6846303 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1527,6 +1527,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1534,6 +1535,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1541,6 +1543,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1548,6 +1551,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{}





Re: [PATCH v2] pinctrl: cherryview: limit Strago DMI workarounds to version 1.0

2018-05-22 Thread Guenter Roeck

On 05/22/2018 01:47 PM, Dmitry Torokhov wrote:

As Google/Intel will fix the BIOS/Coreboot issues with hardcoding
virtual interrupt numbers for keyboard/touchpad/touchscreen controllers
in ACPI tables, they will also update BOARD version number from 1.0
to 1.1. Let's limit the DMI quirks that try to preserve virtual IRQ
numbers on Strago boards to those that still carry older BIOSes.

Note that ideally not BOARD but BIOS version should have been updated.
However the BIOS version used by Chrome devices has format of
Google_BUILD.BRANCH.PATCH which is not well suited for DMI matching as
we do not have "less than" match mode for DMI data.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197953
Signed-off-by: Dmitry Torokhov 


Reviewed-by: Guenter Roeck 


---

v1->v2:

- switch from matching on DMI_BIOS_VERSION to DMI_BOARD_VERSION


  drivers/pinctrl/intel/pinctrl-cherryview.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c 
b/drivers/pinctrl/intel/pinctrl-cherryview.c
index b1ae1618fefea..44133e6846303 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1527,6 +1527,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1534,6 +1535,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1541,6 +1543,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{
@@ -1548,6 +1551,7 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
+   DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
},
},
{}





Re: [RFC PATCH 1/1] kconfig: drop localization support

2018-05-22 Thread Sam Ravnborg
Hi Masahiro.

> > Ulf Magnusson originally mentioned this removal some time ago.
> >
> > So, here is his tag.
> > Suggested-by: Ulf Magnusson 
Added.

> PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \
>  localmodconfig localyesconfig
> 
> 
> The 'update-po-config' is left-over in the PHONY assignment.
Good catch.

> This is simple, so I can fix it up locally.
Fine

If there is any other feedback I will respin the patch.

Sam


Re: [RFC PATCH 1/1] kconfig: drop localization support

2018-05-22 Thread Sam Ravnborg
Hi Masahiro.

> > Ulf Magnusson originally mentioned this removal some time ago.
> >
> > So, here is his tag.
> > Suggested-by: Ulf Magnusson 
Added.

> PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \
>  localmodconfig localyesconfig
> 
> 
> The 'update-po-config' is left-over in the PHONY assignment.
Good catch.

> This is simple, so I can fix it up locally.
Fine

If there is any other feedback I will respin the patch.

Sam


[GIT PULL] Qualcomm Device Tree updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-dts-for-4.18

for you to fetch changes up to 90ce62659994b87723ec6ba26815f9634c18e449:

  ARM: dts: qcom-apq8064: use correct pci address for address translation 
(2018-05-14 15:22:28 -0500)


Qualcomm Device Tree Changes for v4.18

* APQ8064 fixes for irq translations and pci address translation
* Fix RPM clock controller compatible on MSM8660
* Add TZ and SMEM reserved regions on IPQ4019
* Add vadc nodes for PM8941
* Disable i2c by default at top level APQ8064 dtsi


Craig Tatlor (1):
  ARM: dts: qcom: pm8941: Add vadc nodes needed to estimate an ocv

Linus Walleij (1):
  ARM: dts: Fix the RPM clock controller compatible string

Niklas Cassel (1):
  ARM: dts: qcom-apq8064: use correct pci address for address translation

Srinivas Kandagatla (1):
  ARM: dts: qcom-apq8064: disable i2c by default at soc dtsi

Sven Eckelmann (1):
  ARM: dts: ipq4019: Add TZ and SMEM reserved regions

Thierry Escande (1):
  ARM: dts: qcom-apq8064: fix gic_irq_domain_translate warnings

 arch/arm/boot/dts/qcom-apq8064.dtsi | 58 -
 arch/arm/boot/dts/qcom-ipq4019.dtsi | 16 ++
 arch/arm/boot/dts/qcom-msm8660.dtsi |  2 +-
 arch/arm/boot/dts/qcom-pm8941.dtsi  |  6 
 4 files changed, 54 insertions(+), 28 deletions(-)


[GIT PULL] Qualcomm Device Tree updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-dts-for-4.18

for you to fetch changes up to 90ce62659994b87723ec6ba26815f9634c18e449:

  ARM: dts: qcom-apq8064: use correct pci address for address translation 
(2018-05-14 15:22:28 -0500)


Qualcomm Device Tree Changes for v4.18

* APQ8064 fixes for irq translations and pci address translation
* Fix RPM clock controller compatible on MSM8660
* Add TZ and SMEM reserved regions on IPQ4019
* Add vadc nodes for PM8941
* Disable i2c by default at top level APQ8064 dtsi


Craig Tatlor (1):
  ARM: dts: qcom: pm8941: Add vadc nodes needed to estimate an ocv

Linus Walleij (1):
  ARM: dts: Fix the RPM clock controller compatible string

Niklas Cassel (1):
  ARM: dts: qcom-apq8064: use correct pci address for address translation

Srinivas Kandagatla (1):
  ARM: dts: qcom-apq8064: disable i2c by default at soc dtsi

Sven Eckelmann (1):
  ARM: dts: ipq4019: Add TZ and SMEM reserved regions

Thierry Escande (1):
  ARM: dts: qcom-apq8064: fix gic_irq_domain_translate warnings

 arch/arm/boot/dts/qcom-apq8064.dtsi | 58 -
 arch/arm/boot/dts/qcom-ipq4019.dtsi | 16 ++
 arch/arm/boot/dts/qcom-msm8660.dtsi |  2 +-
 arch/arm/boot/dts/qcom-pm8941.dtsi  |  6 
 4 files changed, 54 insertions(+), 28 deletions(-)


[GIT PULL] Qualcomm Driver updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-drivers-for-4.18

for you to fetch changes up to f378dab2c576ab1ef30ff26d2a96687a5a855271:

  soc: qcom: smem: introduce qcom_smem_virt_to_phys() (2018-05-14 14:06:49 
-0500)


Qualcomm ARM Based Driver Updates for v4.18

* Various SMEM updates/fixes
* Add qcom_smem_virt_to_phys SMEM API
* Update MAINTAINERS to include qcom_scm pattern
* Add Qualcomm Command DB driver
* Fix crash in Qualcomm SCM atomic1 call
* Add Qualcomm SCM compatible for IPQ4019
* Add MSM8998 to smd-rpm compatible list
* Add Qualcomm GENI based QUP wrapper
* Fix Qualcomm QMI buffer sizing bug


Alex Elder (8):
  soc: qcom: smem: fix first cache entry calculation
  soc: qcom: smem: return proper type for cached entry functions
  soc: qcom: smem: byte swap values properly
  soc: qcom: smem: fix off-by-one error in qcom_smem_alloc_private()
  soc: qcom: smem: fix qcom_smem_set_global_partition()
  soc: qcom: smem: check sooner in qcom_smem_set_global_partition()
  soc: qcom: qmi: fix a buffer sizing bug
  soc: qcom: smem: introduce qcom_smem_virt_to_phys()

Bjorn Andersson (1):
  soc: qcom: smd-rpm: Add msm8998 compatible

Guenter Roeck (1):
  soc: Unconditionally include qcom Makefile

Karthikeyan Ramasubramanian (1):
  soc: qcom: Add GENI based QUP Wrapper driver

Mahesh Sivasubramanian (1):
  drivers: qcom: add command DB driver

Niklas Cassel (2):
  firmware: qcom: scm: Fix crash in qcom_scm_call_atomic1()
  MAINTAINERS: Update pattern for qcom_scm

Sricharan R (1):
  firmware: qcom: scm: Add ipq4019 soc compatible

Stephen Boyd (1):
  soc: qcom: cmd-db: Make endian-agnostic

 .../devicetree/bindings/firmware/qcom,scm.txt  |   3 +-
 .../devicetree/bindings/soc/qcom/qcom,smd-rpm.txt  |   1 +
 MAINTAINERS|   2 +-
 drivers/firmware/qcom_scm-32.c |   8 +-
 drivers/firmware/qcom_scm.c|   3 +
 drivers/of/platform.c  |   1 +
 drivers/soc/Makefile   |   2 +-
 drivers/soc/qcom/Kconfig   |  18 +
 drivers/soc/qcom/Makefile  |   2 +
 drivers/soc/qcom/cmd-db.c  | 317 +
 drivers/soc/qcom/qcom-geni-se.c| 748 +
 drivers/soc/qcom/qmi_interface.c   |   5 +-
 drivers/soc/qcom/smd-rpm.c |   1 +
 drivers/soc/qcom/smem.c|  77 ++-
 include/linux/qcom-geni-se.h   | 425 
 include/linux/soc/qcom/smem.h  |   2 +
 include/soc/qcom/cmd-db.h  |  45 ++
 17 files changed, 1629 insertions(+), 31 deletions(-)
 create mode 100644 drivers/soc/qcom/cmd-db.c
 create mode 100644 drivers/soc/qcom/qcom-geni-se.c
 create mode 100644 include/linux/qcom-geni-se.h
 create mode 100644 include/soc/qcom/cmd-db.h


[GIT PULL] Qualcomm ARM64 DT updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-arm64-for-4.18

for you to fetch changes up to 57fc67ef0d35af11fbb1b928e359b370889994ae:

  arm64: dts: qcom: msm8996: Add ufs related nodes (2018-05-22 23:29:03 -0500)


Qualcomm ARM64 Updates for v4.18

* Add support for SDM845 and associated peripherals
* Fix gic_irq_domain_translation warnings on Qualcomm platforms
* Add binding for GENI SE, Qualcomm bluetooth, and Command DB
* Add support for SDHCI and ramoops on MSM8992
* Fixup qcom,pcie devices to pcie
* Add wlan, bluetooth, and micro SD supplies on db820c
* Add UFS related nodes on MSM8996


Arnd Bergmann (1):
  arm64: dts: qcom: rename qcom,pcie devices to pcie

Bjorn Andersson (1):
  arm64: dts: qcom: msm8996: Add ufs related nodes

Douglas Anderson (4):
  arm64: dts: sdm845: Fix xo_board clock name and speed
  arm64: dts: sdm845: Add command DB node
  arm64: dts: qcom: sdm845: Sort nodes in the reserved mem by address
  arm64: dts: qcom: sdm845: Sort nodes in the soc by address

Jeremy McNicoll (2):
  arm64: dts: Enable onboard SDHCI on msm8992
  arm64: dts: msm8992: add pstore-ramoops support

Karthikeyan Ramasubramanian (1):
  dt-bindings: soc: qcom: Add device tree binding for GENI SE

Mahesh Sivasubramanian (1):
  dt-bindings: introduce Command DB for QCOM SoCs

Rajendra Nayak (1):
  arm64: dts: sdm845: Add minimal dts/dtsi files for sdm845 SoC and MTP

Sibi S (2):
  arm64: dts: qcom: Add APSS shared mailbox node to SDM845
  arm64: dts: qcom: Add SDM845 SMEM nodes

Srinivas Kandagatla (3):
  arm64: dts: apq8096-db820c: Enable wlan and bt en pins
  arm64: dts: apq8096-db820c: Add micro sd card supplies
  arm64: dts: msm8916: fix gic_irq_domain_translate warnings

Thierry Escande (3):
  arm64: dts: apq8096-db820c: enable bluetooth node
  dt-bindings: net: bluetooth: Add qualcomm-bluetooth
  arm64: dts: msm8996: fix gic_irq_domain_translate warnings

 .../devicetree/bindings/net/qualcomm-bluetooth.txt |  30 ++
 .../bindings/reserved-memory/qcom,cmd-db.txt   |  37 +++
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  | 119 
 arch/arm64/boot/dts/qcom/Makefile  |   1 +
 arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi  |  26 ++
 .../boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi|  32 ++
 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi   |  77 -
 arch/arm64/boot/dts/qcom/msm8916.dtsi  |  18 +-
 .../boot/dts/qcom/msm8992-bullhead-rev-101.dts |  17 ++
 arch/arm64/boot/dts/qcom/msm8992-pins.dtsi |  60 
 arch/arm64/boot/dts/qcom/msm8992.dtsi  |  87 +-
 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi  | 276 +
 arch/arm64/boot/dts/qcom/msm8996.dtsi  | 120 +++-
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts|  15 +
 arch/arm64/boot/dts/qcom/sdm845.dtsi   | 327 +
 15 files changed, 1217 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
 create mode 100644 
Documentation/devicetree/bindings/reserved-memory/qcom,cmd-db.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845-mtp.dts
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845.dtsi


[GIT PULL] Qualcomm Driver updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-drivers-for-4.18

for you to fetch changes up to f378dab2c576ab1ef30ff26d2a96687a5a855271:

  soc: qcom: smem: introduce qcom_smem_virt_to_phys() (2018-05-14 14:06:49 
-0500)


Qualcomm ARM Based Driver Updates for v4.18

* Various SMEM updates/fixes
* Add qcom_smem_virt_to_phys SMEM API
* Update MAINTAINERS to include qcom_scm pattern
* Add Qualcomm Command DB driver
* Fix crash in Qualcomm SCM atomic1 call
* Add Qualcomm SCM compatible for IPQ4019
* Add MSM8998 to smd-rpm compatible list
* Add Qualcomm GENI based QUP wrapper
* Fix Qualcomm QMI buffer sizing bug


Alex Elder (8):
  soc: qcom: smem: fix first cache entry calculation
  soc: qcom: smem: return proper type for cached entry functions
  soc: qcom: smem: byte swap values properly
  soc: qcom: smem: fix off-by-one error in qcom_smem_alloc_private()
  soc: qcom: smem: fix qcom_smem_set_global_partition()
  soc: qcom: smem: check sooner in qcom_smem_set_global_partition()
  soc: qcom: qmi: fix a buffer sizing bug
  soc: qcom: smem: introduce qcom_smem_virt_to_phys()

Bjorn Andersson (1):
  soc: qcom: smd-rpm: Add msm8998 compatible

Guenter Roeck (1):
  soc: Unconditionally include qcom Makefile

Karthikeyan Ramasubramanian (1):
  soc: qcom: Add GENI based QUP Wrapper driver

Mahesh Sivasubramanian (1):
  drivers: qcom: add command DB driver

Niklas Cassel (2):
  firmware: qcom: scm: Fix crash in qcom_scm_call_atomic1()
  MAINTAINERS: Update pattern for qcom_scm

Sricharan R (1):
  firmware: qcom: scm: Add ipq4019 soc compatible

Stephen Boyd (1):
  soc: qcom: cmd-db: Make endian-agnostic

 .../devicetree/bindings/firmware/qcom,scm.txt  |   3 +-
 .../devicetree/bindings/soc/qcom/qcom,smd-rpm.txt  |   1 +
 MAINTAINERS|   2 +-
 drivers/firmware/qcom_scm-32.c |   8 +-
 drivers/firmware/qcom_scm.c|   3 +
 drivers/of/platform.c  |   1 +
 drivers/soc/Makefile   |   2 +-
 drivers/soc/qcom/Kconfig   |  18 +
 drivers/soc/qcom/Makefile  |   2 +
 drivers/soc/qcom/cmd-db.c  | 317 +
 drivers/soc/qcom/qcom-geni-se.c| 748 +
 drivers/soc/qcom/qmi_interface.c   |   5 +-
 drivers/soc/qcom/smd-rpm.c |   1 +
 drivers/soc/qcom/smem.c|  77 ++-
 include/linux/qcom-geni-se.h   | 425 
 include/linux/soc/qcom/smem.h  |   2 +
 include/soc/qcom/cmd-db.h  |  45 ++
 17 files changed, 1629 insertions(+), 31 deletions(-)
 create mode 100644 drivers/soc/qcom/cmd-db.c
 create mode 100644 drivers/soc/qcom/qcom-geni-se.c
 create mode 100644 include/linux/qcom-geni-se.h
 create mode 100644 include/soc/qcom/cmd-db.h


[GIT PULL] Qualcomm ARM64 DT updates for 4.18

2018-05-22 Thread Andy Gross
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git 
tags/qcom-arm64-for-4.18

for you to fetch changes up to 57fc67ef0d35af11fbb1b928e359b370889994ae:

  arm64: dts: qcom: msm8996: Add ufs related nodes (2018-05-22 23:29:03 -0500)


Qualcomm ARM64 Updates for v4.18

* Add support for SDM845 and associated peripherals
* Fix gic_irq_domain_translation warnings on Qualcomm platforms
* Add binding for GENI SE, Qualcomm bluetooth, and Command DB
* Add support for SDHCI and ramoops on MSM8992
* Fixup qcom,pcie devices to pcie
* Add wlan, bluetooth, and micro SD supplies on db820c
* Add UFS related nodes on MSM8996


Arnd Bergmann (1):
  arm64: dts: qcom: rename qcom,pcie devices to pcie

Bjorn Andersson (1):
  arm64: dts: qcom: msm8996: Add ufs related nodes

Douglas Anderson (4):
  arm64: dts: sdm845: Fix xo_board clock name and speed
  arm64: dts: sdm845: Add command DB node
  arm64: dts: qcom: sdm845: Sort nodes in the reserved mem by address
  arm64: dts: qcom: sdm845: Sort nodes in the soc by address

Jeremy McNicoll (2):
  arm64: dts: Enable onboard SDHCI on msm8992
  arm64: dts: msm8992: add pstore-ramoops support

Karthikeyan Ramasubramanian (1):
  dt-bindings: soc: qcom: Add device tree binding for GENI SE

Mahesh Sivasubramanian (1):
  dt-bindings: introduce Command DB for QCOM SoCs

Rajendra Nayak (1):
  arm64: dts: sdm845: Add minimal dts/dtsi files for sdm845 SoC and MTP

Sibi S (2):
  arm64: dts: qcom: Add APSS shared mailbox node to SDM845
  arm64: dts: qcom: Add SDM845 SMEM nodes

Srinivas Kandagatla (3):
  arm64: dts: apq8096-db820c: Enable wlan and bt en pins
  arm64: dts: apq8096-db820c: Add micro sd card supplies
  arm64: dts: msm8916: fix gic_irq_domain_translate warnings

Thierry Escande (3):
  arm64: dts: apq8096-db820c: enable bluetooth node
  dt-bindings: net: bluetooth: Add qualcomm-bluetooth
  arm64: dts: msm8996: fix gic_irq_domain_translate warnings

 .../devicetree/bindings/net/qualcomm-bluetooth.txt |  30 ++
 .../bindings/reserved-memory/qcom,cmd-db.txt   |  37 +++
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  | 119 
 arch/arm64/boot/dts/qcom/Makefile  |   1 +
 arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi  |  26 ++
 .../boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi|  32 ++
 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi   |  77 -
 arch/arm64/boot/dts/qcom/msm8916.dtsi  |  18 +-
 .../boot/dts/qcom/msm8992-bullhead-rev-101.dts |  17 ++
 arch/arm64/boot/dts/qcom/msm8992-pins.dtsi |  60 
 arch/arm64/boot/dts/qcom/msm8992.dtsi  |  87 +-
 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi  | 276 +
 arch/arm64/boot/dts/qcom/msm8996.dtsi  | 120 +++-
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts|  15 +
 arch/arm64/boot/dts/qcom/sdm845.dtsi   | 327 +
 15 files changed, 1217 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
 create mode 100644 
Documentation/devicetree/bindings/reserved-memory/qcom,cmd-db.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845-mtp.dts
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845.dtsi


Re: [PATCH v2] pinctrl: cherryview: limit Strago DMI workarounds to version 1.0

2018-05-22 Thread Mika Westerberg
On Tue, May 22, 2018 at 01:47:53PM -0700, Dmitry Torokhov wrote:
> As Google/Intel will fix the BIOS/Coreboot issues with hardcoding
> virtual interrupt numbers for keyboard/touchpad/touchscreen controllers
> in ACPI tables, they will also update BOARD version number from 1.0
> to 1.1. Let's limit the DMI quirks that try to preserve virtual IRQ
> numbers on Strago boards to those that still carry older BIOSes.
> 
> Note that ideally not BOARD but BIOS version should have been updated.
> However the BIOS version used by Chrome devices has format of
> Google_BUILD.BRANCH.PATCH which is not well suited for DMI matching as
> we do not have "less than" match mode for DMI data.
> 
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197953
> Signed-off-by: Dmitry Torokhov 

Acked-by: Mika Westerberg 


Re: [PATCH v2] pinctrl: cherryview: limit Strago DMI workarounds to version 1.0

2018-05-22 Thread Mika Westerberg
On Tue, May 22, 2018 at 01:47:53PM -0700, Dmitry Torokhov wrote:
> As Google/Intel will fix the BIOS/Coreboot issues with hardcoding
> virtual interrupt numbers for keyboard/touchpad/touchscreen controllers
> in ACPI tables, they will also update BOARD version number from 1.0
> to 1.1. Let's limit the DMI quirks that try to preserve virtual IRQ
> numbers on Strago boards to those that still carry older BIOSes.
> 
> Note that ideally not BOARD but BIOS version should have been updated.
> However the BIOS version used by Chrome devices has format of
> Google_BUILD.BRANCH.PATCH which is not well suited for DMI matching as
> we do not have "less than" match mode for DMI data.
> 
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197953
> Signed-off-by: Dmitry Torokhov 

Acked-by: Mika Westerberg 


Re: [PATCH] [RFC] bpf: tracing: new helper bpf_get_current_cgroup_ino

2018-05-22 Thread Y Song
On Tue, May 22, 2018 at 8:35 PM, Alexei Starovoitov
 wrote:
> On Tue, May 22, 2018 at 08:33:24PM -0700, Y Song wrote:
>> +   struct cgroup *cgrp = task_dfl_cgroup(current);
>> +   if (!cgrp)
>> +   return -EINVAL;
>
> why this check is needed?

No reason :-) Originally I am concerned whether it is possible cgrp
could be NULL.
By looking at the code, it SEEMS to me that it could not be NULL, but I am not
100% sure (as I am not a cgroup expert). Since you are asking,
probably means it cannot be NULL, so will remove it in formal upstream patch.


Re: [PATCH] [RFC] bpf: tracing: new helper bpf_get_current_cgroup_ino

2018-05-22 Thread Y Song
On Tue, May 22, 2018 at 8:35 PM, Alexei Starovoitov
 wrote:
> On Tue, May 22, 2018 at 08:33:24PM -0700, Y Song wrote:
>> +   struct cgroup *cgrp = task_dfl_cgroup(current);
>> +   if (!cgrp)
>> +   return -EINVAL;
>
> why this check is needed?

No reason :-) Originally I am concerned whether it is possible cgrp
could be NULL.
By looking at the code, it SEEMS to me that it could not be NULL, but I am not
100% sure (as I am not a cgroup expert). Since you are asking,
probably means it cannot be NULL, so will remove it in formal upstream patch.


  1   2   3   4   5   6   7   8   9   10   >