* [PATCH v5 1/8] clocksource: dmtimer: Remove all the exports
From: Ladislav Michl @ 2017-12-13 9:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171212182150.GF14441@atomide.com>
On Tue, Dec 12, 2017 at 10:21:50AM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171212 18:06]:
> > I do not follow. Each general-purpose timer module has its own interrupt line,
> > so claiming that irq directly using request_irq seems enough. Could you
> > explain interrupt controller idea a bit more?
>
> Well let's assume we have drivers/clocksource/timer-dm.c implement
> an irq controller. Then the pwm driver would just do:
>
> pwm9: dmtimer-pwm {
> compatible = "ti,omap-dmtimer-pwm";
> #pwm-cells = <3>;
> ti,timers = <&timer9>;
> ti,clock-source = <0x00>; /* timer_sys_ck */
> interrupts-extended = <&timer9 IRQ_TYPE_SOMETHING>;
> };
>
> Then you can do whatever you need to in the pwm driver with
> enable_irq/disable_irq + a handler?
That seems to work. Now should we map 1:1 to timer interrupt or
have separate interrupt for match, overflow and capture?
Former would need some more dm_timer_ops to determine interrupt
source, while later would work "automagically" - but I haven't
tested it yet.
> If reading the line status is needed.. Then maybe the GPIO framework
> needs to have hardware timer support instead?
It does not seem OMAP can read event pin value in event capture mode.
> Anyways, just thinking out loud how we could have a Linux generic
> hardware timer framework that drivers like pwm could then use.
I need a bit longer chain:
dmtimer -> pwm -> rc (which calls ir_raw_event_store from interrupt)
Is extending pwm core with interrpt callback the right thing there?
Something like:
(*pulse_captured)(ktime_t width, ktime_t last_edge);
Thank you,
ladis
^ permalink raw reply
* [PATCH] KVM: arm/arm64: don't set vtimer->cnt_ctl in kvm_arch_timer_handler
From: Christoffer Dall @ 2017-12-13 9:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513148407-2611-1-git-send-email-hejianet@gmail.com>
On Tue, Dec 12, 2017 at 11:00:07PM -0800, Jia He wrote:
> In our Armv8a server (qualcomm Amberwing, non VHE), after applying
> Christoffer's timer optimizing patchset(Optimize arch timer register
> handling), the guest is hang during kernel booting.
>
> The error root cause might be as follows:
> 1. in kvm_arch_timer_handler, it reset vtimer->cnt_ctl with current
> cntv_ctl register value. And then it missed some cases to update timer's
> irq (irq.level) when kvm_timer_irq_can_fire() is false
Why should it set the irq level to true when the timer cannot fire?
> 2. It causes kvm_vcpu_check_block return 0 instead of -EINTR
> kvm_vcpu_check_block
> kvm_cpu_has_pending_timer
> kvm_timer_is_pending
> kvm_timer_should_fire
> 3. Thus, the kvm hyp code can not break the loop in kvm_vcpu_block (halt
> poll process) and the guest is hang forever
This is just a polling loop which will expire after some time, so it
shouldn't halt the guest indefinitely, but merely slow it down for some
while, if we have a bug. Is that the behavior you're seeing or are you
seeing the guest coming to a complete halt?
>
> Fixes: b103cc3f10c0 ("KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit")
> Signed-off-by: Jia He <jia.he@hxt-semitech.com>
> ---
> virt/kvm/arm/arch_timer.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index f9555b1..bb86433 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -100,7 +100,6 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
> vtimer = vcpu_vtimer(vcpu);
>
> if (!vtimer->irq.level) {
> - vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
This fix is clearly not correct, as it would prevent forwarding timer
interrupts in some cases.
> if (kvm_timer_irq_can_fire(vtimer))
> kvm_timer_update_irq(vcpu, true, vtimer);
> }
> --
> 2.7.4
>
I actually don't see how the above scenario you painted can happen.
If you're in the polling loop, that means that the timer state is loaded
on the vcpu, and that means you can take interrupts from the timer, and
when you take interrupts, you will set the irq.level.
And here's the first bit of logic in kvm_timer_is_pending():
if (vtimer->irq.level || ptimer->irq.level)
return true;
So that would break the loop.
I'm not able to reproduce on my side with a non-VHE platform.
What is the workload you're running to reproduce this, and what is the
exact kernel tree and kernel configuration you're using?
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH v8 10/13] IIO: ADC: add stm32 DFSDM support for PDM microphone
From: Jonathan Cameron @ 2017-12-13 9:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ed92f7e5-f321-866f-3e22-8a14e3982c9f@st.com>
On Wed, 13 Dec 2017 09:42:02 +0100
Arnaud Pouliquen <arnaud.pouliquen@st.com> wrote:
> Hi Jonathan,
>
>
> On 12/12/2017 09:27 PM, Jonathan Cameron wrote:
> > On Mon, 11 Dec 2017 11:18:41 +0100
> > Arnaud Pouliquen <arnaud.pouliquen@st.com> wrote:
> >
> >> This code offers a way to handle PDM audio microphones in
> >> ASOC framework. Audio driver should use consumer API.
> >> A specific management is implemented for DMA, with a
> >> callback, to allows to handle audio buffers efficiently.
> >>
> >> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
>
>
> > Hi Arnaud,
> >
> > I raise a few queries on v7 of this patch.
> >
> > https://marc.info/?l=linux-iio&m=151292965915376&w=2
> Never received the associated mail (and no in my spam list):( ,I just
> discover it...
>
> Thanks to have highlighted this and sorry for the inconvenience, I will
> send a v9.
Don't worry about it! Happens to me from time to time as well.
Thanks,
Jonathan
>
> Regards
> Arnaud
>
>
> >
> > Jonathan
> >
> >> ---
> >> .../ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 | 16 +
> >> drivers/iio/adc/stm32-dfsdm-adc.c | 508 ++++++++++++++++++++-
> >> include/linux/iio/adc/stm32-dfsdm-adc.h | 18 +
> >> 3 files changed, 534 insertions(+), 8 deletions(-)
> >> create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
> >> create mode 100644 include/linux/iio/adc/stm32-dfsdm-adc.h
> >>
> >> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
> >> new file mode 100644
> >> index 0000000..da98223
> >> --- /dev/null
> >> +++ b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
> >> @@ -0,0 +1,16 @@
> >> +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_spi_clk_freq
> >> +KernelVersion: 4.14
> >> +Contact: arnaud.pouliquen at st.com
> >> +Description:
> >> + For audio purpose only.
> >> + Used by audio driver to set/get the spi input frequency.
> >> + This is mandatory if DFSDM is slave on SPI bus, to
> >> + provide information on the SPI clock frequency during runtime
> >> + Notice that the SPI frequency should be a multiple of sample
> >> + frequency to ensure the precision.
> >> + if DFSDM input is SPI master
> >> + Reading SPI clkout frequency,
> >> + error on writing
> >> + If DFSDM input is SPI Slave:
> >> + Reading returns value previously set.
> >> + Writing value before starting conversions.
> >> \ No newline at end of file
> >> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> >> index 68b5920..2d6aed5 100644
> >> --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> >> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> >> @@ -6,19 +6,25 @@
> >> * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>.
> >> */
> >>
> >> +#include <linux/dmaengine.h>
> >> +#include <linux/dma-mapping.h>
> >> #include <linux/interrupt.h>
> >> #include <linux/iio/buffer.h>
> >> #include <linux/iio/hw-consumer.h>
> >> #include <linux/iio/iio.h>
> >> #include <linux/iio/sysfs.h>
> >> +#include <linux/iio/trigger_consumer.h>
> >> +#include <linux/iio/triggered_buffer.h>
> >> #include <linux/module.h>
> >> -#include <linux/of.h>
> >> +#include <linux/of_device.h>
> >> #include <linux/platform_device.h>
> >> #include <linux/regmap.h>
> >> #include <linux/slab.h>
> >>
> >> #include "stm32-dfsdm.h"
> >>
> >> +#define DFSDM_DMA_BUFFER_SIZE (4 * PAGE_SIZE)
> >> +
> >> /* Conversion timeout */
> >> #define DFSDM_TIMEOUT_US 100000
> >> #define DFSDM_TIMEOUT (msecs_to_jiffies(DFSDM_TIMEOUT_US / 1000))
> >> @@ -58,6 +64,18 @@ struct stm32_dfsdm_adc {
> >> struct completion completion;
> >> u32 *buffer;
> >>
> >> + /* Audio specific */
> >> + unsigned int spi_freq; /* SPI bus clock frequency */
> >> + unsigned int sample_freq; /* Sample frequency after filter decimation */
> >> + int (*cb)(const void *data, size_t size, void *cb_priv);
> >> + void *cb_priv;
> >> +
> >> + /* DMA */
> >> + u8 *rx_buf;
> >> + unsigned int bufi; /* Buffer current position */
> >> + unsigned int buf_sz; /* Buffer size */
> >> + struct dma_chan *dma_chan;
> >> + dma_addr_t dma_buf;
> >> };
> >>
> >> struct stm32_dfsdm_str2field {
> >> @@ -351,10 +369,63 @@ int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
> >> return 0;
> >> }
> >>
> >> +static ssize_t dfsdm_adc_audio_get_spiclk(struct iio_dev *indio_dev,
> >> + uintptr_t priv,
> >> + const struct iio_chan_spec *chan,
> >> + char *buf)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> +
> >> + return snprintf(buf, PAGE_SIZE, "%d\n", adc->spi_freq);
> >> +}
> >> +
> >> +static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
> >> + uintptr_t priv,
> >> + const struct iio_chan_spec *chan,
> >> + const char *buf, size_t len)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
> >> + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
> >> + unsigned int sample_freq = adc->sample_freq;
> >> + unsigned int spi_freq;
> >> + int ret;
> >> +
> >> + dev_err(&indio_dev->dev, "enter %s\n", __func__);
> >> + /* If DFSDM is master on SPI, SPI freq can not be updated */
> >> + if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
> >> + return -EPERM;
> >> +
> >> + ret = kstrtoint(buf, 0, &spi_freq);
> >> + if (ret)
> >> + return ret;
> >> +
> >> + if (!spi_freq)
> >> + return -EINVAL;
> >> +
> >> + if (sample_freq) {
> >> + if (spi_freq % sample_freq)
> >> + dev_warn(&indio_dev->dev,
> >> + "Sampling rate not accurate (%d)\n",
> >> + spi_freq / (spi_freq / sample_freq));
> >> +
> >> + ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / sample_freq));
> >> + if (ret < 0) {
> >> + dev_err(&indio_dev->dev,
> >> + "No filter parameters that match!\n");
> >> + return ret;
> >> + }
> >> + }
> >> + adc->spi_freq = spi_freq;
> >> +
> >> + return len;
> >> +}
> >> +
> >> static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma)
> >> {
> >> struct regmap *regmap = adc->dfsdm->regmap;
> >> int ret;
> >> + unsigned int dma_en = 0, cont_en = 0;
> >>
> >> ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id);
> >> if (ret < 0)
> >> @@ -365,6 +436,24 @@ static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma)
> >> if (ret < 0)
> >> goto stop_channels;
> >>
> >> + if (dma) {
> >> + /* Enable DMA transfer*/
> >> + dma_en = DFSDM_CR1_RDMAEN(1);
> >> + /* Enable conversion triggered by SPI clock*/
> >> + cont_en = DFSDM_CR1_RCONT(1);
> >> + }
> >> + /* Enable DMA transfer*/
> >> + ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> >> + DFSDM_CR1_RDMAEN_MASK, dma_en);
> >> + if (ret < 0)
> >> + goto stop_channels;
> >> +
> >> + /* Enable conversion triggered by SPI clock*/
> >> + ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> >> + DFSDM_CR1_RCONT_MASK, cont_en);
> >> + if (ret < 0)
> >> + goto stop_channels;
> >> +
> >> ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
> >> if (ret < 0)
> >> goto stop_channels;
> >> @@ -398,6 +487,231 @@ static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
> >> stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id);
> >> }
> >>
> >> +static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev,
> >> + unsigned int val)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + unsigned int watermark = DFSDM_DMA_BUFFER_SIZE / 2;
> >> +
> >> + /*
> >> + * DMA cyclic transfers are used, buffer is split into two periods.
> >> + * There should be :
> >> + * - always one buffer (period) DMA is working on
> >> + * - one buffer (period) driver pushed to ASoC side.
> >> + */
> >> + watermark = min(watermark, val * (unsigned int)(sizeof(u32)));
> >> + adc->buf_sz = watermark * 2;
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc)
> >> +{
> >> + struct dma_tx_state state;
> >> + enum dma_status status;
> >> +
> >> + status = dmaengine_tx_status(adc->dma_chan,
> >> + adc->dma_chan->cookie,
> >> + &state);
> >> + if (status == DMA_IN_PROGRESS) {
> >> + /* Residue is size in bytes from end of buffer */
> >> + unsigned int i = adc->buf_sz - state.residue;
> >> + unsigned int size;
> >> +
> >> + /* Return available bytes */
> >> + if (i >= adc->bufi)
> >> + size = i - adc->bufi;
> >> + else
> >> + size = adc->buf_sz + i - adc->bufi;
> >> +
> >> + return size;
> >> + }
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static void stm32_dfsdm_audio_dma_buffer_done(void *data)
> >> +{
> >> + struct iio_dev *indio_dev = data;
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + int available = stm32_dfsdm_adc_dma_residue(adc);
> >> + size_t old_pos;
> >> +
> >> + /*
> >> + * FIXME: In Kernel interface does not support cyclic DMA buffer,and
> >> + * offers only an interface to push data samples per samples.
> >> + * For this reason IIO buffer interface is not used and interface is
> >> + * bypassed using a private callback registered by ASoC.
> >> + * This should be a temporary solution waiting a cyclic DMA engine
> >> + * support in IIO.
> >> + */
> >> +
> >> + dev_dbg(&indio_dev->dev, "%s: pos = %d, available = %d\n", __func__,
> >> + adc->bufi, available);
> >> + old_pos = adc->bufi;
> >> +
> >> + while (available >= indio_dev->scan_bytes) {
> >> + u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi];
> >> +
> >> + /* Mask 8 LSB that contains the channel ID */
> >> + *buffer = (*buffer & 0xFFFFFF00) << 8;
> >> + available -= indio_dev->scan_bytes;
> >> + adc->bufi += indio_dev->scan_bytes;
> >> + if (adc->bufi >= adc->buf_sz) {
> >> + if (adc->cb)
> >> + adc->cb(&adc->rx_buf[old_pos],
> >> + adc->buf_sz - old_pos, adc->cb_priv);
> >> + adc->bufi = 0;
> >> + old_pos = 0;
> >> + }
> >> + }
> >> + if (adc->cb)
> >> + adc->cb(&adc->rx_buf[old_pos], adc->bufi - old_pos,
> >> + adc->cb_priv);
> >> +}
> >> +
> >> +static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + struct dma_async_tx_descriptor *desc;
> >> + dma_cookie_t cookie;
> >> + int ret;
> >> +
> >> + if (!adc->dma_chan)
> >> + return -EINVAL;
> >> +
> >> + dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__,
> >> + adc->buf_sz, adc->buf_sz / 2);
> >> +
> >> + /* Prepare a DMA cyclic transaction */
> >> + desc = dmaengine_prep_dma_cyclic(adc->dma_chan,
> >> + adc->dma_buf,
> >> + adc->buf_sz, adc->buf_sz / 2,
> >> + DMA_DEV_TO_MEM,
> >> + DMA_PREP_INTERRUPT);
> >> + if (!desc)
> >> + return -EBUSY;
> >> +
> >> + desc->callback = stm32_dfsdm_audio_dma_buffer_done;
> >> + desc->callback_param = indio_dev;
> >> +
> >> + cookie = dmaengine_submit(desc);
> >> + ret = dma_submit_error(cookie);
> >> + if (ret) {
> >> + dmaengine_terminate_all(adc->dma_chan);
> >> + return ret;
> >> + }
> >> +
> >> + /* Issue pending DMA requests */
> >> + dma_async_issue_pending(adc->dma_chan);
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + int ret;
> >> +
> >> + /* Reset adc buffer index */
> >> + adc->bufi = 0;
> >> +
> >> + ret = stm32_dfsdm_start_dfsdm(adc->dfsdm);
> >> + if (ret < 0)
> >> + return ret;
> >> +
> >> + ret = stm32_dfsdm_start_conv(adc, true);
> >> + if (ret) {
> >> + dev_err(&indio_dev->dev, "Can't start conversion\n");
> >> + goto stop_dfsdm;
> >> + }
> >> +
> >> + if (adc->dma_chan) {
> >> + ret = stm32_dfsdm_adc_dma_start(indio_dev);
> >> + if (ret) {
> >> + dev_err(&indio_dev->dev, "Can't start DMA\n");
> >> + goto err_stop_conv;
> >> + }
> >> + }
> >> +
> >> + return 0;
> >> +
> >> +err_stop_conv:
> >> + stm32_dfsdm_stop_conv(adc);
> >> +stop_dfsdm:
> >> + stm32_dfsdm_stop_dfsdm(adc->dfsdm);
> >> +
> >> + return ret;
> >> +}
> >> +
> >> +static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> +
> >> + if (adc->dma_chan)
> >> + dmaengine_terminate_all(adc->dma_chan);
> >> +
> >> + stm32_dfsdm_stop_conv(adc);
> >> +
> >> + stm32_dfsdm_stop_dfsdm(adc->dfsdm);
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static const struct iio_buffer_setup_ops stm32_dfsdm_buffer_setup_ops = {
> >> + .postenable = &stm32_dfsdm_postenable,
> >> + .predisable = &stm32_dfsdm_predisable,
> >> +};
> >> +
> >> +/**
> >> + * stm32_dfsdm_get_buff_cb() - register a callback that will be called when
> >> + * DMA transfer period is achieved.
> >> + *
> >> + * @iio_dev: Handle to IIO device.
> >> + * @cb: Pointer to callback function:
> >> + * - data: pointer to data buffer
> >> + * - size: size in byte of the data buffer
> >> + * - private: pointer to consumer private structure.
> >> + * @private: Pointer to consumer private structure.
> >> + */
> >> +int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
> >> + int (*cb)(const void *data, size_t size,
> >> + void *private),
> >> + void *private)
> >> +{
> >> + struct stm32_dfsdm_adc *adc;
> >> +
> >> + if (!iio_dev)
> >> + return -EINVAL;
> >> + adc = iio_priv(iio_dev);
> >> +
> >> + adc->cb = cb;
> >> + adc->cb_priv = private;
> >> +
> >> + return 0;
> >> +}
> >> +EXPORT_SYMBOL_GPL(stm32_dfsdm_get_buff_cb);
> >> +
> >> +/**
> >> + * stm32_dfsdm_release_buff_cb - unregister buffer callback
> >> + *
> >> + * @iio_dev: Handle to IIO device.
> >> + */
> >> +int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev)
> >> +{
> >> + struct stm32_dfsdm_adc *adc;
> >> +
> >> + if (!iio_dev)
> >> + return -EINVAL;
> >> + adc = iio_priv(iio_dev);
> >> +
> >> + adc->cb = NULL;
> >> + adc->cb_priv = NULL;
> >> +
> >> + return 0;
> >> +}
> >> +EXPORT_SYMBOL_GPL(stm32_dfsdm_release_buff_cb);
> >> +
> >> static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
> >> const struct iio_chan_spec *chan, int *res)
> >> {
> >> @@ -453,15 +767,41 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
> >> {
> >> struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
> >> + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
> >> + unsigned int spi_freq = adc->spi_freq;
> >> int ret = -EINVAL;
> >>
> >> - if (mask == IIO_CHAN_INFO_OVERSAMPLING_RATIO) {
> >> + switch (mask) {
> >> + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> >> ret = stm32_dfsdm_set_osrs(fl, 0, val);
> >> if (!ret)
> >> adc->oversamp = val;
> >> +
> >> + return ret;
> >> +
> >> + case IIO_CHAN_INFO_SAMP_FREQ:
> >> + if (!val)
> >> + return -EINVAL;
> >> + if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
> >> + spi_freq = adc->dfsdm->spi_master_freq;
> >> +
> >> + if (spi_freq % val)
> >> + dev_warn(&indio_dev->dev,
> >> + "Sampling rate not accurate (%d)\n",
> >> + spi_freq / (spi_freq / val));
> >> +
> >> + ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / val));
> >> + if (ret < 0) {
> >> + dev_err(&indio_dev->dev,
> >> + "Not able to find parameter that match!\n");
> >> + return ret;
> >> + }
> >> + adc->sample_freq = val;
> >> +
> >> + return 0;
> >> }
> >>
> >> - return ret;
> >> + return -EINVAL;
> >> }
> >>
> >> static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
> >> @@ -494,11 +834,22 @@ static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
> >> *val = adc->oversamp;
> >>
> >> return IIO_VAL_INT;
> >> +
> >> + case IIO_CHAN_INFO_SAMP_FREQ:
> >> + *val = adc->sample_freq;
> >> +
> >> + return IIO_VAL_INT;
> >> }
> >>
> >> return -EINVAL;
> >> }
> >>
> >> +static const struct iio_info stm32_dfsdm_info_audio = {
> >> + .hwfifo_set_watermark = stm32_dfsdm_set_watermark,
> >> + .read_raw = stm32_dfsdm_read_raw,
> >> + .write_raw = stm32_dfsdm_write_raw,
> >> +};
> >> +
> >> static const struct iio_info stm32_dfsdm_info_adc = {
> >> .read_raw = stm32_dfsdm_read_raw,
> >> .write_raw = stm32_dfsdm_write_raw,
> >> @@ -531,6 +882,60 @@ static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> >> return IRQ_HANDLED;
> >> }
> >>
> >> +/*
> >> + * Define external info for SPI Frequency and audio sampling rate that can be
> >> + * configured by ASoC driver through consumer.h API
> >> + */
> >> +static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = {
> >> + /* spi_clk_freq : clock freq on SPI/manchester bus used by channel */
> >> + {
> >> + .name = "spi_clk_freq",
> >> + .shared = IIO_SHARED_BY_TYPE,
> >> + .read = dfsdm_adc_audio_get_spiclk,
> >> + .write = dfsdm_adc_audio_set_spiclk,
> >> + },
> >> + {},
> >> +};
> >> +
> >> +static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev)
> >> +{
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + struct dma_slave_config config;
> >> + int ret;
> >> +
> >> + adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx");
> >> + if (!adc->dma_chan)
> >> + return -EINVAL;
> >> +
> >> + adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev,
> >> + DFSDM_DMA_BUFFER_SIZE,
> >> + &adc->dma_buf, GFP_KERNEL);
> >> + if (!adc->rx_buf) {
> >> + ret = -ENOMEM;
> >> + goto err_release;
> >> + }
> >> +
> >> + /* Configure DMA channel to read data register */
> >> + memset(&config, 0, sizeof(config));
> >> + config.src_addr = (dma_addr_t)adc->dfsdm->phys_base;
> >> + config.src_addr += DFSDM_RDATAR(adc->fl_id);
> >> + config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> >> +
> >> + ret = dmaengine_slave_config(adc->dma_chan, &config);
> >> + if (ret)
> >> + goto err_free;
> >> +
> >> + return 0;
> >> +
> >> +err_free:
> >> + dma_free_coherent(adc->dma_chan->device->dev, DFSDM_DMA_BUFFER_SIZE,
> >> + adc->rx_buf, adc->dma_buf);
> >> +err_release:
> >> + dma_release_channel(adc->dma_chan);
> >> +
> >> + return ret;
> >> +}
> >> +
> >> static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
> >> struct iio_chan_spec *ch)
> >> {
> >> @@ -551,7 +956,12 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
> >> ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
> >> ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
> >>
> >> - ch->scan_type.sign = 'u';
> >> + if (adc->dev_data->type == DFSDM_AUDIO) {
> >> + ch->scan_type.sign = 's';
> >> + ch->ext_info = dfsdm_adc_audio_ext_info;
> >> + } else {
> >> + ch->scan_type.sign = 'u';
> >> + }
> >> ch->scan_type.realbits = 24;
> >> ch->scan_type.storagebits = 32;
> >> adc->ch_id = ch->channel;
> >> @@ -560,6 +970,64 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
> >> &adc->dfsdm->ch_list[ch->channel]);
> >> }
> >>
> >> +static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev)
> >> +{
> >> + struct iio_chan_spec *ch;
> >> + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >> + struct stm32_dfsdm_channel *d_ch;
> >> + int ret;
> >> +
> >> + ret = stm32_dfsdm_dma_request(indio_dev);
> >> + if (ret) {
> >> + dev_err(&indio_dev->dev, "DMA request failed\n");
> >> + return ret;
> >> + }
> >> +
> >> + indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> >> +
> >> + ret = iio_triggered_buffer_setup(indio_dev,
> >> + &iio_pollfunc_store_time,
> >> + NULL,
> >> + &stm32_dfsdm_buffer_setup_ops);
> >> + if (ret) {
> >> + dev_err(&indio_dev->dev, "Buffer setup failed\n");
> >> + goto err_dma_disable;
> >> + }
> >> +
> >> + ch = devm_kzalloc(&indio_dev->dev, sizeof(*ch), GFP_KERNEL);
> >> + if (!ch)
> >> + return -ENOMEM;
> >> +
> >> + ch->scan_index = 0;
> >> + ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
> >> + if (ret < 0) {
> >> + dev_err(&indio_dev->dev, "channels init failed\n");
> >> + goto err_buffer_cleanup;
> >> + }
> >> + ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ);
> >> +
> >> + d_ch = &adc->dfsdm->ch_list[adc->ch_id];
> >> + if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
> >> + adc->spi_freq = adc->dfsdm->spi_master_freq;
> >> +
> >> + indio_dev->num_channels = 1;
> >> + indio_dev->channels = ch;
> >> +
> >> + return 0;
> >> +
> >> +err_buffer_cleanup:
> >> + iio_triggered_buffer_cleanup(indio_dev);
> >> +
> >> +err_dma_disable:
> >> + if (adc->dma_chan) {
> >> + dma_free_coherent(adc->dma_chan->device->dev,
> >> + DFSDM_DMA_BUFFER_SIZE,
> >> + adc->rx_buf, adc->dma_buf);
> >> + dma_release_channel(adc->dma_chan);
> >> + }
> >> + return ret;
> >> +}
> >> +
> >> static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
> >> {
> >> struct iio_chan_spec *ch;
> >> @@ -612,11 +1080,20 @@ static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_adc_data = {
> >> .init = stm32_dfsdm_adc_init,
> >> };
> >>
> >> +static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_audio_data = {
> >> + .type = DFSDM_AUDIO,
> >> + .init = stm32_dfsdm_audio_init,
> >> +};
> >> +
> >> static const struct of_device_id stm32_dfsdm_adc_match[] = {
> >> {
> >> .compatible = "st,stm32-dfsdm-adc",
> >> .data = &stm32h7_dfsdm_adc_data,
> >> },
> >> + {
> >> + .compatible = "st,stm32-dfsdm-dmic",
> >> + .data = &stm32h7_dfsdm_audio_data,
> >> + },
> >> {}
> >> };
> >>
> >> @@ -667,8 +1144,13 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
> >> name = devm_kzalloc(dev, sizeof("dfsdm-adc0"), GFP_KERNEL);
> >> if (!name)
> >> return -ENOMEM;
> >> - iio->info = &stm32_dfsdm_info_adc;
> >> - snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id);
> >> + if (dev_data->type == DFSDM_AUDIO) {
> >> + iio->info = &stm32_dfsdm_info_audio;
> >> + snprintf(name, sizeof("dfsdm-pdm0"), "dfsdm-pdm%d", adc->fl_id);
> >> + } else {
> >> + iio->info = &stm32_dfsdm_info_adc;
> >> + snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id);
> >> + }
> >> iio->name = name;
> >>
> >> /*
> >> @@ -700,7 +1182,10 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
> >> if (ret < 0)
> >> return ret;
> >>
> >> - return iio_device_register(iio);
> >> + iio_device_register(iio);
> >> + if (dev_data->type == DFSDM_AUDIO)
> >> + return devm_of_platform_populate(&pdev->dev);
> >> + return 0;
> >> }
> >>
> >> static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
> >> @@ -709,7 +1194,14 @@ static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
> >> struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> >>
> >> iio_device_unregister(indio_dev);
> >> -
> >> + if (indio_dev->pollfunc)
> >> + iio_triggered_buffer_cleanup(indio_dev);
> >> + if (adc->dma_chan) {
> >> + dma_free_coherent(adc->dma_chan->device->dev,
> >> + DFSDM_DMA_BUFFER_SIZE,
> >> + adc->rx_buf, adc->dma_buf);
> >> + dma_release_channel(adc->dma_chan);
> >> + }
> >> return 0;
> >> }
> >>
> >> diff --git a/include/linux/iio/adc/stm32-dfsdm-adc.h b/include/linux/iio/adc/stm32-dfsdm-adc.h
> >> new file mode 100644
> >> index 0000000..e7dc7a5
> >> --- /dev/null
> >> +++ b/include/linux/iio/adc/stm32-dfsdm-adc.h
> >> @@ -0,0 +1,18 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +/*
> >> + * This file discribe the STM32 DFSDM IIO driver API for audio part
> >> + *
> >> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
> >> + * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>.
> >> + */
> >> +
> >> +#ifndef STM32_DFSDM_ADC_H
> >> +#define STM32_DFSDM_ADC_H
> >> +
> >> +int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
> >> + int (*cb)(const void *data, size_t size,
> >> + void *private),
> >> + void *private);
> >> +int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev);
> >> +
> >> +#endif
> >
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] KVM: arm/arm64: don't set vtimer->cnt_ctl in kvm_arch_timer_handler
From: Christoffer Dall @ 2017-12-13 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b2d0234c-e763-d4c1-02f7-c50cd0914b13@arm.com>
On Wed, Dec 13, 2017 at 08:56:12AM +0000, Marc Zyngier wrote:
> Hi Jia,
>
> On 13/12/17 07:00, Jia He wrote:
> > In our Armv8a server (qualcomm Amberwing, non VHE), after applying
> > Christoffer's timer optimizing patchset(Optimize arch timer register
> > handling), the guest is hang during kernel booting.
> >
> > The error root cause might be as follows:
> > 1. in kvm_arch_timer_handler, it reset vtimer->cnt_ctl with current
> > cntv_ctl register value. And then it missed some cases to update timer's
> > irq (irq.level) when kvm_timer_irq_can_fire() is false
> > 2. It causes kvm_vcpu_check_block return 0 instead of -EINTR
> > kvm_vcpu_check_block
> > kvm_cpu_has_pending_timer
> > kvm_timer_is_pending
> > kvm_timer_should_fire
> > 3. Thus, the kvm hyp code can not break the loop in kvm_vcpu_block (halt
> > poll process) and the guest is hang forever
> >
> > Fixes: b103cc3f10c0 ("KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit")
> > Signed-off-by: Jia He <jia.he@hxt-semitech.com>
> > ---
> > virt/kvm/arm/arch_timer.c | 1 -
> > 1 file changed, 1 deletion(-)
> >
> > diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> > index f9555b1..bb86433 100644
> > --- a/virt/kvm/arm/arch_timer.c
> > +++ b/virt/kvm/arm/arch_timer.c
> > @@ -100,7 +100,6 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
> > vtimer = vcpu_vtimer(vcpu);
> >
> > if (!vtimer->irq.level) {
> > - vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
> > if (kvm_timer_irq_can_fire(vtimer))
> > kvm_timer_update_irq(vcpu, true, vtimer);
> > }
> >
>
> Which patches are you looking at? The current code in mainline looks
> like this:
>
> vtimer = vcpu_vtimer(vcpu);
>
> vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
> if (kvm_timer_irq_can_fire(vtimer))
> kvm_timer_update_irq(vcpu, true, vtimer);
>
> I'd suggest you use mainline and report if this doesn't work.
>
That looks like you have the level-triggered mapped series applied?
That would be an interesting data point to get from Jia as well though.
Jia, can you try applying this series and see if it helps?
git://git.kernel.org/pub/scm/linux/kernel/git/cdall/linux.git level-mapped-v7
Thanks,
-Christoffer
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v2 3/4] thermal: armada: add support for CP110
From: Gregory CLEMENT @ 2017-12-13 9:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213091040.jwsphlax4yidm4qp@sapphire.tkos.co.il>
Hi Baruch,
On mer., d?c. 13 2017, Baruch Siach <baruch@tkos.co.il> wrote:
> Hi Miquel,
>
> On Wed, Dec 13, 2017 at 09:55:01AM +0100, Miquel RAYNAL wrote:
>> > > > How would a separate init_sensor routine improve things?
>> > >
>> > > So yes please do it, thanks to this you won't have to add the
>> > > control_msb_offset member and can use a clean function. Moreover if
>> > > in the future we see some usefulness for this LSB register then we
>> > > could use the new compatible for the Armada 38x.
>> >
>> > There are two separate issues here:
>> >
>> > 1. DT binding
>> >
>> > 2. init_sensor callback implementation
>> >
>> > We both agree on #1. The A38x and CP110 need separate compatible
>> > strings. In case we want to access the LSB control register on Armada
>> > 38x, we will need yet another compatible string
>> > (marvell,armada380-v2-thermal maybe?).
>> >
>> > As for #2, I'm all for sharing as much code as possible. I find the
>> > vendor kernel approach of duplicating the init routines[1] unhelpful
>> > as it violates the DRY principle. The differences between
>> > armada380_init_sensor() and cp110_init_sensor() are minor. In my
>> > opinion, these differences should be expressed explicitly in the
>> > armada_thermal_data, in a similar way to my suggested
>> > control_msb_offset field. The vendor code hides these differences in
>> > slight variations of duplicated code.
>> >
>> > What is the advantage of a separate init routine?
>>
>> The advantage is that is the very near future I plan to add the
>> overheat interrupt only on CP110 (not on 38x) and this needs some
>> initialization. So if we don't make different routines now, I will
>> have to do it right after.
>
> I don't think so. The code of these functions in the vendor kernel overheat
> support implementation is the same, duplicated. The variations are only in
> registers/bits offsets. A single routine with one or two added
> armada_thermal_data fields would be much easier to comprehend and maintain.
>
>> What would be fine is to have the shared code in a separate function,
>> like it is done in Marvell kernel. What do you think about that?
>
> The Marvell code does not "share" the code. Separate functions means
> duplicated code that obscures the hardware details, making maintenance harder
> on the long run.
Well, Miquel speak about writting new code, so I don't see why you refer
the Marvell LSP code. Also, I don't see how having common function will
duplicate the code.
Gregory
>
> https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
>
> baruch
>
> --
> http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
> - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] arm64: mm: Fix false positives in set_pte_at access/dirty race detection
From: Will Deacon @ 2017-12-13 9:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8761ce54-ad67-1113-44e1-0d1606d12dbf@huawei.com>
Hi Yisheng,
On Wed, Dec 13, 2017 at 09:01:23AM +0800, Yisheng Xie wrote:
> On 2017/12/12 19:43, Will Deacon wrote:
> > Jiankang reports that our race detection in set_pte_at is firing when
> > copying the page tables in dup_mmap as a result of a fork(). In this
> > situation, the page table isn't actually live and so there is no way
> > that we can race with a concurrent update from the hardware page table
> > walker.
> >
> > This patch reworks the race detection so that we require either the
> > mm to match the current active_mm (i.e. currently installed in our TTBR0)
> > or the mm_users count to be greater than 1, implying that the page table
> > could be live in another CPU. The mm_users check might still be racy,
> > but we'll avoid false positives and it's not realistic to validate that
> > all the necessary locks are held as part of this assertion.
> >
> > Cc: Yisheng Xie <xieyisheng1@huawei.com>
> > Reported-by: Jiankang Chen <chenjiankang1@huawei.com>
> > Tested-by: Jiankang Chen <chenjiankang1@huawei.com>
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > ---
> > arch/arm64/include/asm/pgtable.h | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 3ff03a755c32..bdcc7f1c9d06 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -42,6 +42,8 @@
> > #include <asm/cmpxchg.h>
> > #include <asm/fixmap.h>
> > #include <linux/mmdebug.h>
> > +#include <linux/mm_types.h>
> > +#include <linux/sched.h>
> >
>
> Do you have compiled kernel after apply this patch? In our environment, it will
> fail to compile kernel if include file here(I will attach some log later).
> Instead, we move these included file after mmdebug.h, and I do not know whether
> this is just my compiler's problem:
It compiles fine for me. Are you seeing a problem building this on top of
mainline? If so, what is your .config?
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -42,6 +42,8 @@
> #include <asm/cmpxchg.h>
> #include <asm/fixmap.h>
> #include <linux/mmdebug.h>
> +#include <linux/mm_types.h>
> +#include <linux/sched.h>
>
> Sorry for not having told you this information.
>
> Thanks
> Yisheng Xie
>
> compiler err log: ==========
> [...]
> include/linux/mm_types_task.h:60: Error: unknown mnemonic `struct' -- `struct page_frag{'
> include/asm-generic/preempt.h:9: Error: unknown mnemonic `static' -- `static inline int preempt_count(void)'
> include/linux/mm_types_task.h:61: Error: unknown mnemonic `struct' -- `struct page*page'
> include/asm-generic/preempt.h:10: Error: junk at end of line, first unrecognized character is `{'
> include/linux/mm_types_task.h:63: Error: unknown mnemonic `__u32' -- `__u32 offset'
> include/asm-generic/preempt.h:11: Error: unknown mnemonic `return' -- `return READ_ONCE(((struct thread_info*)current)->preempt_count)'
> include/linux/mm_types_task.h:64: Error: unknown mnemonic `__u32' -- `__u32 size'
> [...]
This looks like the includes are being pulled into an assembly file, but
this part is guarded by #ifndef __ASSEMBLY__ so I can't see how that could
happen.
Will
^ permalink raw reply
* [PATCH 0/5] Add Sound support for iWave RZ/G1M board
From: Biju Das @ 2017-12-13 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213090240.xqgihh4bqsfzeaip@verge.net.au>
Hi Simon,
Thanks.
There is a typo in the documentation dependency link.
The correct one is https://patchwork.kernel.org/patch/10108015/
Regards,
Biju
> -----Original Message-----
> From: Simon Horman [mailto:horms at verge.net.au]
> Sent: 13 December 2017 09:03
> To: Biju Das <biju.das@bp.renesas.com>
> Cc: Rob Herring <robh+dt@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>; Russell King <linux@armlinux.org.uk>; Magnus
> Damm <magnus.damm@gmail.com>; Chris Paterson
> <Chris.Paterson2@renesas.com>; devicetree at vger.kernel.org; linux-renesas-
> soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 0/5] Add Sound support for iWave RZ/G1M board
>
> On Tue, Dec 12, 2017 at 06:25:06PM +0000, Biju Das wrote:
> > This series aims to add sound support for iWave RZ/G1M board.
> >
> > This patch series has documentation dependency on
> > https://patchwork.kernel.org/patch/10108014/
> >
> > Biju Das (5):
> > ARM: shmobile: defconfig: Enable SGTL5000 audio codec
> > ARM: dts: r8a7743: Add audio clocks
> > ARM: dts: r8a7743: Add audio DMAC support
> > ARM: dts: r8a7743: Add sound support
> > ARM: dts: iwg20d-q7-common: Enable SGTL5000 audio codec
> >
> > arch/arm/boot/dts/iwg20d-q7-common.dtsi | 24 +++
> > arch/arm/boot/dts/r8a7743.dtsi | 270
> ++++++++++++++++++++++++++++++++
> > arch/arm/configs/shmobile_defconfig | 1 +
> > 3 files changed, 295 insertions(+)
>
> These patches seem clean to me although I do not have sufficient
> documentation to properly review the last patch.
>
> I will leave these sit for a few days to allow others to review them.
[https://www2.renesas.eu/media/email/unicef_2017.jpg]
This Christmas, instead of sending out cards, Renesas Electronics Europe have decided to support Unicef with a donation. For further details click here<https://www.unicef.org/> to find out about the valuable work they do, helping children all over the world.
We would like to take this opportunity to wish you a Merry Christmas and a prosperous New Year.
Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
^ permalink raw reply
* [PATCH] KVM: arm/arm64: don't set vtimer->cnt_ctl in kvm_arch_timer_handler
From: Marc Zyngier @ 2017-12-13 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f0252a5a-cb81-ce24-5d46-f19fce054b13@redhat.com>
On 13/12/17 09:08, Auger Eric wrote:
> Marc,
> On 13/12/17 09:56, Marc Zyngier wrote:
>> Hi Jia,
>>
>> On 13/12/17 07:00, Jia He wrote:
>>> In our Armv8a server (qualcomm Amberwing, non VHE), after applying
>>> Christoffer's timer optimizing patchset(Optimize arch timer register
>>> handling), the guest is hang during kernel booting.
>>>
>>> The error root cause might be as follows:
>>> 1. in kvm_arch_timer_handler, it reset vtimer->cnt_ctl with current
>>> cntv_ctl register value. And then it missed some cases to update timer's
>>> irq (irq.level) when kvm_timer_irq_can_fire() is false
>>> 2. It causes kvm_vcpu_check_block return 0 instead of -EINTR
>>> kvm_vcpu_check_block
>>> kvm_cpu_has_pending_timer
>>> kvm_timer_is_pending
>>> kvm_timer_should_fire
>>> 3. Thus, the kvm hyp code can not break the loop in kvm_vcpu_block (halt
>>> poll process) and the guest is hang forever
>>>
>>> Fixes: b103cc3f10c0 ("KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit")
>>> Signed-off-by: Jia He <jia.he@hxt-semitech.com>
>>> ---
>>> virt/kvm/arm/arch_timer.c | 1 -
>>> 1 file changed, 1 deletion(-)
>>>
>>> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
>>> index f9555b1..bb86433 100644
>>> --- a/virt/kvm/arm/arch_timer.c
>>> +++ b/virt/kvm/arm/arch_timer.c
>>> @@ -100,7 +100,6 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
>>> vtimer = vcpu_vtimer(vcpu);
>>>
>>> if (!vtimer->irq.level) {
>>> - vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
>>> if (kvm_timer_irq_can_fire(vtimer))
>>> kvm_timer_update_irq(vcpu, true, vtimer);
>>> }
>>>
>>
>> Which patches are you looking at? The current code in mainline looks
>> like this:
>>
>> vtimer = vcpu_vtimer(vcpu);
>>
>> vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
>> if (kvm_timer_irq_can_fire(vtimer))
>> kvm_timer_update_irq(vcpu, true, vtimer);
>>
>> I'd suggest you use mainline and report if this doesn't work
> the removal of if (!vtimer->irq.level) test happened in:
> [PATCH v7 3/8] KVM: arm/arm64: Don't cache the timer IRQ level
>
> which is not upstream.
Ah, my bad (I have that series in my working tree already...).
I still think Jia's approach to this is not quite right. If you don't
update the status of the timer by reading the HW value, how can you
decide whether the timer can fire or not?
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH] nvmem: uniphier: change access unit from 32bit to 8bit
From: Kunihiko Hayashi @ 2017-12-13 9:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1511327699-26396-1-git-send-email-hayashi.kunihiko@socionext.com>
Hello Srinivas,
This patch was already reviewed and tested for all UniPhier SoCs:
https://patchwork.kernel.org/patch/10069557/
Do you have any comments, or would you please pick it up?
Thank you,
On Wed, 22 Nov 2017 14:14:59 +0900 Kunihiko Hayashi <hayashi.kunihiko@socionext.com> wrote:
> The efuse on UniPhier allows 8bit access according to the specification.
> Since bit offset of nvmem is limited to 0-7, it is desiable to change
> access unit of nvmem to 8bit.
>
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> ---
> drivers/nvmem/uniphier-efuse.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c
> index 2bb45c4..fac3122 100644
> --- a/drivers/nvmem/uniphier-efuse.c
> +++ b/drivers/nvmem/uniphier-efuse.c
> @@ -27,11 +27,11 @@ static int uniphier_reg_read(void *context,
> unsigned int reg, void *_val, size_t bytes)
> {
> struct uniphier_efuse_priv *priv = context;
> - u32 *val = _val;
> + u8 *val = _val;
> int offs;
>
> - for (offs = 0; offs < bytes; offs += sizeof(u32))
> - *val++ = readl(priv->base + reg + offs);
> + for (offs = 0; offs < bytes; offs += sizeof(u8))
> + *val++ = readb(priv->base + reg + offs);
>
> return 0;
> }
> @@ -53,8 +53,8 @@ static int uniphier_efuse_probe(struct platform_device *pdev)
> if (IS_ERR(priv->base))
> return PTR_ERR(priv->base);
>
> - econfig.stride = 4;
> - econfig.word_size = 4;
> + econfig.stride = 1;
> + econfig.word_size = 1;
> econfig.read_only = true;
> econfig.reg_read = uniphier_reg_read;
> econfig.size = resource_size(res);
> --
> 2.7.4
---
Best Regards,
Kunihiko Hayashi
^ permalink raw reply
* [PATCH] KVM: arm/arm64: don't set vtimer->cnt_ctl in kvm_arch_timer_handler
From: Christoffer Dall @ 2017-12-13 9:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <daece017-50be-494f-4176-6e5f081edfa2@arm.com>
On Wed, Dec 13, 2017 at 10:27 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 13/12/17 09:08, Auger Eric wrote:
>> Marc,
>> On 13/12/17 09:56, Marc Zyngier wrote:
>>> Hi Jia,
>>>
>>> On 13/12/17 07:00, Jia He wrote:
>>>> In our Armv8a server (qualcomm Amberwing, non VHE), after applying
>>>> Christoffer's timer optimizing patchset(Optimize arch timer register
>>>> handling), the guest is hang during kernel booting.
>>>>
>>>> The error root cause might be as follows:
>>>> 1. in kvm_arch_timer_handler, it reset vtimer->cnt_ctl with current
>>>> cntv_ctl register value. And then it missed some cases to update timer's
>>>> irq (irq.level) when kvm_timer_irq_can_fire() is false
>>>> 2. It causes kvm_vcpu_check_block return 0 instead of -EINTR
>>>> kvm_vcpu_check_block
>>>> kvm_cpu_has_pending_timer
>>>> kvm_timer_is_pending
>>>> kvm_timer_should_fire
>>>> 3. Thus, the kvm hyp code can not break the loop in kvm_vcpu_block (halt
>>>> poll process) and the guest is hang forever
>>>>
>>>> Fixes: b103cc3f10c0 ("KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit")
>>>> Signed-off-by: Jia He <jia.he@hxt-semitech.com>
>>>> ---
>>>> virt/kvm/arm/arch_timer.c | 1 -
>>>> 1 file changed, 1 deletion(-)
>>>>
>>>> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
>>>> index f9555b1..bb86433 100644
>>>> --- a/virt/kvm/arm/arch_timer.c
>>>> +++ b/virt/kvm/arm/arch_timer.c
>>>> @@ -100,7 +100,6 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
>>>> vtimer = vcpu_vtimer(vcpu);
>>>>
>>>> if (!vtimer->irq.level) {
>>>> - vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
>>>> if (kvm_timer_irq_can_fire(vtimer))
>>>> kvm_timer_update_irq(vcpu, true, vtimer);
>>>> }
>>>>
>>>
>>> Which patches are you looking at? The current code in mainline looks
>>> like this:
>>>
>>> vtimer = vcpu_vtimer(vcpu);
>>>
>>> vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
>>> if (kvm_timer_irq_can_fire(vtimer))
>>> kvm_timer_update_irq(vcpu, true, vtimer);
>>>
>>> I'd suggest you use mainline and report if this doesn't work
>> the removal of if (!vtimer->irq.level) test happened in:
>> [PATCH v7 3/8] KVM: arm/arm64: Don't cache the timer IRQ level
>>
>> which is not upstream.
> Ah, my bad (I have that series in my working tree already...).
>
> I still think Jia's approach to this is not quite right. If you don't
> update the status of the timer by reading the HW value, how can you
> decide whether the timer can fire or not?
>
Exactly. We need to know the exact kernel source, symptoms, how to
reproduce, and then trace what's going on. It may be needed to tweak
kvm_timer_is_pending(), but I don't yet see a case where it breaks.
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH] nvmem: uniphier: change access unit from 32bit to 8bit
From: Srinivas Kandagatla @ 2017-12-13 9:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213183152.A835.4A936039@socionext.com>
On 13/12/17 09:31, Kunihiko Hayashi wrote:
> Hello Srinivas,
>
> This patch was already reviewed and tested for all UniPhier SoCs:
> https://patchwork.kernel.org/patch/10069557/
>
> Do you have any comments, or would you please pick it up?
Thanks for your patience,
I will send it along with other fixes to Greg Sometime this week!
Rgrds,
Srini
>
> Thank you,
>
> On Wed, 22 Nov 2017 14:14:59 +0900 Kunihiko Hayashi <hayashi.kunihiko@socionext.com> wrote:
>
>> The efuse on UniPhier allows 8bit access according to the specification.
>> Since bit offset of nvmem is limited to 0-7, it is desiable to change
>> access unit of nvmem to 8bit.
>>
>> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
>> ---
>> drivers/nvmem/uniphier-efuse.c | 10 +++++-----
>> 1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c
>> index 2bb45c4..fac3122 100644
>> --- a/drivers/nvmem/uniphier-efuse.c
>> +++ b/drivers/nvmem/uniphier-efuse.c
>> @@ -27,11 +27,11 @@ static int uniphier_reg_read(void *context,
>> unsigned int reg, void *_val, size_t bytes)
>> {
>> struct uniphier_efuse_priv *priv = context;
>> - u32 *val = _val;
>> + u8 *val = _val;
>> int offs;
>>
>> - for (offs = 0; offs < bytes; offs += sizeof(u32))
>> - *val++ = readl(priv->base + reg + offs);
>> + for (offs = 0; offs < bytes; offs += sizeof(u8))
>> + *val++ = readb(priv->base + reg + offs);
>>
>> return 0;
>> }
>> @@ -53,8 +53,8 @@ static int uniphier_efuse_probe(struct platform_device *pdev)
>> if (IS_ERR(priv->base))
>> return PTR_ERR(priv->base);
>>
>> - econfig.stride = 4;
>> - econfig.word_size = 4;
>> + econfig.stride = 1;
>> + econfig.word_size = 1;
>> econfig.read_only = true;
>> econfig.reg_read = uniphier_reg_read;
>> econfig.size = resource_size(res);
>> --
>> 2.7.4
>
> ---
> Best Regards,
> Kunihiko Hayashi
>
>
^ permalink raw reply
* [PATCH V4 03/12] drivers: Add boot constraints core
From: Greg Kroah-Hartman @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2868a37e561cab91ba5495a1e14b9548c8e93c3e.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:51PM +0530, Viresh Kumar wrote:
> Some devices are powered ON by the bootloader before the bootloader
> handovers control to Linux. It maybe important for those devices to keep
> working until the time a Linux device driver probes the device and
> reconfigure its resources.
>
> A typical example of that can be the LCD controller, which is used by
> the bootloaders to show image(s) while the platform is booting into
> Linux. The LCD controller can be using some resources, like clk,
> regulators, PM domain, etc, that are shared between several devices.
> These shared resources should be configured to satisfy need of all the
> users. If another device's (X) driver gets probed before the LCD
> controller driver in this case, then it may end up reconfiguring these
> resources to ranges satisfying the current users (only device X) and
> that can make the LCD screen unstable.
>
> This patch introduces the concept of boot-constraints, which will be set
> by the bootloaders and the kernel will satisfy them until the time
> driver for such a device is probed (successfully or unsuccessfully).
>
> The list of boot constraint types is empty for now, and will be
> incrementally updated by later patches.
>
> Only two routines are exposed by the boot constraints core for now:
>
> - dev_boot_constraint_add(): This shall be called by parts of the kernel
> (before the device is probed) to set the constraints.
>
> - dev_boot_constraints_remove(): This is called only by the driver core
> after a device is probed successfully or unsuccessfully. Special
> handling is done here for deferred probing.
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Minor nits:
> ---
> drivers/Kconfig | 2 +
> drivers/Makefile | 1 +
> drivers/base/dd.c | 20 ++--
> drivers/boot_constraints/Kconfig | 9 ++
> drivers/boot_constraints/Makefile | 3 +
> drivers/boot_constraints/core.c | 199 ++++++++++++++++++++++++++++++++++++++
> drivers/boot_constraints/core.h | 33 +++++++
> include/linux/boot_constraint.h | 46 +++++++++
> 8 files changed, 306 insertions(+), 7 deletions(-)
> create mode 100644 drivers/boot_constraints/Kconfig
> create mode 100644 drivers/boot_constraints/Makefile
> create mode 100644 drivers/boot_constraints/core.c
> create mode 100644 drivers/boot_constraints/core.h
> create mode 100644 include/linux/boot_constraint.h
>
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index 505c676fa9c7..e595ffad2214 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -4,6 +4,8 @@ source "drivers/amba/Kconfig"
>
> source "drivers/base/Kconfig"
>
> +source "drivers/boot_constraints/Kconfig"
> +
> source "drivers/bus/Kconfig"
>
> source "drivers/connector/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index d90fdc413648..29d03466cb2a 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -72,6 +72,7 @@ obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
> obj-$(CONFIG_PARPORT) += parport/
> obj-$(CONFIG_NVM) += lightnvm/
> obj-y += base/ block/ misc/ mfd/ nfc/
> +obj-$(CONFIG_DEV_BOOT_CONSTRAINTS) += boot_constraints/
> obj-$(CONFIG_LIBNVDIMM) += nvdimm/
> obj-$(CONFIG_DAX) += dax/
> obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index ad44b40fe284..4eec27fe2b2b 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -17,6 +17,7 @@
> * This file is released under the GPLv2
> */
Can you rebase this patch, I think it will have conflicts or fuzz here.
>
> +#include <linux/boot_constraint.h>
> #include <linux/device.h>
> #include <linux/delay.h>
> #include <linux/dma-mapping.h>
> @@ -409,15 +410,20 @@ static int really_probe(struct device *dev, struct device_driver *drv)
> */
> devices_kset_move_last(dev);
>
> - if (dev->bus->probe) {
> + if (dev->bus->probe)
> ret = dev->bus->probe(dev);
> - if (ret)
> - goto probe_failed;
> - } else if (drv->probe) {
> + else if (drv->probe)
> ret = drv->probe(dev);
> - if (ret)
> - goto probe_failed;
> - }
> +
> + /*
> + * Remove boot constraints for both successful and unsuccessful probe(),
> + * except for the case where EPROBE_DEFER is returned by probe().
> + */
> + if (ret != -EPROBE_DEFER)
> + dev_boot_constraints_remove(dev);
This feels odd, but ok, I trust you :)
> +
> + if (ret)
> + goto probe_failed;
>
> if (test_remove) {
> test_remove = false;
> diff --git a/drivers/boot_constraints/Kconfig b/drivers/boot_constraints/Kconfig
> new file mode 100644
> index 000000000000..77831af1c6fb
> --- /dev/null
> +++ b/drivers/boot_constraints/Kconfig
> @@ -0,0 +1,9 @@
> +config DEV_BOOT_CONSTRAINTS
> + bool "Boot constraints for devices"
> + help
> + This enables boot constraints detection for devices. These constraints
> + are (normally) set by the Bootloader and must be satisfied by the
> + kernel until the relevant device driver is probed. Once the driver is
> + probed, the constraint is dropped.
> +
> + If unsure, say N.
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> new file mode 100644
> index 000000000000..0f2680177974
> --- /dev/null
> +++ b/drivers/boot_constraints/Makefile
> @@ -0,0 +1,3 @@
> +# Makefile for device boot constraints
> +
> +obj-y := core.o
> diff --git a/drivers/boot_constraints/core.c b/drivers/boot_constraints/core.c
> new file mode 100644
> index 000000000000..366a05d6d9ba
> --- /dev/null
> +++ b/drivers/boot_constraints/core.c
> @@ -0,0 +1,199 @@
> +/*
> + * This takes care of boot time device constraints, normally set by the
> + * Bootloader.
> + *
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
Care to update this patch with the new SPDX format for licenses?
> + */
> +
> +#define pr_fmt(fmt) "Boot Constraints: " fmt
You don't have any pr_* calls, so this isn't needed :)
> +struct constraint {
> + struct constraint_dev *cdev;
> + struct list_head node;
> + enum dev_boot_constraint_type type;
> + void (*free_resources)(void *data);
> + void *free_resources_data;
> +
> + int (*add)(struct constraint *constraint, void *data);
> + void (*remove)(struct constraint *constraint);
> + void *private;
> +};
> +
> +/* Forward declarations of constraint specific callbacks */
> +#endif /* _CORE_H */
What is this comment at the end of the file for?
> diff --git a/include/linux/boot_constraint.h b/include/linux/boot_constraint.h
> new file mode 100644
> index 000000000000..2b816bf74144
> --- /dev/null
> +++ b/include/linux/boot_constraint.h
> @@ -0,0 +1,46 @@
> +/*
> + * Boot constraints header.
> + *
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2
> + */
> +#ifndef _LINUX_BOOT_CONSTRAINT_H
> +#define _LINUX_BOOT_CONSTRAINT_H
> +
> +#include <linux/err.h>
> +#include <linux/types.h>
> +
> +struct device;
> +
> +enum dev_boot_constraint_type {
> + DEV_BOOT_CONSTRAINT_NONE,
> +};
> +
> +struct dev_boot_constraint {
> + enum dev_boot_constraint_type type;
> + void *data;
> +};
> +
> +struct dev_boot_constraint_info {
> + struct dev_boot_constraint constraint;
> +
> + /* This will be called just before the constraint is removed */
> + void (*free_resources)(void *data);
> + void *free_resources_data;
> +};
> +
> +#ifdef CONFIG_DEV_BOOT_CONSTRAINTS
> +int dev_boot_constraint_add(struct device *dev,
> + struct dev_boot_constraint_info *info);
> +void dev_boot_constraints_remove(struct device *dev);
> +#else
> +static inline
> +int dev_boot_constraint_add(struct device *dev,
> + struct dev_boot_constraint_info *info)
> +{ return -EINVAL; }
Why return an error? Shouldn't this just "succeed" if the option is not
built in? What will you do with it if it fails because of this?
thanks,
greg k-h
^ permalink raw reply
* [PATCH V4 03/12] drivers: Add boot constraints core
From: Greg Kroah-Hartman @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2868a37e561cab91ba5495a1e14b9548c8e93c3e.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:51PM +0530, Viresh Kumar wrote:
> Some devices are powered ON by the bootloader before the bootloader
> handovers control to Linux. It maybe important for those devices to keep
> working until the time a Linux device driver probes the device and
> reconfigure its resources.
>
> A typical example of that can be the LCD controller, which is used by
> the bootloaders to show image(s) while the platform is booting into
> Linux. The LCD controller can be using some resources, like clk,
> regulators, PM domain, etc, that are shared between several devices.
> These shared resources should be configured to satisfy need of all the
> users. If another device's (X) driver gets probed before the LCD
> controller driver in this case, then it may end up reconfiguring these
> resources to ranges satisfying the current users (only device X) and
> that can make the LCD screen unstable.
>
> This patch introduces the concept of boot-constraints, which will be set
> by the bootloaders and the kernel will satisfy them until the time
> driver for such a device is probed (successfully or unsuccessfully).
>
> The list of boot constraint types is empty for now, and will be
> incrementally updated by later patches.
>
> Only two routines are exposed by the boot constraints core for now:
I think we need some documentation somewhere on how to use this, right?
thanks,
greg k-h
^ permalink raw reply
* [PATCH v2 3/4] thermal: armada: add support for CP110
From: Baruch Siach @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <874lovq9cx.fsf@free-electrons.com>
Hi Gregory,
On Wed, Dec 13, 2017 at 10:13:02AM +0100, Gregory CLEMENT wrote:
> On mer., d?c. 13 2017, Baruch Siach <baruch@tkos.co.il> wrote:
[...]
> > There are two separate issues here:
> >
> > 1. DT binding
> >
> > 2. init_sensor callback implementation
> >
> > We both agree on #1. The A38x and CP110 need separate compatible strings. In
> > case we want to access the LSB control register on Armada 38x, we will need
> > yet another compatible string (marvell,armada380-v2-thermal maybe?).
>
> Actually, if it is _compatible_ then we will use the same compatible, ie
> "marvell,armadacp110-thermal"
Reusing the same compatible string for the same hardware peripheral in
different SoCs is not a good idea. You often find out later that they are not
actually the same.
But this point is moot. The A38x and CP110 thermal sensors are not the same.
The overheat interrupt registers are in different offsets.
> > As for #2, I'm all for sharing as much code as possible. I find the vendor
> > kernel approach of duplicating the init routines[1] unhelpful as it violates
> > the DRY principle. The differences between armada380_init_sensor() and
> > cp110_init_sensor() are minor. In my opinion, these differences should be
> > expressed explicitly in the armada_thermal_data, in a similar way to my
> > suggested control_msb_offset field. The vendor code hides these differences in
> > slight variations of duplicated code.
> >
> > What is the advantage of a separate init routine?
>
> The main advantage is to be able keep the armada380_init_sensor as the
> legacy init, and then being able to use the new armadacp110_init_sensor
> for the new binding.
I disagree, sorry. I don't think I can make my point any more clear than I
did.
I am fine with you or Miquel making the code changes that you think are
necessary. I'll comment on the code when I see it.
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH] ARM: exynos_defconfig - enable CONFIG_EXYNOS_IOMMU
From: Marek Szyprowski @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171212213110.20893-1-shuahkh@osg.samsung.com>
Hi Shuah,
On 2017-12-12 22:31, Shuah Khan wrote:
> EXYNOS_IOMMU is disabled in exynos_defconfig since it is known to cause
> boot failures on Exynos Chrome-books. The recommendation is for IOMMU to
> be enabled manually on systems as needed.
>
> A recent exynos_drm change added a warning message when EXYNOS_IOMMU is
> disabled. It is necessary to enable it to avoid the warning messages.
> A few initial tests have shown that enabling EXYNOS_IOMMU might be safe
> on Exynos Chrome-books.
>
> Enable CONFIG_EXYNOS_IOMMU in exynos_defconfig.
>
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Due to some other changes in the order of operations during boot process,
power domains are initialized very early and because of the temporary
lack of devices (which are not yet added to the system), are turned off.
This practically stops FIMD for scanning framebuffer very early during
boot, before IOMMU gets initialized and "solves" the issue, which was
the reason to disable Exynos IOMMU by default.
Like I've already said, I've checked Exynos Snow Chromebook boots fine
with IOMMU support enabled, both with v4.15-rc3 and linux-next.
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> arch/arm/configs/exynos_defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
> index f1d7834..0ccd5eb 100644
> --- a/arch/arm/configs/exynos_defconfig
> +++ b/arch/arm/configs/exynos_defconfig
> @@ -281,6 +281,7 @@ CONFIG_DEVFREQ_GOV_POWERSAVE=y
> CONFIG_DEVFREQ_GOV_USERSPACE=y
> CONFIG_ARM_EXYNOS_BUS_DEVFREQ=y
> CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=y
> +CONFIG_EXYNOS_IOMMU=y
> CONFIG_EXTCON=y
> CONFIG_EXTCON_MAX14577=y
> CONFIG_EXTCON_MAX77693=y
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply
* [PATCH] arm64: mm: Fix false positives in set_pte_at access/dirty race detection
From: Yisheng Xie @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213092119.GB27222@arm.com>
Hi Will,
On 2017/12/13 17:21, Will Deacon wrote:
> Hi Yisheng,
>
> On Wed, Dec 13, 2017 at 09:01:23AM +0800, Yisheng Xie wrote:
>> On 2017/12/12 19:43, Will Deacon wrote:
>>> Jiankang reports that our race detection in set_pte_at is firing when
>>> copying the page tables in dup_mmap as a result of a fork(). In this
>>> situation, the page table isn't actually live and so there is no way
>>> that we can race with a concurrent update from the hardware page table
>>> walker.
>>>
>>> This patch reworks the race detection so that we require either the
>>> mm to match the current active_mm (i.e. currently installed in our TTBR0)
>>> or the mm_users count to be greater than 1, implying that the page table
>>> could be live in another CPU. The mm_users check might still be racy,
>>> but we'll avoid false positives and it's not realistic to validate that
>>> all the necessary locks are held as part of this assertion.
>>>
>>> Cc: Yisheng Xie <xieyisheng1@huawei.com>
>>> Reported-by: Jiankang Chen <chenjiankang1@huawei.com>
>>> Tested-by: Jiankang Chen <chenjiankang1@huawei.com>
>>> Signed-off-by: Will Deacon <will.deacon@arm.com>
>>> ---
>>> arch/arm64/include/asm/pgtable.h | 8 ++++----
>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>>> index 3ff03a755c32..bdcc7f1c9d06 100644
>>> --- a/arch/arm64/include/asm/pgtable.h
>>> +++ b/arch/arm64/include/asm/pgtable.h
>>> @@ -42,6 +42,8 @@
>>> #include <asm/cmpxchg.h>
>>> #include <asm/fixmap.h>
>>> #include <linux/mmdebug.h>
>>> +#include <linux/mm_types.h>
>>> +#include <linux/sched.h>
>>>
>>
>> Do you have compiled kernel after apply this patch? In our environment, it will
>> fail to compile kernel if include file here(I will attach some log later).
>> Instead, we move these included file after mmdebug.h, and I do not know whether
>> this is just my compiler's problem:
>
> It compiles fine for me. Are you seeing a problem building this on top of
> mainline? If so, what is your .config?
Oh, you have already moved it after #ifndef __ASSEMBLY__ , sorry for not finding
this when review this patch.
And I also have just compiled with this patch in mainline, is ok.
Thanks for your help.
Thanks
Yisheng Xie
>
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -42,6 +42,8 @@
>> #include <asm/cmpxchg.h>
>> #include <asm/fixmap.h>
>> #include <linux/mmdebug.h>
>> +#include <linux/mm_types.h>
>> +#include <linux/sched.h>
>>
>> Sorry for not having told you this information.
>>
>> Thanks
>> Yisheng Xie
>>
>> compiler err log: ==========
>> [...]
>> include/linux/mm_types_task.h:60: Error: unknown mnemonic `struct' -- `struct page_frag{'
>> include/asm-generic/preempt.h:9: Error: unknown mnemonic `static' -- `static inline int preempt_count(void)'
>> include/linux/mm_types_task.h:61: Error: unknown mnemonic `struct' -- `struct page*page'
>> include/asm-generic/preempt.h:10: Error: junk at end of line, first unrecognized character is `{'
>> include/linux/mm_types_task.h:63: Error: unknown mnemonic `__u32' -- `__u32 offset'
>> include/asm-generic/preempt.h:11: Error: unknown mnemonic `return' -- `return READ_ONCE(((struct thread_info*)current)->preempt_count)'
>> include/linux/mm_types_task.h:64: Error: unknown mnemonic `__u32' -- `__u32 size'
>> [...]
>
> This looks like the includes are being pulled into an assembly file, but
> this part is guarded by #ifndef __ASSEMBLY__ so I can't see how that could
> happen.
>
> Will
>
> .
>
^ permalink raw reply
* [PATCH 2/3] ARM: dts: r8a7743: Add CMT SoC specific support
From: Fabrizio Castro @ 2017-12-13 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213083829.ptdeggbon3szmko4@verge.net.au>
Hello Simon,
thank you for your feedback.
> On Tue, Dec 12, 2017 at 06:49:38PM +0000, Fabrizio Castro wrote:
> > Add CMT[01] support to SoC DT.
> >
> > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> > Reviewed-by: Biju Das <biju.das@bp.renesas.com>
> > ---
> > arch/arm/boot/dts/r8a7743.dtsi | 30 ++++++++++++++++++++++++++++++
> > 1 file changed, 30 insertions(+)
>
> I was expecting the cmt nodes to be "disabled" in the SoC file
> and then enabled selectively in board files. Am I missing something?
Since this component is just a compare and match timer, I thought there was no harm in enabling it by default in the SoC specific DT. The system will park it and leave its clock disabled until actually needed for something.
The user can still disable it in the board specific DT if he/she doesn't mean to even have the option to use it. Do you prefer I left it disabled by default?
Thanks,
Fab
>
> Otherwise this patch looks good to me.
>
> > diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
> > index 59860c8..0e2834a 100644
> > --- a/arch/arm/boot/dts/r8a7743.dtsi
> > +++ b/arch/arm/boot/dts/r8a7743.dtsi
> > @@ -262,6 +262,36 @@
> > IRQ_TYPE_LEVEL_LOW)>;
> > };
> >
> > +cmt0: timer at ffca0000 {
> > +compatible = "renesas,r8a7743-cmt0",
> > + "renesas,rcar-gen2-cmt0";
> > +reg = <0 0xffca0000 0 0x1004>;
> > +interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> > +clocks = <&cpg CPG_MOD 124>;
> > +clock-names = "fck";
> > +power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
> > +resets = <&cpg 124>;
> > +};
> > +
> > +cmt1: timer at e6130000 {
> > +compatible = "renesas,r8a7743-cmt1",
> > + "renesas,rcar-gen2-cmt1";
> > +reg = <0 0xe6130000 0 0x1004>;
> > +interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
> > +clocks = <&cpg CPG_MOD 329>;
> > +clock-names = "fck";
> > +power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
> > +resets = <&cpg 329>;
> > +};
> > +
> > cpg: clock-controller at e6150000 {
> > compatible = "renesas,r8a7743-cpg-mssr";
> > reg = <0 0xe6150000 0 0x1000>;
> > --
> > 2.7.4
> >
[https://www2.renesas.eu/media/email/unicef_2017.jpg]
This Christmas, instead of sending out cards, Renesas Electronics Europe have decided to support Unicef with a donation. For further details click here<https://www.unicef.org/> to find out about the valuable work they do, helping children all over the world.
We would like to take this opportunity to wish you a Merry Christmas and a prosperous New Year.
Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
^ permalink raw reply
* [PATCH V4 09/12] boot_constraint: Add earlycon helper
From: Greg Kroah-Hartman @ 2017-12-13 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f32e9a84a985e36cbff76df73faf0e3966d90ada.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:57PM +0530, Viresh Kumar wrote:
> Getting boot messages during initial kernel boot is a common problem,
> which (almost) everyone wants to solve. Considering that this would be
> required by multiple platforms, provide a helper to check if "earlycon"
> or "earlyprintk" boot arguments are passed to kernel or not. The
> platforms can use this helper to add serial constraints only if earlycon
> if required.
>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/boot_constraints/Makefile | 2 +-
> drivers/boot_constraints/serial.c | 28 ++++++++++++++++++++++++++++
> include/linux/boot_constraint.h | 2 ++
> 3 files changed, 31 insertions(+), 1 deletion(-)
> create mode 100644 drivers/boot_constraints/serial.c
>
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index a765094623a3..0d4f88bb767c 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,3 @@
> # Makefile for device boot constraints
>
> -obj-y := clk.o deferrable_dev.o core.o pm.o supply.o
> +obj-y := clk.o deferrable_dev.o core.o pm.o serial.o supply.o
> diff --git a/drivers/boot_constraints/serial.c b/drivers/boot_constraints/serial.c
> new file mode 100644
> index 000000000000..d0d07d4aa6af
> --- /dev/null
> +++ b/drivers/boot_constraints/serial.c
> @@ -0,0 +1,28 @@
> +/*
> + * This contains helpers related to serial boot constraints.
> + *
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#include <linux/init.h>
> +
> +static bool earlycon_boot_constraints_enabled __initdata;
> +
> +bool __init boot_constraint_earlycon_enabled(void)
> +{
> + return earlycon_boot_constraints_enabled;
> +}
> +
> +static int __init enable_earlycon_boot_constraints(char *str)
> +{
> + earlycon_boot_constraints_enabled = true;
> +
> + return 0;
> +}
> +__setup_param("earlycon", boot_constraint_earlycon,
> + enable_earlycon_boot_constraints, 0);
> +__setup_param("earlyprintk", boot_constraint_earlyprintk,
> + enable_earlycon_boot_constraints, 0);
> diff --git a/include/linux/boot_constraint.h b/include/linux/boot_constraint.h
> index c110b36e490f..aeada69b87e6 100644
> --- a/include/linux/boot_constraint.h
> +++ b/include/linux/boot_constraint.h
> @@ -10,6 +10,7 @@
> #define _LINUX_BOOT_CONSTRAINT_H
>
> #include <linux/err.h>
> +#include <linux/init.h>
> #include <linux/types.h>
>
> struct device;
> @@ -58,6 +59,7 @@ int dev_boot_constraint_add(struct device *dev,
> void dev_boot_constraints_remove(struct device *dev);
> void dev_boot_constraint_add_deferrable_of(struct dev_boot_constraint_of *oconst,
> int count);
> +bool __init boot_constraint_earlycon_enabled(void);
> #else
> static inline
> int dev_boot_constraint_add(struct device *dev,
No need for this function if it's not enabled?
And this feels really odd, does it really save any work for the
individual "constraint" to check for this option? I'm all for helper
functions, but this feels like more work than it's worth...
thanks,
greg k-h
^ permalink raw reply
* [PATCH V4 10/12] boot_constraint: Add support for Hisilicon platforms
From: Greg Kroah-Hartman @ 2017-12-13 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <facf1c5838468c8440240e2828a8e4982003a6f6.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:58PM +0530, Viresh Kumar wrote:
> This adds boot constraint support for Hisilicon platforms. Currently
> only one use case is supported: earlycon. One of the UART is enabled by
> the bootloader and is used for early console in the kernel. The boot
> constraint core handles it properly and removes constraints once the
> serial device is probed by its driver.
>
> This is tested on hi6220-hikey 96board.
>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> arch/arm64/Kconfig.platforms | 1 +
> drivers/boot_constraints/Makefile | 2 +
> drivers/boot_constraints/hikey.c | 145 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 148 insertions(+)
> create mode 100644 drivers/boot_constraints/hikey.c
>
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 6b54ee8c1262..265df4a088ab 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -87,6 +87,7 @@ config ARCH_HISI
> select ARM_TIMER_SP804
> select HISILICON_IRQ_MBIGEN if PCI
> select PINCTRL
> + select DEV_BOOT_CONSTRAINTS
> help
> This enables support for Hisilicon ARMv8 SoC family
>
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index 0d4f88bb767c..43c89d2458e9 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,5 @@
> # Makefile for device boot constraints
>
> obj-y := clk.o deferrable_dev.o core.o pm.o serial.o supply.o
> +
> +obj-$(CONFIG_ARCH_HISI) += hikey.o
> diff --git a/drivers/boot_constraints/hikey.c b/drivers/boot_constraints/hikey.c
> new file mode 100644
> index 000000000000..5f69f9451d93
> --- /dev/null
> +++ b/drivers/boot_constraints/hikey.c
> @@ -0,0 +1,145 @@
> +/*
> + * This takes care of Hisilicon boot time device constraints, normally set by
> + * the Bootloader.
> + *
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#include <linux/boot_constraint.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +
> +struct hikey_machine_constraints {
> + struct dev_boot_constraint_of *dev_constraints;
> + unsigned int count;
> +};
> +
> +static struct dev_boot_constraint_clk_info uart_iclk_info = {
> + .name = "uartclk",
> +};
> +
> +static struct dev_boot_constraint_clk_info uart_pclk_info = {
> + .name = "apb_pclk",
> +};
> +
> +static struct dev_boot_constraint hikey3660_uart_constraints[] = {
> + {
> + .type = DEV_BOOT_CONSTRAINT_CLK,
> + .data = &uart_iclk_info,
> + }, {
> + .type = DEV_BOOT_CONSTRAINT_CLK,
> + .data = &uart_pclk_info,
> + },
> +};
> +
> +static const char * const uarts_hikey3660[] = {
> + "serial at fff32000", /* UART 6 */
> +};
> +
> +static struct dev_boot_constraint_of hikey3660_dev_constraints[] = {
> + {
> + .compat = "arm,pl011",
> + .constraints = hikey3660_uart_constraints,
> + .count = ARRAY_SIZE(hikey3660_uart_constraints),
> +
> + .dev_names = uarts_hikey3660,
> + .dev_names_count = ARRAY_SIZE(uarts_hikey3660),
> + },
> +};
> +
> +static struct hikey_machine_constraints hikey3660_constraints = {
> + .dev_constraints = hikey3660_dev_constraints,
> + .count = ARRAY_SIZE(hikey3660_dev_constraints),
> +};
> +
> +static const char * const uarts_hikey6220[] = {
> + "uart at f7113000", /* UART 3 */
> +};
> +
> +static struct dev_boot_constraint_of hikey6220_dev_constraints[] = {
> + {
> + .compat = "arm,pl011",
> + .constraints = hikey3660_uart_constraints,
> + .count = ARRAY_SIZE(hikey3660_uart_constraints),
> +
> + .dev_names = uarts_hikey6220,
> + .dev_names_count = ARRAY_SIZE(uarts_hikey6220),
> + },
> +};
> +
> +static struct hikey_machine_constraints hikey6220_constraints = {
> + .dev_constraints = hikey6220_dev_constraints,
> + .count = ARRAY_SIZE(hikey6220_dev_constraints),
> +};
> +
> +static struct dev_boot_constraint hikey3798cv200_uart_constraints[] = {
> + {
> + .type = DEV_BOOT_CONSTRAINT_CLK,
> + .data = &uart_pclk_info,
> + },
> +};
> +
> +static const char * const uarts_hikey3798cv200[] = {
> + "serial at 8b00000", /* UART 0 */
> +};
> +
> +static struct dev_boot_constraint_of hikey3798cv200_dev_constraints[] = {
> + {
> + .compat = "arm,pl011",
> + .constraints = hikey3798cv200_uart_constraints,
> + .count = ARRAY_SIZE(hikey3798cv200_uart_constraints),
> +
> + .dev_names = uarts_hikey3798cv200,
> + .dev_names_count = ARRAY_SIZE(uarts_hikey3798cv200),
> + },
> +};
> +
> +static struct hikey_machine_constraints hikey3798cv200_constraints = {
> + .dev_constraints = hikey3798cv200_dev_constraints,
> + .count = ARRAY_SIZE(hikey3798cv200_dev_constraints),
> +};
> +
> +static const struct of_device_id machines[] __initconst = {
> + { .compatible = "hisilicon,hi3660", .data = &hikey3660_constraints },
> + { .compatible = "hisilicon,hi3798cv200", .data = &hikey3798cv200_constraints },
> + { .compatible = "hisilicon,hi6220", .data = &hikey6220_constraints },
> + { }
> +};
> +
> +static int __init hikey_constraints_init(void)
> +{
> + const struct hikey_machine_constraints *constraints;
> + const struct of_device_id *match;
> + struct device_node *np;
> +
> + if (!boot_constraint_earlycon_enabled())
> + return 0;
> +
> + np = of_find_node_by_path("/");
What is this for?
> + if (!np)
> + return -ENODEV;
> +
> + match = of_match_node(machines, np);
> + of_node_put(np);
> +
> + if (!match)
> + return 0;
> +
> + constraints = match->data;
> + BUG_ON(!constraints);
Never crash the device for a driver configuration issue. That's going
to be bad.
> + dev_boot_constraint_add_deferrable_of(constraints->dev_constraints,
> + constraints->count);
> +
> + return 0;
> +}
> +
> +/*
> + * The amba-pl011 driver registers itself from arch_initcall level. Setup the
> + * serial boot constraints before that in order not to miss any boot messages.
> + */
> +postcore_initcall_sync(hikey_constraints_init);
Now you have to worry about the bootconstraints earlycon being called
before/after your code. That's another linking order dependancy you
just created. It feels more complex for something so "simple" as
looking for the earlycon flag...
thanks,
greg k-h
^ permalink raw reply
* [PATCH V4 06/12] boot_constraint: Add support for PM constraints
From: Greg Kroah-Hartman @ 2017-12-13 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <000268f9c5b06354333a18dbe26fc8b052231ed8.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:54PM +0530, Viresh Kumar wrote:
> This patch adds the PM constraint type.
>
> The constraint is set by attaching the power domain for the device,
> which will also enable the power domain. This guarantees that the power
> domain doesn't get shut down while being used.
>
> We don't need to detach the power domain to remove the constraint as the
> domain is attached only once, from here or before driver probe.
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/boot_constraints/Makefile | 2 +-
> drivers/boot_constraints/core.c | 4 ++++
> drivers/boot_constraints/core.h | 3 +++
> drivers/boot_constraints/pm.c | 24 ++++++++++++++++++++++++
> include/linux/boot_constraint.h | 1 +
> 5 files changed, 33 insertions(+), 1 deletion(-)
> create mode 100644 drivers/boot_constraints/pm.c
>
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index 3424379fd1e4..b7ade1a7afb5 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,3 @@
> # Makefile for device boot constraints
>
> -obj-y := clk.o core.o supply.o
> +obj-y := clk.o core.o pm.o supply.o
> diff --git a/drivers/boot_constraints/core.c b/drivers/boot_constraints/core.c
> index 9213e56e8078..f4d3520ddb04 100644
> --- a/drivers/boot_constraints/core.c
> +++ b/drivers/boot_constraints/core.c
> @@ -98,6 +98,10 @@ static struct constraint *constraint_allocate(struct constraint_dev *cdev,
> add = constraint_clk_add;
> remove = constraint_clk_remove;
> break;
> + case DEV_BOOT_CONSTRAINT_PM:
> + add = constraint_pm_add;
> + remove = constraint_pm_remove;
> + break;
> case DEV_BOOT_CONSTRAINT_SUPPLY:
> add = constraint_supply_add;
> remove = constraint_supply_remove;
> diff --git a/drivers/boot_constraints/core.h b/drivers/boot_constraints/core.h
> index 4f28ac2ef691..a051c3d7c8ab 100644
> --- a/drivers/boot_constraints/core.h
> +++ b/drivers/boot_constraints/core.h
> @@ -33,6 +33,9 @@ struct constraint {
> int constraint_clk_add(struct constraint *constraint, void *data);
> void constraint_clk_remove(struct constraint *constraint);
>
> +int constraint_pm_add(struct constraint *constraint, void *data);
> +void constraint_pm_remove(struct constraint *constraint);
> +
> int constraint_supply_add(struct constraint *constraint, void *data);
> void constraint_supply_remove(struct constraint *constraint);
>
> diff --git a/drivers/boot_constraints/pm.c b/drivers/boot_constraints/pm.c
> new file mode 100644
> index 000000000000..edba5eca5093
> --- /dev/null
> +++ b/drivers/boot_constraints/pm.c
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#define pr_fmt(fmt) "PM Boot Constraints: " fmt
You don't use this :(
^ permalink raw reply
* [PATCH V4 05/12] boot_constraint: Add support for clk constraints
From: Greg Kroah-Hartman @ 2017-12-13 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fb9fb79a1486bc2ed62cfb2257db44b1498ad66e.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:53PM +0530, Viresh Kumar wrote:
> This patch adds the clk constraint type.
>
> The constraint is set by enabling the clk for the device. Once the
> device is probed, the clk is disabled and the constraint is removed.
>
> We may want to do clk_set_rate() from here, but lets wait for some real
> users that really want it.
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/boot_constraints/Makefile | 2 +-
> drivers/boot_constraints/clk.c | 70 +++++++++++++++++++++++++++++++++++++++
> drivers/boot_constraints/core.c | 4 +++
> drivers/boot_constraints/core.h | 3 ++
> include/linux/boot_constraint.h | 5 +++
> 5 files changed, 83 insertions(+), 1 deletion(-)
> create mode 100644 drivers/boot_constraints/clk.c
>
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index a45616f0c3b0..3424379fd1e4 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,3 @@
> # Makefile for device boot constraints
>
> -obj-y := core.o supply.o
> +obj-y := clk.o core.o supply.o
> diff --git a/drivers/boot_constraints/clk.c b/drivers/boot_constraints/clk.c
> new file mode 100644
> index 000000000000..b5b1d63c3e76
> --- /dev/null
> +++ b/drivers/boot_constraints/clk.c
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#define pr_fmt(fmt) "Clock Boot Constraints: " fmt
You don't use this :(
^ permalink raw reply
* [PATCH V4 04/12] boot_constraint: Add support for supply constraints
From: Greg Kroah-Hartman @ 2017-12-13 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4e171b6a496a6f5645804d9ed9cb53b4bcbe75a0.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:52PM +0530, Viresh Kumar wrote:
> This patch adds the first constraint type: power-supply.
>
> The constraint is set by enabling the regulator and setting a voltage
> range (if required) for the respective regulator device, which will be
> honored by the regulator core even if more users turn up. Once the
> device is probed, the regulator is released and the constraint is
> removed.
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/boot_constraints/Makefile | 2 +-
> drivers/boot_constraints/core.c | 4 ++
> drivers/boot_constraints/core.h | 3 ++
> drivers/boot_constraints/supply.c | 98 +++++++++++++++++++++++++++++++++++++++
> include/linux/boot_constraint.h | 8 +++-
> 5 files changed, 113 insertions(+), 2 deletions(-)
> create mode 100644 drivers/boot_constraints/supply.c
>
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index 0f2680177974..a45616f0c3b0 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,3 @@
> # Makefile for device boot constraints
>
> -obj-y := core.o
> +obj-y := core.o supply.o
> diff --git a/drivers/boot_constraints/core.c b/drivers/boot_constraints/core.c
> index 366a05d6d9ba..b9c024a3bdf5 100644
> --- a/drivers/boot_constraints/core.c
> +++ b/drivers/boot_constraints/core.c
> @@ -94,6 +94,10 @@ static struct constraint *constraint_allocate(struct constraint_dev *cdev,
> void (*remove)(struct constraint *constraint);
>
> switch (type) {
> + case DEV_BOOT_CONSTRAINT_SUPPLY:
> + add = constraint_supply_add;
> + remove = constraint_supply_remove;
> + break;
> default:
> return ERR_PTR(-EINVAL);
> }
> diff --git a/drivers/boot_constraints/core.h b/drivers/boot_constraints/core.h
> index 7ba4ac172c09..73b9d2d22a12 100644
> --- a/drivers/boot_constraints/core.h
> +++ b/drivers/boot_constraints/core.h
> @@ -30,4 +30,7 @@ struct constraint {
> };
>
> /* Forward declarations of constraint specific callbacks */
> +int constraint_supply_add(struct constraint *constraint, void *data);
> +void constraint_supply_remove(struct constraint *constraint);
> +
> #endif /* _CORE_H */
> diff --git a/drivers/boot_constraints/supply.c b/drivers/boot_constraints/supply.c
> new file mode 100644
> index 000000000000..30f816dbf12c
> --- /dev/null
> +++ b/drivers/boot_constraints/supply.c
> @@ -0,0 +1,98 @@
> +/*
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#define pr_fmt(fmt) "Supply Boot Constraints: " fmt
And again :)
^ permalink raw reply
* [PATCH V4 07/12] boot_constraint: Add debugfs support
From: Greg Kroah-Hartman @ 2017-12-13 9:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a796de9a338d7d0876faa3ec99f5cb49315c893c.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:55PM +0530, Viresh Kumar wrote:
> This patch adds debugfs support for boot constraints. This is how it
> looks for a "vmmc-supply" constraint for the MMC device.
>
> $ ls -R /sys/kernel/debug/boot_constraints/
> /sys/kernel/debug/boot_constraints/:
> f723d000.dwmmc0
>
> /sys/kernel/debug/boot_constraints/f723d000.dwmmc0:
> clk-ciu pm-domain supply-vmmc supply-vmmcaux
>
> /sys/kernel/debug/boot_constraints/f723d000.dwmmc0/clk-ciu:
>
> /sys/kernel/debug/boot_constraints/f723d000.dwmmc0/pm-domain:
>
> /sys/kernel/debug/boot_constraints/f723d000.dwmmc0/supply-vmmc:
> u_volt_max u_volt_min
>
> /sys/kernel/debug/boot_constraints/f723d000.dwmmc0/supply-vmmcaux:
> u_volt_max u_volt_min
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/boot_constraints/clk.c | 3 ++
> drivers/boot_constraints/core.c | 60 +++++++++++++++++++++++++++++++++++++++
> drivers/boot_constraints/core.h | 6 ++++
> drivers/boot_constraints/pm.c | 11 +++++--
> drivers/boot_constraints/supply.c | 9 ++++++
> 5 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/boot_constraints/clk.c b/drivers/boot_constraints/clk.c
> index b5b1d63c3e76..91b7b538ef32 100644
> --- a/drivers/boot_constraints/clk.c
> +++ b/drivers/boot_constraints/clk.c
> @@ -49,6 +49,8 @@ int constraint_clk_add(struct constraint *constraint, void *data)
> cclk->clk_info.name = kstrdup_const(clk_info->name, GFP_KERNEL);
> constraint->private = cclk;
>
> + constraint_add_debugfs(constraint, clk_info->name);
> +
> return 0;
>
> put_clk:
> @@ -63,6 +65,7 @@ void constraint_clk_remove(struct constraint *constraint)
> {
> struct constraint_clk *cclk = constraint->private;
>
> + constraint_remove_debugfs(constraint);
> kfree_const(cclk->clk_info.name);
> clk_disable_unprepare(cclk->clk);
> clk_put(cclk->clk);
> diff --git a/drivers/boot_constraints/core.c b/drivers/boot_constraints/core.c
> index f4d3520ddb04..707ffac690fc 100644
> --- a/drivers/boot_constraints/core.c
> +++ b/drivers/boot_constraints/core.c
> @@ -24,6 +24,64 @@
> static LIST_HEAD(constraint_devices);
> static DEFINE_MUTEX(constraint_devices_mutex);
>
> +/* Debugfs */
> +
> +static struct dentry *rootdir;
> +
> +static void constraint_device_add_debugfs(struct constraint_dev *cdev)
> +{
> + struct device *dev = cdev->dev;
> +
> + cdev->dentry = debugfs_create_dir(dev_name(dev), rootdir);
> +}
> +
> +static void constraint_device_remove_debugfs(struct constraint_dev *cdev)
> +{
> + debugfs_remove_recursive(cdev->dentry);
> +}
> +
> +void constraint_add_debugfs(struct constraint *constraint, const char *suffix)
> +{
> + struct device *dev = constraint->cdev->dev;
> + const char *prefix;
> + char name[NAME_MAX];
> +
> + switch (constraint->type) {
> + case DEV_BOOT_CONSTRAINT_CLK:
> + prefix = "clk";
> + break;
> + case DEV_BOOT_CONSTRAINT_PM:
> + prefix = "pm";
> + break;
> + case DEV_BOOT_CONSTRAINT_SUPPLY:
> + prefix = "supply";
> + break;
> + default:
> + dev_err(dev, "%s: Constraint type (%d) not supported\n",
> + __func__, constraint->type);
> + return;
> + }
> +
> + snprintf(name, NAME_MAX, "%s-%s", prefix, suffix);
> +
> + constraint->dentry = debugfs_create_dir(name, constraint->cdev->dentry);
> +}
> +
> +void constraint_remove_debugfs(struct constraint *constraint)
> +{
> + debugfs_remove_recursive(constraint->dentry);
> +}
> +
> +static int __init constraint_debugfs_init(void)
> +{
> + /* Create /sys/kernel/debug/opp directory */
> + rootdir = debugfs_create_dir("boot_constraints", NULL);
Your comment makes no sense at all, it would be better, and correct, to
have no comment at all :)
^ permalink raw reply
* [PATCH V4 08/12] boot_constraint: Manage deferrable constraints
From: Greg Kroah-Hartman @ 2017-12-13 9:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <88c7a0a6421d267c118f501ea1e920b04649002d.1509284255.git.viresh.kumar@linaro.org>
On Sun, Oct 29, 2017 at 07:18:56PM +0530, Viresh Kumar wrote:
> It is possible that some of the resources aren't available at the time
> constraints are getting set and the boot constraints core will return
> -EPROBE_DEFER for them. In order to retry adding the constraints at a
> later point of time (after the resource is added and before any of its
> users come up), this patch proposes two things:
>
> - Each constraint is represented by a virtual platform device, so that
> it is re-probed again until the time all the dependencies aren't met.
> The platform device is removed along with the constraint, with help of
> the free_resources() callback.
>
> - Enable early defer probing support by calling
> driver_enable_deferred_probe(), so that the core retries probing
> deferred devices every time any device is bound to a driver. This
> makes sure that the constraint is set before any of the users of the
> resources come up.
>
> This is tested on ARM64 Hikey board where probe was deferred for a
> device.
>
> Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> drivers/base/dd.c | 12 ++
> drivers/boot_constraints/Makefile | 2 +-
> drivers/boot_constraints/deferrable_dev.c | 235 ++++++++++++++++++++++++++++++
> include/linux/boot_constraint.h | 14 ++
> 4 files changed, 262 insertions(+), 1 deletion(-)
> create mode 100644 drivers/boot_constraints/deferrable_dev.c
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 4eec27fe2b2b..19eff5d08b9a 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -228,6 +228,18 @@ void device_unblock_probing(void)
> driver_deferred_probe_trigger();
> }
>
> +/**
> + * driver_enable_deferred_probe() - Enable probing of deferred devices
> + *
> + * We don't want to get in the way when the bulk of drivers are getting probed
> + * and so deferred probe is disabled in the beginning. Enable it now because we
> + * need it.
> + */
> +void driver_enable_deferred_probe(void)
> +{
> + driver_deferred_probe_enable = true;
> +}
> +
> /**
> * deferred_probe_initcall() - Enable probing of deferred devices
> *
> diff --git a/drivers/boot_constraints/Makefile b/drivers/boot_constraints/Makefile
> index b7ade1a7afb5..a765094623a3 100644
> --- a/drivers/boot_constraints/Makefile
> +++ b/drivers/boot_constraints/Makefile
> @@ -1,3 +1,3 @@
> # Makefile for device boot constraints
>
> -obj-y := clk.o core.o pm.o supply.o
> +obj-y := clk.o deferrable_dev.o core.o pm.o supply.o
> diff --git a/drivers/boot_constraints/deferrable_dev.c b/drivers/boot_constraints/deferrable_dev.c
> new file mode 100644
> index 000000000000..04056f317aff
> --- /dev/null
> +++ b/drivers/boot_constraints/deferrable_dev.c
> @@ -0,0 +1,235 @@
> +/*
> + * Copyright (C) 2017 Linaro.
> + * Viresh Kumar <viresh.kumar@linaro.org>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#define pr_fmt(fmt) "Boot Constraints: " fmt
Hey, you use this one!
But you shouldn't :)
> +/* This only creates platform devices for now */
> +static void add_deferrable_of_single(struct device_node *np,
> + struct dev_boot_constraint *constraints,
> + int count)
> +{
> + struct device *dev;
> + int ret;
> +
> + if (!of_device_is_available(np))
> + return;
> +
> + ret = of_platform_bus_create(np, NULL, NULL, NULL, false);
> + if (ret)
> + return;
> +
> + if (of_device_is_compatible(np, "arm,primecell")) {
Why is "arm,primecell" in the core code here?
> + struct amba_device *adev = of_find_amba_device_by_node(np);
> +
> + if (!adev) {
> + pr_err("Failed to find amba dev: %s\n", np->full_name);
Never use pr_* when you have a valid struct device to use. Don't you
have one from the struct device_node * passed in here?
> + return;
> + }
> + dev = &adev->dev;
> + } else {
> + struct platform_device *pdev = of_find_device_by_node(np);
> +
> + if (!pdev) {
> + pr_err("Failed to find pdev: %s\n", np->full_name);
Same here.
thanks,
greg k-h
^ permalink raw reply
* [PATCH V4 00/12] drivers: Boot Constraints core
From: Greg Kroah-Hartman @ 2017-12-13 9:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171128041818.GE11413@vireshk-i7>
On Tue, Nov 28, 2017 at 09:48:18AM +0530, Viresh Kumar wrote:
> On 29-10-17, 19:18, Viresh Kumar wrote:
> > Here is V4 of the boot constraints core based on your feedback from V3.
> > We now have support for three platforms (as you suggested) included in
> > this series: Hisilicon, IMX and Qualcomm.
>
> Hi Greg,
>
> I was waiting for rc1 to come out before sending a reminder for this
> series and so here is one :)
I've reviewed it enough for now, needs a tiny bit of work, but looking
much better, nice job!
gre gk-h
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox