Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH V7 1/4] Documentation/devicetree/bindings: b850v3_lvds_dp
From: Laurent Pinchart @ 2017-01-10 21:04 UTC (permalink / raw)
  To: dri-devel
  Cc: Peter Senna Tschudin, Rob Herring, Mark Rutland, Daniel Vetter,
	Peter Senna Tschudin, Takashi Iwai, Yakir Yang, Jiri Slaby,
	Martyn Welch, Ian Campbell, Russell King, Peter Senna Tschudin,
	Javier Martinez Canillas, Thierry Reding, Guenter Roeck,
	martin.donnelly, devicetree@vger.kernel.org, Pawel Moll,
	Mauro Carvalho Chehab
In-Reply-To: <74f0-58704480-5-27259840@173563636>

Hi Peter,

On Saturday 07 Jan 2017 01:29:52 Peter Senna Tschudin wrote:
> On 04 January, 2017 21:39 CET, Rob Herring wrote:
> > On Tue, Jan 3, 2017 at 5:34 PM, Peter Senna Tschudin wrote:
> >> On 03 January, 2017 23:51 CET, Rob Herring <robh@kernel.org> wrote:
> >>> On Sun, Jan 01, 2017 at 09:24:29PM +0100, Peter Senna Tschudin wrote:
> >>>> Devicetree bindings documentation for the GE B850v3 LVDS/DP++
> >>>> display bridge.
> >>>> 
> >>>> Cc: Martyn Welch <martyn.welch@collabora.co.uk>
> >>>> Cc: Martin Donnelly <martin.donnelly@ge.com>
> >>>> Cc: Javier Martinez Canillas <javier@dowhile0.org>
> >>>> Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> >>>> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> >>>> Cc: Rob Herring <robh@kernel.org>
> >>>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> >>>> Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
> >>>> ---
> >>>> There was an Acked-by from Rob Herring <robh@kernel.org> for V6, but
> >>>> I changed the bindings to use i2c_new_secondary_device() so I
> >>>> removed it from the commit message.
> >>>> 
> >>>>  .../devicetree/bindings/ge/b850v3-lvds-dp.txt      | 39 ++++++++++++++
> >>> Generally, bindings are not organized by vendor. Put in
> >>> bindings/display/bridge/... instead.
> >> 
> >> Will change that.
> >> 
> >>>>  1 file changed, 39 insertions(+)
> >>>>  create mode 100644
> >>>>  Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> >>>> 
> >>>> diff --git a/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> >>>> b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt new file
> >>>> mode 100644
> >>>> index 0000000..1bc6ebf
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> >>>> @@ -0,0 +1,39 @@
> >>>> +Driver for GE B850v3 LVDS/DP++ display bridge
> >>>> +
> >>>> +Required properties:
> >>>> +  - compatible : should be "ge,b850v3-lvds-dp".
> >>> 
> >>> Isn't '-lvds-dp' redundant? The part# should be enough.
> >> 
> >> b850v3 is the name of the product, this is why the proposed name. What
> >> about, b850v3-dp2 dp2 indicating the second DP output?
> >
> > Humm, b850v3 is the board name? This node should be the name of the bridge
> > chip.
>
> From the cover letter:
> 
> -- // --
> There are two physical bridges on the video signal pipeline: a STDP4028(LVDS
> to DP) and a STDP2690(DP to DP++).  The hardware and firmware made it
> complicated for this binding to comprise two device tree nodes, as the
> design goal is to configure both bridges based on the LVDS signal, which
> leave the driver powerless to control the video processing pipeline. The
> two bridges behaves as a single bridge, and the driver is only needed for
> telling the host about EDID / HPD, and for giving the host powers to ack
> interrupts. The video signal pipeline is as follows:
> 
>   Host -> LVDS|--(STDP4028)--|DP -> DP|--(STDP2690)--|DP++ -> Video output
> -- // --

You forgot to prefix your patch series with [HACK] ;-)

How about fixing the issues that make the two DT nodes solution difficult ? 
What are they ?

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH V7 1/4] Documentation/devicetree/bindings: b850v3_lvds_dp
From: Laurent Pinchart @ 2017-01-10 21:06 UTC (permalink / raw)
  To: dri-devel
  Cc: Peter Senna Tschudin, airlied, architt, akpm, daniel.vetter,
	davem, devicetree, enric.balletbo, eballetbo, galak, gregkh,
	heiko, ijc+devicetree, javier, jslaby, kernel, linux-arm-kernel,
	linux, linux-kernel, linux, mark.rutland, martin.donnelly,
	martyn.welch, mchehab, pawel.moll, peter.senna, p.zabel,
	thierry.reding, rmk+kernel, robh+dt, shawnguo, tiwai
In-Reply-To: <21ea1b0795bdaa30ca475d6ce675b620b2b644ed.1483301745.git.peter.senna@collabora.com>

Hi Peter,

Thank you for the patch.

On Sunday 01 Jan 2017 21:24:29 Peter Senna Tschudin wrote:
> Devicetree bindings documentation for the GE B850v3 LVDS/DP++
> display bridge.
> 
> Cc: Martyn Welch <martyn.welch@collabora.co.uk>
> Cc: Martin Donnelly <martin.donnelly@ge.com>
> Cc: Javier Martinez Canillas <javier@dowhile0.org>
> Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
> ---
> There was an Acked-by from Rob Herring <robh@kernel.org> for V6, but I
> changed the bindings to use i2c_new_secondary_device() so I removed it from
> the commit message.
> 
>  .../devicetree/bindings/ge/b850v3-lvds-dp.txt      | 39 +++++++++++++++++++
>  1 file changed, 39 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> 
> diff --git a/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt new file mode
> 100644
> index 0000000..1bc6ebf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
> @@ -0,0 +1,39 @@
> +Driver for GE B850v3 LVDS/DP++ display bridge
> +
> +Required properties:
> +  - compatible : should be "ge,b850v3-lvds-dp".
> +  - reg : should contain the main address which is used to ack the
> +    interrupts and address for edid.
> +  - reg-names : comma separeted list of register names. Valid values
> +    are "main", and "edid".
> +  - interrupt-parent : phandle of the interrupt controller that services
> +    interrupts to the device
> +  - interrupts : one interrupt should be described here, as in
> +    <0 IRQ_TYPE_LEVEL_HIGH>.
> +  - port : should describe the video signal connection between the host
> +    and the bridge.

A bridge has, by definition, (at least) one input and (at least) one output. 
You should thus have (at least) two ports.

> +Example:
> +
> +&mux2_i2c2 {
> +	status = "okay";
> +	clock-frequency = <100000>;
> +
> +	b850v3-lvds-dp-bridge@73  {
> +		compatible = "ge,b850v3-lvds-dp";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		reg = <0x73 0x72>;
> +		reg-names = "main", "edid";
> +
> +		interrupt-parent = <&gpio2>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +
> +		port {
> +			b850v3_dp_bridge_in: endpoint {
> +				remote-endpoint = <&lvds0_out>;
> +			};
> +		};
> +	};
> +};

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 1/1] iio: adc: tlc4541: add support for TI tlc4541 adc
From: Jonathan Cameron @ 2017-01-10 21:17 UTC (permalink / raw)
  To: Phil Reid, Peter Meerwald-Stadler
  Cc: lars-Qo5EllUWu/uELgA04lAiVw, linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <d2b5f8fe-f9ce-bf9b-b5d8-facc10936290-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>

On 10/01/17 06:26, Phil Reid wrote:
> G'day Peter,
> 
> Thanks for the review.
> 
> On 5/01/2017 17:21, Peter Meerwald-Stadler wrote:
> <snip>
>>> +
>>> +#define TLC4541_V_CHAN(index, bits) {                                 \
>>> +        .type = IIO_VOLTAGE,                                  \
>>> +        .indexed = 1,                                         \
>>
>> no need if there is just one channel
>>
>>> +        .channel = index,                                     \
>>> +        .info_mask_separate       = BIT(IIO_CHAN_INFO_RAW),   \
>>> +        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
>>> +        .address = index,                                     \
>>
>> .address not needed
>>
>>> +        .scan_index = index,                                  \
>>> +        .scan_type = {                                        \
>>> +            .sign = 'u',                                  \
>>> +            .realbits = (bits),                           \
>>> +            .storagebits = 16,                            \
>>> +            .endianness = IIO_BE,                         \
>>> +        },                                                    \
>>> +    }
>>> +
>>> +#define DECLARE_TLC4541_CHANNELS(name, bits) \
>>
>> this flexibility is only needed when further chips are added; maybe start
>> simple and only implement what is needed at first
> I'll add the spec for to the TLC3541 which is a 14-bit version of this chip.
> I don't have one to test, but it looks pretty straight forward.
> 
>>
>>> +const struct iio_chan_spec name ## _channels[] = { \
>>> +    TLC4541_V_CHAN(0, bits), \
>>> +    IIO_CHAN_SOFT_TIMESTAMP(1), \
>>> +}
>>> +
>>> +static DECLARE_TLC4541_CHANNELS(tlc4541, 16);
>>> +
>>> +static const struct tlc4541_chip_info tlc4541_chip_info[] = {
>>> +    [TLC4541] = {
>>> +        .channels = tlc4541_channels,
>>> +        .num_channels = ARRAY_SIZE(tlc4541_channels),
>>> +    },
>>> +};
>>> +
>>> +static irqreturn_t tlc4541_trigger_handler(int irq, void *p)
>>> +{
>>> +    struct iio_poll_func *pf = p;
>>> +    struct iio_dev *indio_dev = pf->indio_dev;
>>> +    struct tlc4541_state *st = iio_priv(indio_dev);
>>> +    u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
>>> +    int ret;
>>> +
>>> +    ret = spi_sync(st->spi, &st->scan_single_msg);
>>> +    if (ret < 0)
>>> +        goto done;
>>> +
>>> +    buf[0] = be16_to_cpu(st->rx_buf[0]);
>>
>> endianness is set to IIO_BE in scan_type, so this conversion is not needed
>> and maybe also buf and the copy can be avoided if rx_buf is large enough
> 
> I was doing the conversion in IIO_CHAN_INFO_RAW as well.
> Is it required there? I'm guessing yes.
Yes. That path is outputting a human readable string so needs to be the write
way around.
> 
>>
>>> +    iio_push_to_buffers_with_timestamp(indio_dev, buf,
>>> +                       iio_get_time_ns(indio_dev));
>>> +
>>> +done:
>>> +    iio_trigger_notify_done(indio_dev->trig);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int tlc4541_get_range(struct tlc4541_state *st)
>>> +{
>>> +    int vref;
>>> +
>>> +    vref = regulator_get_voltage(st->reg);
>>> +    if (vref < 0)
>>> +        return vref;
>>> +
>>> +    vref /= 1000;
>>> +
>>> +    return vref;
>>> +}
>>> +
>>> +static int tlc4541_read_raw(struct iio_dev *indio_dev,
>>> +                struct iio_chan_spec const *chan,
>>> +                int *val,
>>> +                int *val2,
>>> +                long m)
>>> +{
>>> +    int ret = 0;
>>> +    struct tlc4541_state *st = iio_priv(indio_dev);
>>> +
>>> +    switch (m) {
>>> +    case IIO_CHAN_INFO_RAW:
>>> +        ret = iio_device_claim_direct_mode(indio_dev);
>>> +        if (ret)
>>> +            return ret;
>>> +        ret = spi_sync(st->spi, &st->scan_single_msg);
>>> +        iio_device_release_direct_mode(indio_dev);
>>> +        if (ret < 0)
>>> +            return ret;
>>> +        *val = be16_to_cpu(st->rx_buf[0]);
>>
>> on page 12 of the datasheet, the conversion results is in two registers?
>> and rx_buf has two elements?
>>
>> haven't investigated in detail -- maybe a comment would be good to detail
>> operation?
> I set that to 4 bytes because I also use that for the dummy 24 clock cycles
> at the beginning as well. I think that documentation is a bit misleading.
> Possible due to the tlc3451 datasheet being  very similar. Those two registers
> are 14 bits and 2 bits wide respectively. The SPI cycle time shows data is
> available in the first 16 bits.
> 
> 
>>
>>> +        return IIO_VAL_INT;
>>> +    case IIO_CHAN_INFO_SCALE:
>>> +        ret = tlc4541_get_range(st);
>>> +        if (ret < 0)
>>> +            return ret;
>>> +        *val = ret;
>>> +        *val2 = chan->scan_type.realbits;
>>> +        return IIO_VAL_FRACTIONAL_LOG2;
>>> +    }
>>> +    return -EINVAL;
>>> +}
> <snip>
> 
> 

^ permalink raw reply

* Re: [PATCH v7 05/12] mux: support simplified bindings for single-user gpio mux
From: Jonathan Cameron @ 2017-01-10 21:22 UTC (permalink / raw)
  To: Peter Rosin, linux-kernel
  Cc: Wolfram Sang, Rob Herring, Mark Rutland, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Jonathan Corbet,
	Arnd Bergmann, Greg Kroah-Hartman, linux-i2c, devicetree,
	linux-iio, linux-doc
In-Reply-To: <60cd24a4-dd13-c5e8-c06d-bbd12a8e7e21@axentia.se>

On 08/01/17 21:56, Peter Rosin wrote:
> On 2017-01-08 11:28, Jonathan Cameron wrote:
>> On 05/01/17 16:21, Peter Rosin wrote:
>>> On 2017-01-04 13:16, Peter Rosin wrote:
>>>> Signed-off-by: Peter Rosin <peda@axentia.se>
>>>> ---
>>>>  drivers/mux/mux-core.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++--
>>>>  drivers/mux/mux-gpio.c | 56 ++--------------------------------
>>>>  include/linux/mux.h    |  7 +++++
>>>>  3 files changed, 89 insertions(+), 55 deletions(-)
>>>>
>>>> diff --git a/drivers/mux/mux-core.c b/drivers/mux/mux-core.c
>>>> index 21da15a264ad..d887ae1c0e55 100644
>>>> --- a/drivers/mux/mux-core.c
>>>> +++ b/drivers/mux/mux-core.c
>>>> @@ -15,6 +15,7 @@
>>>>  #include <linux/device.h>
>>>>  #include <linux/err.h>
>>>>  #include <linux/idr.h>
>>>> +#include <linux/gpio/consumer.h>
>>>>  #include <linux/module.h>
>>>>  #include <linux/mux.h>
>>>>  #include <linux/of.h>
>>>> @@ -288,6 +289,63 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
>>>>  	return dev ? to_mux_chip(dev) : NULL;
>>>>  }
>>>>  
>>>> +#ifdef CONFIG_MUX_GPIO
>>>> +
>>>> +static int mux_gpio_set(struct mux_control *mux, int state)
>>>> +{
>>>> +	struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip);
>>>> +	int i;
>>>> +
>>>> +	for (i = 0; i < mux_gpio->gpios->ndescs; i++)
>>>> +		mux_gpio->val[i] = (state >> i) & 1;
>>>> +
>>>> +	gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,
>>>> +				       mux_gpio->gpios->desc,
>>>> +				       mux_gpio->val);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static const struct mux_control_ops mux_gpio_ops = {
>>>> +	.set = mux_gpio_set,
>>>> +};
>>>> +
>>>> +struct mux_chip *mux_gpio_alloc(struct device *dev)
>>>> +{
>>>> +	struct mux_chip *mux_chip;
>>>> +	struct mux_gpio *mux_gpio;
>>>> +	int pins;
>>>> +	int ret;
>>>> +
>>>> +	pins = gpiod_count(dev, "mux");
>>>> +	if (pins < 0)
>>>> +		return ERR_PTR(pins);
>>>> +
>>>> +	mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio) +
>>>> +				       pins * sizeof(*mux_gpio->val));
>>>> +	if (!mux_chip)
>>>> +		return ERR_PTR(-ENOMEM);
>>>> +
>>>> +	mux_gpio = mux_chip_priv(mux_chip);
>>>> +	mux_gpio->val = (int *)(mux_gpio + 1);
>>>> +	mux_chip->ops = &mux_gpio_ops;
>>>> +
>>>> +	mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW);
>>>> +	if (IS_ERR(mux_gpio->gpios)) {
>>>> +		ret = PTR_ERR(mux_gpio->gpios);
>>>> +		if (ret != -EPROBE_DEFER)
>>>> +			dev_err(dev, "failed to get gpios\n");
>>>> +		return ERR_PTR(ret);
>>>> +	}
>>>> +	WARN_ON(pins != mux_gpio->gpios->ndescs);
>>>> +	mux_chip->mux->states = 1 << pins;
>>>> +
>>>> +	return mux_chip;
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(mux_gpio_alloc);
>>>> +
>>>> +#endif /* CONFIG_MUX_GPIO */
>>>> +
>>>>  struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
>>>>  {
>>>>  	struct device_node *np = dev->of_node;
>>>> @@ -307,9 +365,28 @@ struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
>>>>  	ret = of_parse_phandle_with_args(np,
>>>>  					 "mux-controls", "#mux-control-cells",
>>>>  					 index, &args);
>>>> +
>>>> +#ifdef CONFIG_MUX_GPIO
>>>> +	if (ret == -ENOENT && !mux_name && gpiod_count(dev, "mux") > 0) {
>>>> +		mux_chip = mux_gpio_alloc(dev);
>>>> +		if (!IS_ERR(mux_chip)) {
>>>> +			ret = devm_mux_chip_register(dev, mux_chip);
>>>> +			if (ret < 0) {
>>>> +				dev_err(dev, "failed to register mux-chip\n");
>>>> +				return ERR_PTR(ret);
>>>> +			}
>>>> +			get_device(&mux_chip->dev);
>>>> +			return mux_chip->mux;
>>>> +		}
>>>> +
>>>> +		ret = PTR_ERR(mux_chip);
>>>> +	}
>>>> +#endif
>>>> +
>>>>  	if (ret) {
>>>> -		dev_err(dev, "%s: failed to get mux-control %s(%i)\n",
>>>> -			np->full_name, mux_name ?: "", index);
>>>> +		if (ret != -EPROBE_DEFER)
>>>> +			dev_err(dev, "%s: failed to get mux-control %s(%i)\n",
>>>> +				np->full_name, mux_name ?: "", index);
>>>>  		return ERR_PTR(ret);
>>>>  	}
>>>>  
>>>> diff --git a/drivers/mux/mux-gpio.c b/drivers/mux/mux-gpio.c
>>>> index 76b52bc63470..8a7bfbc0c4bb 100644
>>>> --- a/drivers/mux/mux-gpio.c
>>>> +++ b/drivers/mux/mux-gpio.c
>>>> @@ -11,37 +11,12 @@
>>>>   */
>>>>  
>>>>  #include <linux/err.h>
>>>> -#include <linux/gpio/consumer.h>
>>>>  #include <linux/module.h>
>>>>  #include <linux/mux.h>
>>>>  #include <linux/of_platform.h>
>>>>  #include <linux/platform_device.h>
>>>>  #include <linux/property.h>
>>>
>>> Instead of moving the mux-gpio guts from mux-gpio.c to mux-core.c, I
>>> will instead make CONFIG_MUX_GPIO a bool option (no module possible)
>>> and call it from the mux-core. That will be cleaner and less of a
>>> break of abstractions in my opinion.
>> Hmm. I wonder if the balance is right here or whether we should just not have the
>> simplified binding at all as it breaks the assumption that all muxes are of the
>> same level...
>>
>> I like the binding, but it is causing significant complexity in here.
> 
> Yes, in this patch it looks pretty bad. But with the suggested
> changes it at least looks fine (apart from the remaining ifdef
> in mux_control_get). But then there's of course the conceptual
> badness of the core depending on a specific driver that you
> mention...
> 
> But. I expect that gpio based muxes will be in vast majority, and
> giving them some extra freedoms is probably not wrong considering
> the upside of the simpler binding.
> 
Difficult balance. As you are going to be the poor soul who has
to maintain this I'm not that bothered either way ;)
Probably worth gathering a few more opinions on this though if
they are forthcoming.

Jonathan
>>>
>>> Cheers,
>>> Peter
>>>
>>>> -struct mux_gpio {
>>>> -	struct gpio_descs *gpios;
>>>> -	int *val;
>>>> -};
>>>> -
>>>> -static int mux_gpio_set(struct mux_control *mux, int state)
>>>> -{
>>>> -	struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip);
>>>> -	int i;
>>>> -
>>>> -	for (i = 0; i < mux_gpio->gpios->ndescs; i++)
>>>> -		mux_gpio->val[i] = (state >> i) & 1;
>>>> -
>>>> -	gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,
>>>> -				       mux_gpio->gpios->desc,
>>>> -				       mux_gpio->val);
>>>> -
>>>> -	return 0;
>>>> -}
>>>> -
>>>> -static const struct mux_control_ops mux_gpio_ops = {
>>>> -	.set = mux_gpio_set,
>>>> -};
>>>> -
>>>>  static const struct of_device_id mux_gpio_dt_ids[] = {
>>>>  	{ .compatible = "mux-gpio", },
>>>>  	{ /* sentinel */ }
>>>> @@ -51,38 +26,13 @@ MODULE_DEVICE_TABLE(of, mux_gpio_dt_ids);
>>>>  static int mux_gpio_probe(struct platform_device *pdev)
>>>>  {
>>>>  	struct device *dev = &pdev->dev;
>>>> -	struct device_node *np = dev->of_node;
>>>>  	struct mux_chip *mux_chip;
>>>> -	struct mux_gpio *mux_gpio;
>>>> -	int pins;
>>>>  	u32 idle_state;
>>>>  	int ret;
>>>>  
>>>> -	if (!np)
>>>> -		return -ENODEV;
>>>> -
>>>> -	pins = gpiod_count(dev, "mux");
>>>> -	if (pins < 0)
>>>> -		return pins;
>>>> -
>>>> -	mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio) +
>>>> -				       pins * sizeof(*mux_gpio->val));
>>>> -	if (!mux_chip)
>>>> -		return -ENOMEM;
>>>> -
>>>> -	mux_gpio = mux_chip_priv(mux_chip);
>>>> -	mux_gpio->val = (int *)(mux_gpio + 1);
>>>> -	mux_chip->ops = &mux_gpio_ops;
>>>> -
>>>> -	mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW);
>>>> -	if (IS_ERR(mux_gpio->gpios)) {
>>>> -		ret = PTR_ERR(mux_gpio->gpios);
>>>> -		if (ret != -EPROBE_DEFER)
>>>> -			dev_err(dev, "failed to get gpios\n");
>>>> -		return ret;
>>>> -	}
>>>> -	WARN_ON(pins != mux_gpio->gpios->ndescs);
>>>> -	mux_chip->mux->states = 1 << pins;
>>>> +	mux_chip = mux_gpio_alloc(dev);
>>>> +	if (IS_ERR(mux_chip))
>>>> +		return PTR_ERR(mux_chip);
>>>>  
>>>>  	ret = device_property_read_u32(dev, "idle-state", &idle_state);
>>>>  	if (ret >= 0) {
>>>> diff --git a/include/linux/mux.h b/include/linux/mux.h
>>>> index 3b9439927f11..3bfee23cfb8c 100644
>>>> --- a/include/linux/mux.h
>>>> +++ b/include/linux/mux.h
>>>> @@ -241,4 +241,11 @@ struct mux_control *devm_mux_control_get(struct device *dev,
>>>>   */
>>>>  void devm_mux_control_put(struct device *dev, struct mux_control *mux);
>>>>  
>>>> +struct mux_gpio {
>>>> +	struct gpio_descs *gpios;
>>>> +	int *val;
>>>> +};
>>>> +
>>>> +struct mux_chip *mux_gpio_alloc(struct device *dev);
>>>> +
>>>>  #endif /* _LINUX_MUX_H */
>>>>
>>>
>>
> 

^ permalink raw reply

* [PATCH] devicetree: Add Fujitsu Ltd. vendor prefix
From: Marek Vasut @ 2017-01-10 21:32 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA; +Cc: Marek Vasut, Rob Herring

The vendor prefix for Fujitsu is used in the tree, but it's
still missing from the documentation, so add it. Fujitsu Ltd.
is a japanese ICT company, http://www.fujitsu.com

Signed-off-by: Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d9c51d7f4aac..b04ef615c124 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -103,6 +103,7 @@ firefly	Firefly
 focaltech	FocalTech Systems Co.,Ltd
 friendlyarm	Guangzhou FriendlyARM Computer Tech Co., Ltd
 fsl	Freescale Semiconductor
+fujitsu	Fujitsu Ltd.
 ge	General Electric Company
 geekbuying	GeekBuying
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH 6/9] dt/bindings: Add a serial/UART attached device binding
From: Pavel Machek @ 2017-01-10 21:41 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, Marcel Holtmann, Jiri Slaby,
	Sebastian Reichel, Arnd Bergmann, Dr . H . Nikolaus Schaller,
	Peter Hurley, Andy Shevchenko, Alan Cox, Loic Poulain, NeilBrown,
	Linus Walleij, linux-bluetooth, linux-serial, linux-kernel,
	Mark Rutland, devicetree
In-Reply-To: <20170106162635.19677-7-robh@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

On Fri 2017-01-06 10:26:32, Rob Herring wrote:
> Add a common binding for describing serial/UART attached devices. Common
> examples are Bluetooth, WiFi, NFC and GPS devices.
> 
> Serial attached devices are represented as child nodes of a UART node.
> This may need to be extended for more complex devices with multiple
> interfaces, but for the simple cases a child node is sufficient.
> 
> Signed-off-by: Rob Herring <robh@kernel.org>

Looks ok to me.

Acked-by: Pavel Machek <pavel@ucw.cz>

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/4] usb: dwc2: Add binding for AHB burst
From: John Youn @ 2017-01-10 21:46 UTC (permalink / raw)
  To: Christian Lamparter, John Youn
  Cc: Felipe Balbi, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <19255165.1fIP7jmgm1@debian64>

On 12/19/2016 6:49 AM, Christian Lamparter wrote:
> Hello John, hello Felipe
> 
> On Monday, November 28, 2016 7:32:20 PM CET John Youn wrote:
>> On 11/22/2016 12:51 PM, Christian Lamparter wrote:
>>> On Monday, November 21, 2016 7:32:30 PM CET John Youn wrote:
>>>> On 11/21/2016 1:10 PM, Christian Lamparter wrote:
>>>>> On Monday, November 21, 2016 12:16:31 PM CET John Youn wrote:
>>>>>> On 11/18/2016 12:18 PM, Christian Lamparter wrote:
>>>>>>> On Friday, November 18, 2016 8:16:08 AM CET Rob Herring wrote:
>>>>>>>> Also, perhaps you should allow that the compatible string can define the 
>>>>>>>> default.
>>>>>>>>
>>>>>>> I hoped you would say that :).
>>>>>>>
>>>>>>> I've attached a patch (on top of John Youn changes) [...]
>>>>>>> ---
>>>>>>> Subject: [PATCH] usb: dwc2: add a default ahb-burst setting for amcc,dwc-otg
>>>>>>> [...]
>>>>>>> @@ -1097,6 +1097,22 @@ static const char *const ahb_bursts[] = {
>>>>>>> +/* [...] */
>>>>>>> +static const struct of_device_id dwc2_compat_ahb_bursts[] = {
>>>>>>> +	{
>>>>>>> +		.compatible = "amcc,dwc-otg",
>>>>>>> +		.data = (void *) GAHBCFG_HBSTLEN_INCR16,
>>>>>>> +	},
>>>>>>> +};
>>>> [...]
>>>>>>>> @@ -1107,6 +1123,12 @@ static int dwc2_get_property_ahb_burst(struct dwc2_hsotg *hsotg)
>>>>>>>  	ret = device_property_read_string(hsotg->dev, "snps,ahb-burst", &str);
>>>>>>>  	if (ret < 0) {
>>>>>>> +		const struct of_device_id *match;
>>>>>>> +
>>>>>>> +		match = of_match_node(dwc2_compat_ahb_bursts, node);
>>>>>>> +		if (match)
>>>>>>> +			ret = (int)match->data;
>>>>>>> +
>>>> [...]
>>>>>> I'd prefer if you use the binding which requires no extra code in
>>>>>> dwc2.
>>>>> I'm fine with either option. However it think that this would require
>>>>> that either Mark or Rob would allow an exception to the "keep existing
>>>>> dts the way they are) and ack the following change to the canyonlands.dts. 
>>>> [...]
>>
>> Ok thanks for clearing that up. I understand.
>>
>> For now we can just set the property to "INCR16" based on the
>> compatible string. Perhaps in the future do this from a glue-layer
>> driver which binds to all compatible strings other than "snps,dwc2".
>>
>> I won't be able to do anything with this until next week though.
> Ok, I think enough time has passed. I would like to see this
> patch series (v3 [0]) being queued for 4.11+ together with
> "usb: dwc2: add a default ahb-burst setting for amcc,dwc-otg" [1].
> 
> Felipe, if you want I can resend the series and add the
> "amcc,dwc-otg" patch to it as well. Just let me know what you
> prefer here.
> 
> Regards,
> Christian
> 
> [0] <https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mail-2Darchive.com_linux-2Dusb-40vger.kernel.org_msg83401.html&d=DgICAg&c=DPL6_X_6JkXFx7AXWqB0tg&r=0VsY7UdB1d6feXmjAhNrI_qghu91wtaLLnO3I3Uw2os&m=9a_ZbkfhbOdNjPstQXQq2hm157AzXQX03qKZIddHarU&s=zb0Zx7ZwvnKxcbpCJ_RlLrt1JtzhwUm9DffIAn9oR3k&e= >
> [1] <https://urldefense.proofpoint.com/v2/url?u=https-3A__www.spinics.net_lists_linux-2Dusb_msg149663.html&d=DgICAg&c=DPL6_X_6JkXFx7AXWqB0tg&r=0VsY7UdB1d6feXmjAhNrI_qghu91wtaLLnO3I3Uw2os&m=9a_ZbkfhbOdNjPstQXQq2hm157AzXQX03qKZIddHarU&s=23LsbEs2DjUVLrj4ifAU2LCzEi-U3wn1G1Nx9FBIxvw&e= >
> 

Hi Christian,

This should be fixed against the latest dwc2 param rework series [1]
which i hope to get queued for 4.11. If you can give it a test, that
would be great.

Regards,
John

[1] https://www.spinics.net/lists/linux-usb/msg151693.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 0/2] add support to STM LSM6DS3-LSM6DSM 6-axis Mems sensor
From: Lorenzo Bianconi @ 2017-01-10 21:55 UTC (permalink / raw)
  To: jic23-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, lorenzo.bianconi-qxv4g6HH51o

Changes since v3:
- use I2C protocol instead of SMBus commands
- allow reading of the scale/sampling frequency whilst buffered operation is
  on going
- move st_lsm6dsx_hw allocation/initialization in st_lsm6dsx_probe() in order
  to avoid code duplication
- introduce enum st_lsm6dsx_hw_id to be used as I2C/SPI driver_data instead of
  the device name (string)
- improve code documentation

Changes since v2:
- improve code documentation
- improve code readability
- use spi_write() instead of spi_sync_transfer() in st_lsm6dsx_spi_write()
- use SMBus commands instead of I2C protocol
- use fifo_lock mutex to prevent concurrent access to hw FIFO instead of
  disabling/enabling irq line in st_lsm6dsx_flush_fifo()
- rename ring occurrences in buffer ones

Changes since v1:
- add sw fifo support
- drop trigger dependency
- use iio_claim_direct_mode() routine instead of grabbing the mutex directly
- use more unique prefix for all defines
- use info_mask_shared_by_all element for sampling_frequency
- use devm_iio_* routines
- use of_match_ptr instead of access directly to of_match_table
- fix device tree binding
- rename st_lsm6dsx_dev in st_lsm6dsx_hw
- cosmetics

Lorenzo Bianconi (2):
  iio: imu: add support to lsm6dsx driver
  Documentation: dt: iio: add st_lsm6dsx sensor device binding

 .../devicetree/bindings/iio/imu/st_lsm6dsx.txt     |  24 +
 drivers/iio/imu/Kconfig                            |   1 +
 drivers/iio/imu/Makefile                           |   2 +
 drivers/iio/imu/st_lsm6dsx/Kconfig                 |  23 +
 drivers/iio/imu/st_lsm6dsx/Makefile                |   5 +
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h            | 142 +++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c     | 455 ++++++++++++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c       | 673 +++++++++++++++++++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c        | 101 ++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c        | 118 ++++
 10 files changed, 1544 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
 create mode 100644 drivers/iio/imu/st_lsm6dsx/Kconfig
 create mode 100644 drivers/iio/imu/st_lsm6dsx/Makefile
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c

-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 1/2] iio: imu: add support to lsm6dsx driver
From: Lorenzo Bianconi @ 2017-01-10 21:55 UTC (permalink / raw)
  To: jic23-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, lorenzo.bianconi-qxv4g6HH51o
In-Reply-To: <20170110215519.960-1-lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>

Add support to STM LSM6DS3-LSM6DSM 6-axis (acc + gyro) Mems sensor

http://www.st.com/resource/en/datasheet/lsm6ds3.pdf
http://www.st.com/resource/en/datasheet/lsm6dsm.pdf

- continuous mode support
- i2c support
- spi support
- sw fifo mode support
- supported devices: lsm6ds3, lsm6dsm

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
---
 drivers/iio/imu/Kconfig                        |   1 +
 drivers/iio/imu/Makefile                       |   2 +
 drivers/iio/imu/st_lsm6dsx/Kconfig             |  23 +
 drivers/iio/imu/st_lsm6dsx/Makefile            |   5 +
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h        | 142 ++++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 455 +++++++++++++++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c   | 673 +++++++++++++++++++++++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c    | 101 ++++
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c    | 118 +++++
 9 files changed, 1520 insertions(+)
 create mode 100644 drivers/iio/imu/st_lsm6dsx/Kconfig
 create mode 100644 drivers/iio/imu/st_lsm6dsx/Makefile
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
 create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c

diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 1f1ad41..156630a 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -39,6 +39,7 @@ config KMX61
 	  be called kmx61.
 
 source "drivers/iio/imu/inv_mpu6050/Kconfig"
+source "drivers/iio/imu/st_lsm6dsx/Kconfig"
 
 endmenu
 
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index c71bcd3..8b563c3 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -17,3 +17,5 @@ obj-y += bmi160/
 obj-y += inv_mpu6050/
 
 obj-$(CONFIG_KMX61) += kmx61.o
+
+obj-y += st_lsm6dsx/
diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig
new file mode 100644
index 0000000..2ebcb74
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/Kconfig
@@ -0,0 +1,23 @@
+
+config IIO_ST_LSM6DSX
+	tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors"
+	depends on (I2C || SPI)
+	select IIO_BUFFER
+	select IIO_KFIFO_BUF
+	select IIO_ST_LSM6DSX_I2C if (I2C)
+	select IIO_ST_LSM6DSX_SPI if (SPI_MASTER)
+	help
+	  Say yes here to build support for STMicroelectronics LSM6DSx imu
+	  sensor. Supported devices: lsm6ds3, lsm6dsm
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called st_lsm6dsx.
+
+config IIO_ST_LSM6DSX_I2C
+	tristate
+	depends on IIO_ST_LSM6DSX
+
+config IIO_ST_LSM6DSX_SPI
+	tristate
+	depends on IIO_ST_LSM6DSX
+
diff --git a/drivers/iio/imu/st_lsm6dsx/Makefile b/drivers/iio/imu/st_lsm6dsx/Makefile
new file mode 100644
index 0000000..35919fe
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/Makefile
@@ -0,0 +1,5 @@
+st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o
+
+obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o
+obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o
+obj-$(CONFIG_IIO_ST_LSM6DSX_SPI) += st_lsm6dsx_spi.o
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
new file mode 100644
index 0000000..16189ff
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -0,0 +1,142 @@
+/*
+ * STMicroelectronics st_lsm6dsx sensor driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
+ * Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef ST_LSM6DSX_H
+#define ST_LSM6DSX_H
+
+#include <linux/device.h>
+
+#define ST_LSM6DS3_DEV_NAME	"lsm6ds3"
+#define ST_LSM6DSM_DEV_NAME	"lsm6dsm"
+
+enum st_lsm6dsx_hw_id {
+	ST_LSM6DS3_ID,
+	ST_LSM6DSM_ID,
+};
+
+#define ST_LSM6DSX_CHAN_SIZE		2
+#define ST_LSM6DSX_SAMPLE_SIZE		6
+#define ST_LSM6DSX_SAMPLE_DEPTH		(ST_LSM6DSX_SAMPLE_SIZE / \
+					 ST_LSM6DSX_CHAN_SIZE)
+
+#if defined(CONFIG_SPI_MASTER)
+#define ST_LSM6DSX_RX_MAX_LENGTH	256
+#define ST_LSM6DSX_TX_MAX_LENGTH	8
+
+struct st_lsm6dsx_transfer_buffer {
+	u8 rx_buf[ST_LSM6DSX_RX_MAX_LENGTH];
+	u8 tx_buf[ST_LSM6DSX_TX_MAX_LENGTH] ____cacheline_aligned;
+};
+#endif /* CONFIG_SPI_MASTER */
+
+struct st_lsm6dsx_transfer_function {
+	int (*read)(struct device *dev, u8 addr, int len, u8 *data);
+	int (*write)(struct device *dev, u8 addr, int len, u8 *data);
+};
+
+struct st_lsm6dsx_reg {
+	u8 addr;
+	u8 mask;
+};
+
+struct st_lsm6dsx_settings {
+	u8 wai;
+	u16 max_fifo_size;
+	enum st_lsm6dsx_hw_id id;
+};
+
+enum st_lsm6dsx_sensor_id {
+	ST_LSM6DSX_ID_ACC,
+	ST_LSM6DSX_ID_GYRO,
+	ST_LSM6DSX_ID_MAX,
+};
+
+enum st_lsm6dsx_fifo_mode {
+	ST_LSM6DSX_FIFO_BYPASS = 0x0,
+	ST_LSM6DSX_FIFO_CONT = 0x6,
+};
+
+/**
+ * struct st_lsm6dsx_sensor - ST IMU sensor instance
+ * @id: Sensor identifier.
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ * @gain: Configured sensor sensitivity.
+ * @odr: Output data rate of the sensor [Hz].
+ * @watermark: Sensor watermark level.
+ * @sip: Number of samples in a given pattern.
+ * @decimator: FIFO decimation factor.
+ * @decimator_mask: Sensor mask for decimation register.
+ * @delta_ts: Delta time between two consecutive interrupts.
+ * @ts: Latest timestamp from the interrupt handler.
+ */
+struct st_lsm6dsx_sensor {
+	enum st_lsm6dsx_sensor_id id;
+	struct st_lsm6dsx_hw *hw;
+
+	u32 gain;
+	u16 odr;
+
+	u16 watermark;
+	u8 sip;
+	u8 decimator;
+	u8 decimator_mask;
+
+	s64 delta_ts;
+	s64 ts;
+};
+
+/**
+ * struct st_lsm6dsx_hw - ST IMU MEMS hw instance
+ * @dev: Pointer to instance of struct device (I2C or SPI).
+ * @irq: Device interrupt line (I2C or SPI).
+ * @lock: Mutex to protect read and write operations.
+ * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
+ * @fifo_mode: FIFO operating mode supported by the device.
+ * @enable_mask: Enabled sensor bitmask.
+ * @sip: Total number of samples (acc/gyro) in a given pattern.
+ * @iio_devs: Pointers to acc/gyro iio_dev instances.
+ * @settings: Pointer to the specific sensor settings in use.
+ * @tf: Transfer function structure used by I/O operations.
+ * @tb: Transfer buffers used by SPI I/O operations.
+ */
+struct st_lsm6dsx_hw {
+	struct device *dev;
+	int irq;
+
+	struct mutex lock;
+	struct mutex fifo_lock;
+
+	enum st_lsm6dsx_fifo_mode fifo_mode;
+	u8 enable_mask;
+	u8 sip;
+
+	struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX];
+
+	const struct st_lsm6dsx_settings *settings;
+
+	const struct st_lsm6dsx_transfer_function *tf;
+#if defined(CONFIG_SPI_MASTER)
+	struct st_lsm6dsx_transfer_buffer tb;
+#endif /* CONFIG_SPI_MASTER */
+};
+
+int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
+		     const struct st_lsm6dsx_transfer_function *tf_ops);
+int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor);
+int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor);
+int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw);
+int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
+			       u8 val);
+int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
+				u16 watermark);
+
+#endif /* ST_LSM6DSX_H */
+
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
new file mode 100644
index 0000000..a16d7c9
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -0,0 +1,455 @@
+/*
+ * STMicroelectronics st_lsm6dsx FIFO buffer library driver
+ *
+ * LSM6DS3/LSM6DSM: The FIFO buffer can be configured to store data
+ * from gyroscope and accelerometer. Samples are queued without any tag
+ * according to a specific pattern based on 'FIFO data sets' (6 bytes each):
+ *  - 1st data set is reserved for gyroscope data
+ *  - 2nd data set is reserved for accelerometer data
+ * The FIFO pattern changes depending on the ODRs and decimation factors
+ * assigned to the FIFO data sets. The first sequence of data stored in FIFO
+ * buffer contains the data of all the enabled FIFO data sets
+ * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
+ * value of the decimation factor and ODR set for each FIFO data set.
+ * FIFO supported modes:
+ *  - BYPASS: FIFO disabled
+ *  - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
+ *    restarts from the beginning and the oldest sample is overwritten
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
+ * Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>
+ *
+ * Licensed under the GPL-2.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+
+#include "st_lsm6dsx.h"
+
+#define ST_LSM6DSX_REG_FIFO_THL_ADDR		0x06
+#define ST_LSM6DSX_REG_FIFO_THH_ADDR		0x07
+#define ST_LSM6DSX_FIFO_TH_MASK			GENMASK(11, 0)
+#define ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR	0x08
+#define ST_LSM6DSX_REG_FIFO_MODE_ADDR		0x0a
+#define ST_LSM6DSX_FIFO_MODE_MASK		GENMASK(2, 0)
+#define ST_LSM6DSX_FIFO_ODR_MASK		GENMASK(6, 3)
+#define ST_LSM6DSX_REG_FIFO_DIFFL_ADDR		0x3a
+#define ST_LSM6DSX_FIFO_DIFF_MASK		GENMASK(11, 0)
+#define ST_LSM6DSX_FIFO_EMPTY_MASK		BIT(12)
+#define ST_LSM6DSX_REG_FIFO_OUTL_ADDR		0x3e
+
+#define ST_LSM6DSX_MAX_FIFO_ODR_VAL		0x08
+
+struct st_lsm6dsx_decimator_entry {
+	u8 decimator;
+	u8 val;
+};
+
+static const
+struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
+	{  0, 0x0 },
+	{  1, 0x1 },
+	{  2, 0x2 },
+	{  3, 0x3 },
+	{  4, 0x4 },
+	{  8, 0x5 },
+	{ 16, 0x6 },
+	{ 32, 0x7 },
+};
+
+static int st_lsm6dsx_get_decimator_val(u8 val)
+{
+	const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
+	int i;
+
+	for (i = 0; i < max_size; i++)
+		if (st_lsm6dsx_decimator_table[i].decimator == val)
+			break;
+
+	return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
+}
+
+static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
+				       u16 *max_odr, u16 *min_odr)
+{
+	struct st_lsm6dsx_sensor *sensor;
+	int i;
+
+	*max_odr = 0, *min_odr = ~0;
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		sensor = iio_priv(hw->iio_devs[i]);
+
+		if (!(hw->enable_mask & BIT(sensor->id)))
+			continue;
+
+		*max_odr = max_t(u16, *max_odr, sensor->odr);
+		*min_odr = min_t(u16, *min_odr, sensor->odr);
+	}
+}
+
+static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
+{
+	struct st_lsm6dsx_sensor *sensor;
+	u16 max_odr, min_odr, sip = 0;
+	int err, i;
+	u8 data;
+
+	st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		sensor = iio_priv(hw->iio_devs[i]);
+
+		/* update fifo decimators and sample in pattern */
+		if (hw->enable_mask & BIT(sensor->id)) {
+			sensor->sip = sensor->odr / min_odr;
+			sensor->decimator = max_odr / sensor->odr;
+			data = st_lsm6dsx_get_decimator_val(sensor->decimator);
+		} else {
+			sensor->sip = 0;
+			sensor->decimator = 0;
+			data = 0;
+		}
+
+		err = st_lsm6dsx_write_with_mask(hw,
+					ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR,
+					sensor->decimator_mask, data);
+		if (err < 0)
+			return err;
+
+		sip += sensor->sip;
+	}
+	hw->sip = sip;
+
+	return 0;
+}
+
+static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
+				    enum st_lsm6dsx_fifo_mode fifo_mode)
+{
+	u8 data;
+	int err;
+
+	switch (fifo_mode) {
+	case ST_LSM6DSX_FIFO_BYPASS:
+		data = fifo_mode;
+		break;
+	case ST_LSM6DSX_FIFO_CONT:
+		data = (ST_LSM6DSX_MAX_FIFO_ODR_VAL <<
+			__ffs(ST_LSM6DSX_FIFO_ODR_MASK)) | fifo_mode;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
+			    sizeof(data), &data);
+	if (err < 0)
+		return err;
+
+	hw->fifo_mode = fifo_mode;
+
+	return 0;
+}
+
+int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
+{
+	u16 fifo_watermark = ~0, cur_watermark, sip = 0;
+	struct st_lsm6dsx_hw *hw = sensor->hw;
+	struct st_lsm6dsx_sensor *cur_sensor;
+	__le16 wdata;
+	int i, err;
+	u8 data;
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		cur_sensor = iio_priv(hw->iio_devs[i]);
+
+		if (!(hw->enable_mask & BIT(cur_sensor->id)))
+			continue;
+
+		cur_watermark = (cur_sensor == sensor) ? watermark
+						       : cur_sensor->watermark;
+
+		fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
+		sip += cur_sensor->sip;
+	}
+
+	if (!sip)
+		return 0;
+
+	fifo_watermark = max_t(u16, fifo_watermark, sip);
+	fifo_watermark = (fifo_watermark / sip) * sip;
+	fifo_watermark = fifo_watermark * ST_LSM6DSX_SAMPLE_DEPTH;
+
+	mutex_lock(&hw->lock);
+
+	err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_THH_ADDR,
+			   sizeof(data), &data);
+	if (err < 0)
+		goto out;
+
+	fifo_watermark = ((data & ~ST_LSM6DSX_FIFO_TH_MASK) << 8) |
+			  (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK);
+
+	wdata = cpu_to_le16(fifo_watermark);
+	err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_THL_ADDR,
+			    sizeof(wdata), (u8 *)&wdata);
+out:
+	mutex_unlock(&hw->lock);
+
+	return err < 0 ? err : 0;
+}
+
+/**
+ * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DSM read FIFO routine
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ *
+ * Read samples from the hw FIFO and push them to IIO buffers.
+ *
+ * Return: Number of bytes read from the FIFO
+ */
+static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
+{
+	u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
+	int err, acc_sip, gyro_sip, read_len, samples, offset;
+	struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
+	s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts;
+	u8 iio_buff[ALIGN(ST_LSM6DSX_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)];
+	u8 buff[pattern_len];
+	__le16 fifo_status;
+
+	err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_DIFFL_ADDR,
+			   sizeof(fifo_status), (u8 *)&fifo_status);
+	if (err < 0)
+		return err;
+
+	if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
+		return 0;
+
+	fifo_len = (le16_to_cpu(fifo_status) & ST_LSM6DSX_FIFO_DIFF_MASK) *
+		   ST_LSM6DSX_CHAN_SIZE;
+	samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE;
+	fifo_len = (fifo_len / pattern_len) * pattern_len;
+
+	/*
+	 * compute delta timestamp between two consecutive samples
+	 * in order to estimate queueing time of data generated
+	 * by the sensor
+	 */
+	acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+	acc_ts = acc_sensor->ts - acc_sensor->delta_ts;
+	acc_delta_ts = div_s64(acc_sensor->delta_ts * acc_sensor->decimator,
+			       samples);
+
+	gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
+	gyro_ts = gyro_sensor->ts - gyro_sensor->delta_ts;
+	gyro_delta_ts = div_s64(gyro_sensor->delta_ts * gyro_sensor->decimator,
+				samples);
+
+	for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
+		err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
+				   sizeof(buff), buff);
+		if (err < 0)
+			return err;
+
+		/*
+		 * Data are written to the FIFO with a specific pattern
+		 * depending on the configured ODRs. The first sequence of data
+		 * stored in FIFO contains the data of all enabled sensors
+		 * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated
+		 * depending on the value of the decimation factor set for each
+		 * sensor.
+		 *
+		 * Supposing the FIFO is storing data from gyroscope and
+		 * accelerometer at different ODRs:
+		 *   - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz
+		 * Since the gyroscope ODR is twice the accelerometer one, the
+		 * following pattern is repeated every 9 samples:
+		 *   - Gx, Gy, Gz, Ax, Ay, Az, Gx, Gy, Gz
+		 */
+		gyro_sip = gyro_sensor->sip;
+		acc_sip = acc_sensor->sip;
+		offset = 0;
+
+		while (acc_sip > 0 || gyro_sip > 0) {
+			if (gyro_sip-- > 0) {
+				memcpy(iio_buff, &buff[offset],
+				       ST_LSM6DSX_SAMPLE_SIZE);
+				iio_push_to_buffers_with_timestamp(
+					hw->iio_devs[ST_LSM6DSX_ID_GYRO],
+					iio_buff, gyro_ts);
+				offset += ST_LSM6DSX_SAMPLE_SIZE;
+				gyro_ts += gyro_delta_ts;
+			}
+
+			if (acc_sip-- > 0) {
+				memcpy(iio_buff, &buff[offset],
+				       ST_LSM6DSX_SAMPLE_SIZE);
+				iio_push_to_buffers_with_timestamp(
+					hw->iio_devs[ST_LSM6DSX_ID_ACC],
+					iio_buff, acc_ts);
+				offset += ST_LSM6DSX_SAMPLE_SIZE;
+				acc_ts += acc_delta_ts;
+			}
+		}
+	}
+
+	return read_len;
+}
+
+static int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
+{
+	int err;
+
+	mutex_lock(&hw->fifo_lock);
+
+	st_lsm6dsx_read_fifo(hw);
+	err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
+
+	mutex_unlock(&hw->fifo_lock);
+
+	return err;
+}
+
+static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+	struct st_lsm6dsx_hw *hw = sensor->hw;
+	int err;
+
+	if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) {
+		err = st_lsm6dsx_flush_fifo(hw);
+		if (err < 0)
+			return err;
+	}
+
+	if (enable) {
+		err = st_lsm6dsx_sensor_enable(sensor);
+		if (err < 0)
+			return err;
+	} else {
+		err = st_lsm6dsx_sensor_disable(sensor);
+		if (err < 0)
+			return err;
+	}
+
+	err = st_lsm6dsx_update_decimators(hw);
+	if (err < 0)
+		return err;
+
+	err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
+	if (err < 0)
+		return err;
+
+	if (hw->enable_mask) {
+		err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
+		if (err < 0)
+			return err;
+
+		/*
+		 * store enable buffer timestamp as reference to compute
+		 * first delta timestamp
+		 */
+		sensor->ts = iio_get_time_ns(iio_dev);
+	}
+
+	return 0;
+}
+
+static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
+{
+	struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private;
+	struct st_lsm6dsx_sensor *sensor;
+	int i;
+
+	if (!hw->sip)
+		return IRQ_NONE;
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		sensor = iio_priv(hw->iio_devs[i]);
+
+		if (sensor->sip > 0) {
+			s64 timestamp;
+
+			timestamp = iio_get_time_ns(hw->iio_devs[i]);
+			sensor->delta_ts = timestamp - sensor->ts;
+			sensor->ts = timestamp;
+		}
+	}
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
+{
+	struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private;
+	int count;
+
+	mutex_lock(&hw->fifo_lock);
+	count = st_lsm6dsx_read_fifo(hw);
+	mutex_unlock(&hw->fifo_lock);
+
+	return !count ? IRQ_NONE : IRQ_HANDLED;
+}
+
+static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
+{
+	return st_lsm6dsx_update_fifo(iio_dev, true);
+}
+
+static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
+{
+	return st_lsm6dsx_update_fifo(iio_dev, false);
+}
+
+static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
+	.preenable = st_lsm6dsx_buffer_preenable,
+	.postdisable = st_lsm6dsx_buffer_postdisable,
+};
+
+int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
+{
+	struct iio_buffer *buffer;
+	unsigned long irq_type;
+	int i, err;
+
+	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
+
+	switch (irq_type) {
+	case IRQF_TRIGGER_HIGH:
+	case IRQF_TRIGGER_RISING:
+		break;
+	default:
+		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
+		return -EINVAL;
+	}
+
+	err = devm_request_threaded_irq(hw->dev, hw->irq,
+					st_lsm6dsx_handler_irq,
+					st_lsm6dsx_handler_thread,
+					irq_type | IRQF_ONESHOT,
+					"lsm6dsx", hw);
+	if (err) {
+		dev_err(hw->dev, "failed to request trigger irq %d\n",
+			hw->irq);
+		return err;
+	}
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		buffer = devm_iio_kfifo_allocate(hw->dev);
+		if (!buffer)
+			return -ENOMEM;
+
+		iio_device_attach_buffer(hw->iio_devs[i], buffer);
+		hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
+		hw->iio_devs[i]->setup_ops = &st_lsm6dsx_buffer_ops;
+	}
+
+	return 0;
+}
+
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
new file mode 100644
index 0000000..01e002c
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -0,0 +1,673 @@
+/*
+ * STMicroelectronics st_lsm6dsx sensor driver
+ *
+ * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
+ * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
+ * interface standard output.
+ * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
+ * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
+ * +-125/+-245/+-500/+-1000/+-2000 dps
+ * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
+ * allowing dynamic batching of sensor data.
+ *
+ * Supported sensors:
+ * - LSM6DS3:
+ *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
+ *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
+ *   - FIFO size: 8KB
+ *
+ * - LSM6DSM:
+ *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
+ *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
+ *   - FIFO size: 4KB
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
+ * Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include "st_lsm6dsx.h"
+
+#define ST_LSM6DSX_REG_ACC_DEC_MASK		GENMASK(2, 0)
+#define ST_LSM6DSX_REG_GYRO_DEC_MASK		GENMASK(5, 3)
+#define ST_LSM6DSX_REG_INT1_ADDR		0x0d
+#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK	BIT(3)
+#define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
+#define ST_LSM6DSX_REG_RESET_ADDR		0x12
+#define ST_LSM6DSX_REG_RESET_MASK		BIT(0)
+#define ST_LSM6DSX_REG_BDU_ADDR			0x12
+#define ST_LSM6DSX_REG_BDU_MASK			BIT(6)
+#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR	0x13
+#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK	BIT(5)
+#define ST_LSM6DSX_REG_ROUNDING_ADDR		0x16
+#define ST_LSM6DSX_REG_ROUNDING_MASK		BIT(2)
+#define ST_LSM6DSX_REG_LIR_ADDR			0x58
+#define ST_LSM6DSX_REG_LIR_MASK			BIT(0)
+
+#define ST_LSM6DSX_REG_ACC_ODR_ADDR		0x10
+#define ST_LSM6DSX_REG_ACC_ODR_MASK		GENMASK(7, 4)
+#define ST_LSM6DSX_REG_ACC_FS_ADDR		0x10
+#define ST_LSM6DSX_REG_ACC_FS_MASK		GENMASK(3, 2)
+#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR		0x28
+#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR		0x2a
+#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR		0x2c
+
+#define ST_LSM6DSX_REG_GYRO_ODR_ADDR		0x11
+#define ST_LSM6DSX_REG_GYRO_ODR_MASK		GENMASK(7, 4)
+#define ST_LSM6DSX_REG_GYRO_FS_ADDR		0x11
+#define ST_LSM6DSX_REG_GYRO_FS_MASK		GENMASK(3, 2)
+#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR	0x22
+#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR	0x24
+#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR	0x26
+
+#define ST_LSM6DS3_WHOAMI			0x69
+#define ST_LSM6DSM_WHOAMI			0x6a
+
+#define ST_LSM6DS3_MAX_FIFO_SIZE		8192
+#define ST_LSM6DSM_MAX_FIFO_SIZE		4096
+
+#define ST_LSM6DSX_ACC_FS_2G_GAIN		IIO_G_TO_M_S_2(61)
+#define ST_LSM6DSX_ACC_FS_4G_GAIN		IIO_G_TO_M_S_2(122)
+#define ST_LSM6DSX_ACC_FS_8G_GAIN		IIO_G_TO_M_S_2(244)
+#define ST_LSM6DSX_ACC_FS_16G_GAIN		IIO_G_TO_M_S_2(488)
+
+#define ST_LSM6DSX_GYRO_FS_245_GAIN		IIO_DEGREE_TO_RAD(4375)
+#define ST_LSM6DSX_GYRO_FS_500_GAIN		IIO_DEGREE_TO_RAD(8750)
+#define ST_LSM6DSX_GYRO_FS_1000_GAIN		IIO_DEGREE_TO_RAD(17500)
+#define ST_LSM6DSX_GYRO_FS_2000_GAIN		IIO_DEGREE_TO_RAD(70000)
+
+struct st_lsm6dsx_odr {
+	u16 hz;
+	u8 val;
+};
+
+#define ST_LSM6DSX_ODR_LIST_SIZE	6
+struct st_lsm6dsx_odr_table_entry {
+	struct st_lsm6dsx_reg reg;
+	struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE];
+};
+
+static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
+	[ST_LSM6DSX_ID_ACC] = {
+		.reg = {
+			.addr = ST_LSM6DSX_REG_ACC_ODR_ADDR,
+			.mask = ST_LSM6DSX_REG_ACC_ODR_MASK,
+		},
+		.odr_avl[0] = {  13, 0x01 },
+		.odr_avl[1] = {  26, 0x02 },
+		.odr_avl[2] = {  52, 0x03 },
+		.odr_avl[3] = { 104, 0x04 },
+		.odr_avl[4] = { 208, 0x05 },
+		.odr_avl[5] = { 416, 0x06 },
+	},
+	[ST_LSM6DSX_ID_GYRO] = {
+		.reg = {
+			.addr = ST_LSM6DSX_REG_GYRO_ODR_ADDR,
+			.mask = ST_LSM6DSX_REG_GYRO_ODR_MASK,
+		},
+		.odr_avl[0] = {  13, 0x01 },
+		.odr_avl[1] = {  26, 0x02 },
+		.odr_avl[2] = {  52, 0x03 },
+		.odr_avl[3] = { 104, 0x04 },
+		.odr_avl[4] = { 208, 0x05 },
+		.odr_avl[5] = { 416, 0x06 },
+	}
+};
+
+struct st_lsm6dsx_fs {
+	u32 gain;
+	u8 val;
+};
+
+#define ST_LSM6DSX_FS_LIST_SIZE		4
+struct st_lsm6dsx_fs_table_entry {
+	struct st_lsm6dsx_reg reg;
+	struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE];
+};
+
+static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
+	[ST_LSM6DSX_ID_ACC] = {
+		.reg = {
+			.addr = ST_LSM6DSX_REG_ACC_FS_ADDR,
+			.mask = ST_LSM6DSX_REG_ACC_FS_MASK,
+		},
+		.fs_avl[0] = {  ST_LSM6DSX_ACC_FS_2G_GAIN, 0x0 },
+		.fs_avl[1] = {  ST_LSM6DSX_ACC_FS_4G_GAIN, 0x2 },
+		.fs_avl[2] = {  ST_LSM6DSX_ACC_FS_8G_GAIN, 0x3 },
+		.fs_avl[3] = { ST_LSM6DSX_ACC_FS_16G_GAIN, 0x1 },
+	},
+	[ST_LSM6DSX_ID_GYRO] = {
+		.reg = {
+			.addr = ST_LSM6DSX_REG_GYRO_FS_ADDR,
+			.mask = ST_LSM6DSX_REG_GYRO_FS_MASK,
+		},
+		.fs_avl[0] = {  ST_LSM6DSX_GYRO_FS_245_GAIN, 0x0 },
+		.fs_avl[1] = {  ST_LSM6DSX_GYRO_FS_500_GAIN, 0x1 },
+		.fs_avl[2] = { ST_LSM6DSX_GYRO_FS_1000_GAIN, 0x2 },
+		.fs_avl[3] = { ST_LSM6DSX_GYRO_FS_2000_GAIN, 0x3 },
+	}
+};
+
+static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+	{
+		.wai = ST_LSM6DS3_WHOAMI,
+		.max_fifo_size = ST_LSM6DS3_MAX_FIFO_SIZE,
+		.id = ST_LSM6DS3_ID,
+	},
+	{
+		.wai = ST_LSM6DSM_WHOAMI,
+		.max_fifo_size = ST_LSM6DSM_MAX_FIFO_SIZE,
+		.id = ST_LSM6DSM_ID,
+	},
+};
+
+#define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx)		\
+{									\
+	.type = chan_type,						\
+	.address = addr,						\
+	.modified = 1,							\
+	.channel2 = mod,						\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
+			      BIT(IIO_CHAN_INFO_SCALE),			\
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+	.scan_index = scan_idx,						\
+	.scan_type = {							\
+		.sign = 's',						\
+		.realbits = 16,						\
+		.storagebits = 16,					\
+		.endianness = IIO_LE,					\
+	},								\
+}
+
+static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+	ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR,
+			   IIO_MOD_X, 0),
+	ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR,
+			   IIO_MOD_Y, 1),
+	ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR,
+			   IIO_MOD_Z, 2),
+	IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
+	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR,
+			   IIO_MOD_X, 0),
+	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR,
+			   IIO_MOD_Y, 1),
+	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR,
+			   IIO_MOD_Z, 2),
+	IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
+			       u8 val)
+{
+	u8 data;
+	int err;
+
+	mutex_lock(&hw->lock);
+
+	err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
+	if (err < 0) {
+		dev_err(hw->dev, "failed to read %02x register\n", addr);
+		goto out;
+	}
+
+	data = (data & ~mask) | ((val << __ffs(mask)) & mask);
+
+	err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
+	if (err < 0)
+		dev_err(hw->dev, "failed to write %02x register\n", addr);
+
+out:
+	mutex_unlock(&hw->lock);
+
+	return err;
+}
+
+static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id)
+{
+	int err, i;
+	u8 data;
+
+	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
+		if (id == st_lsm6dsx_sensor_settings[i].id)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
+		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
+		return -ENODEV;
+	}
+
+	err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_WHOAMI_ADDR, sizeof(data),
+			   &data);
+	if (err < 0) {
+		dev_err(hw->dev, "failed to read whoami register\n");
+		return err;
+	}
+
+	if (data != st_lsm6dsx_sensor_settings[i].wai) {
+		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
+		return -ENODEV;
+	}
+
+	hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+	return 0;
+}
+
+static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
+				     u32 gain)
+{
+	enum st_lsm6dsx_sensor_id id = sensor->id;
+	int i, err;
+	u8 val;
+
+	for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+		if (st_lsm6dsx_fs_table[id].fs_avl[i].gain == gain)
+			break;
+
+	if (i == ST_LSM6DSX_FS_LIST_SIZE)
+		return -EINVAL;
+
+	val = st_lsm6dsx_fs_table[id].fs_avl[i].val;
+	err = st_lsm6dsx_write_with_mask(sensor->hw,
+					 st_lsm6dsx_fs_table[id].reg.addr,
+					 st_lsm6dsx_fs_table[id].reg.mask,
+					 val);
+	if (err < 0)
+		return err;
+
+	sensor->gain = gain;
+
+	return 0;
+}
+
+static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)
+{
+	enum st_lsm6dsx_sensor_id id = sensor->id;
+	int i, err;
+	u8 val;
+
+	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+		if (st_lsm6dsx_odr_table[id].odr_avl[i].hz == odr)
+			break;
+
+	if (i == ST_LSM6DSX_ODR_LIST_SIZE)
+		return -EINVAL;
+
+	val = st_lsm6dsx_odr_table[id].odr_avl[i].val;
+	err = st_lsm6dsx_write_with_mask(sensor->hw,
+					 st_lsm6dsx_odr_table[id].reg.addr,
+					 st_lsm6dsx_odr_table[id].reg.mask,
+					 val);
+	if (err < 0)
+		return err;
+
+	sensor->odr = odr;
+
+	return 0;
+}
+
+int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor)
+{
+	int err;
+
+	err = st_lsm6dsx_set_odr(sensor, sensor->odr);
+	if (err < 0)
+		return err;
+
+	sensor->hw->enable_mask |= BIT(sensor->id);
+
+	return 0;
+}
+
+int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor)
+{
+	enum st_lsm6dsx_sensor_id id = sensor->id;
+	int err;
+
+	err = st_lsm6dsx_write_with_mask(sensor->hw,
+					 st_lsm6dsx_odr_table[id].reg.addr,
+					 st_lsm6dsx_odr_table[id].reg.mask, 0);
+	if (err < 0)
+		return err;
+
+	sensor->hw->enable_mask &= ~BIT(id);
+
+	return 0;
+}
+
+static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
+				   u8 addr, int *val)
+{
+	int err, delay;
+	__le16 data;
+
+	err = st_lsm6dsx_sensor_enable(sensor);
+	if (err < 0)
+		return err;
+
+	delay = 1000000 / sensor->odr;
+	usleep_range(delay, 2 * delay);
+
+	err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
+				   (u8 *)&data);
+	if (err < 0)
+		return err;
+
+	st_lsm6dsx_sensor_disable(sensor);
+
+	*val = (s16)data;
+
+	return IIO_VAL_INT;
+}
+
+static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
+			       struct iio_chan_spec const *ch,
+			       int *val, int *val2, long mask)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = iio_device_claim_direct_mode(iio_dev);
+		if (ret)
+			break;
+
+		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
+		iio_device_release_direct_mode(iio_dev);
+		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = sensor->odr;
+		ret = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 0;
+		*val2 = sensor->gain;
+		ret = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
+				struct iio_chan_spec const *chan,
+				int val, int val2, long mask)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+	int err;
+
+	err = iio_device_claim_direct_mode(iio_dev);
+	if (err)
+		return err;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		err = st_lsm6dsx_set_full_scale(sensor, val2);
+		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		err = st_lsm6dsx_set_odr(sensor, val);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	iio_device_release_direct_mode(iio_dev);
+
+	return err;
+}
+
+static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+	struct st_lsm6dsx_hw *hw = sensor->hw;
+	int err, max_fifo_len;
+
+	max_fifo_len = hw->settings->max_fifo_size / ST_LSM6DSX_SAMPLE_SIZE;
+	if (val < 1 || val > max_fifo_len)
+		return -EINVAL;
+
+	err = st_lsm6dsx_update_watermark(sensor, val);
+	if (err < 0)
+		return err;
+
+	sensor->watermark = val;
+
+	return 0;
+}
+
+static ssize_t
+st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+	enum st_lsm6dsx_sensor_id id = sensor->id;
+	int i, len = 0;
+
+	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
+				 st_lsm6dsx_odr_table[id].odr_avl[i].hz);
+	buf[len - 1] = '\n';
+
+	return len;
+}
+
+static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+	enum st_lsm6dsx_sensor_id id = sensor->id;
+	int i, len = 0;
+
+	for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
+				 st_lsm6dsx_fs_table[id].fs_avl[i].gain);
+	buf[len - 1] = '\n';
+
+	return len;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
+static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
+		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
+		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
+
+static struct attribute *st_lsm6dsx_acc_attributes[] = {
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
+	.attrs = st_lsm6dsx_acc_attributes,
+};
+
+static const struct iio_info st_lsm6dsx_acc_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &st_lsm6dsx_acc_attribute_group,
+	.read_raw = st_lsm6dsx_read_raw,
+	.write_raw = st_lsm6dsx_write_raw,
+	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
+};
+
+static struct attribute *st_lsm6dsx_gyro_attributes[] = {
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
+	.attrs = st_lsm6dsx_gyro_attributes,
+};
+
+static const struct iio_info st_lsm6dsx_gyro_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &st_lsm6dsx_gyro_attribute_group,
+	.read_raw = st_lsm6dsx_read_raw,
+	.write_raw = st_lsm6dsx_write_raw,
+	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
+};
+
+static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
+
+static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+{
+	int err;
+	u8 data;
+
+	data = ST_LSM6DSX_REG_RESET_MASK;
+	err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_RESET_ADDR, sizeof(data),
+			    &data);
+	if (err < 0)
+		return err;
+
+	msleep(200);
+
+	/* latch interrupts */
+	err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_LIR_ADDR,
+					 ST_LSM6DSX_REG_LIR_MASK, 1);
+	if (err < 0)
+		return err;
+
+	/* enable Block Data Update */
+	err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_BDU_ADDR,
+					 ST_LSM6DSX_REG_BDU_MASK, 1);
+	if (err < 0)
+		return err;
+
+	err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_ROUNDING_ADDR,
+					 ST_LSM6DSX_REG_ROUNDING_MASK, 1);
+	if (err < 0)
+		return err;
+
+	/* enable FIFO watermak interrupt */
+	err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_INT1_ADDR,
+					 ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 1);
+	if (err < 0)
+		return err;
+
+	/* redirect INT2 on INT1 */
+	return st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_INT2_ON_INT1_ADDR,
+					  ST_LSM6DSX_REG_INT2_ON_INT1_MASK, 1);
+}
+
+static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
+					       enum st_lsm6dsx_sensor_id id)
+{
+	struct st_lsm6dsx_sensor *sensor;
+	struct iio_dev *iio_dev;
+
+	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
+	if (!iio_dev)
+		return NULL;
+
+	iio_dev->modes = INDIO_DIRECT_MODE;
+	iio_dev->dev.parent = hw->dev;
+	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
+
+	sensor = iio_priv(iio_dev);
+	sensor->id = id;
+	sensor->hw = hw;
+	sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
+	sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
+	sensor->watermark = 1;
+
+	switch (id) {
+	case ST_LSM6DSX_ID_ACC:
+		iio_dev->channels = st_lsm6dsx_acc_channels;
+		iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels);
+		iio_dev->name = "lsm6dsx_accel";
+		iio_dev->info = &st_lsm6dsx_acc_info;
+
+		sensor->decimator_mask = ST_LSM6DSX_REG_ACC_DEC_MASK;
+		break;
+	case ST_LSM6DSX_ID_GYRO:
+		iio_dev->channels = st_lsm6dsx_gyro_channels;
+		iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels);
+		iio_dev->name = "lsm6dsx_gyro";
+		iio_dev->info = &st_lsm6dsx_gyro_info;
+
+		sensor->decimator_mask = ST_LSM6DSX_REG_GYRO_DEC_MASK;
+		break;
+	default:
+		return NULL;
+	}
+
+	return iio_dev;
+}
+
+int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
+		     const struct st_lsm6dsx_transfer_function *tf_ops)
+{
+	struct st_lsm6dsx_hw *hw;
+	int i, err;
+
+	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, (void *)hw);
+
+	mutex_init(&hw->lock);
+	mutex_init(&hw->fifo_lock);
+
+	hw->dev = dev;
+	hw->irq = irq;
+	hw->tf = tf_ops;
+
+	err = st_lsm6dsx_check_whoami(hw, hw_id);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i);
+		if (!hw->iio_devs[i])
+			return -ENOMEM;
+	}
+
+	err = st_lsm6dsx_init_device(hw);
+	if (err < 0)
+		return err;
+
+	if (hw->irq > 0) {
+		err = st_lsm6dsx_fifo_setup(hw);
+		if (err < 0)
+			return err;
+	}
+
+	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(st_lsm6dsx_probe);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
new file mode 100644
index 0000000..ea30411
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
@@ -0,0 +1,101 @@
+/*
+ * STMicroelectronics st_lsm6dsx i2c driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
+ * Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_lsm6dsx.h"
+
+static int st_lsm6dsx_i2c_read(struct device *dev, u8 addr, int len, u8 *data)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_msg msg[2];
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags;
+	msg[0].len = 1;
+	msg[0].buf = &addr;
+
+	msg[1].addr = client->addr;
+	msg[1].flags = client->flags | I2C_M_RD;
+	msg[1].len = len;
+	msg[1].buf = data;
+
+	return i2c_transfer(client->adapter, msg, 2);
+}
+
+static int st_lsm6dsx_i2c_write(struct device *dev, u8 addr, int len, u8 *data)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_msg msg;
+	u8 send[len + 1];
+
+	send[0] = addr;
+	memcpy(&send[1], data, len * sizeof(u8));
+
+	msg.addr = client->addr;
+	msg.flags = client->flags;
+	msg.len = len + 1;
+	msg.buf = send;
+
+	return i2c_transfer(client->adapter, &msg, 1);
+}
+
+static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = {
+	.read = st_lsm6dsx_i2c_read,
+	.write = st_lsm6dsx_i2c_write,
+};
+
+static int st_lsm6dsx_i2c_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	return st_lsm6dsx_probe(&client->dev, client->irq,
+				(int)id->driver_data,
+				&st_lsm6dsx_transfer_fn);
+}
+
+static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
+	{
+		.compatible = "st,lsm6ds3",
+		.data = (void *)ST_LSM6DS3_ID,
+	},
+	{
+		.compatible = "st,lsm6dsm",
+		.data = (void *)ST_LSM6DSM_ID,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
+
+static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
+	{ ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+	{ ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
+
+static struct i2c_driver st_lsm6dsx_driver = {
+	.driver = {
+		.name = "st_lsm6dsx_i2c",
+		.of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match),
+	},
+	.probe = st_lsm6dsx_i2c_probe,
+	.id_table = st_lsm6dsx_i2c_id_table,
+};
+module_i2c_driver(st_lsm6dsx_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i2c driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
new file mode 100644
index 0000000..fbe7247
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
@@ -0,0 +1,118 @@
+/*
+ * STMicroelectronics st_lsm6dsx spi driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
+ * Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_lsm6dsx.h"
+
+#define SENSORS_SPI_READ	BIT(7)
+
+static int st_lsm6dsx_spi_read(struct device *dev, u8 addr, int len,
+			       u8 *data)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct st_lsm6dsx_hw *hw = spi_get_drvdata(spi);
+	int err;
+
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = hw->tb.tx_buf,
+			.bits_per_word = 8,
+			.len = 1,
+		},
+		{
+			.rx_buf = hw->tb.rx_buf,
+			.bits_per_word = 8,
+			.len = len,
+		}
+	};
+
+	hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
+
+	err = spi_sync_transfer(spi, xfers,  ARRAY_SIZE(xfers));
+	if (err < 0)
+		return err;
+
+	memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
+
+	return len;
+}
+
+static int st_lsm6dsx_spi_write(struct device *dev, u8 addr, int len,
+				u8 *data)
+{
+	struct st_lsm6dsx_hw *hw;
+	struct spi_device *spi;
+
+	if (len >= ST_LSM6DSX_TX_MAX_LENGTH)
+		return -ENOMEM;
+
+	spi = to_spi_device(dev);
+	hw = spi_get_drvdata(spi);
+
+	hw->tb.tx_buf[0] = addr;
+	memcpy(&hw->tb.tx_buf[1], data, len);
+
+	return spi_write(spi, hw->tb.tx_buf, len + 1);
+}
+
+static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = {
+	.read = st_lsm6dsx_spi_read,
+	.write = st_lsm6dsx_spi_write,
+};
+
+static int st_lsm6dsx_spi_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+
+	return st_lsm6dsx_probe(&spi->dev, spi->irq,
+				(int)id->driver_data,
+				&st_lsm6dsx_transfer_fn);
+}
+
+static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
+	{
+		.compatible = "st,lsm6ds3",
+		.data = (void *)ST_LSM6DS3_ID,
+	},
+	{
+		.compatible = "st,lsm6dsm",
+		.data = (void *)ST_LSM6DSM_ID,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
+
+static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
+	{ ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+	{ ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
+	{},
+};
+MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
+
+static struct spi_driver st_lsm6dsx_driver = {
+	.driver = {
+		.name = "st_lsm6dsx_spi",
+		.of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
+	},
+	.probe = st_lsm6dsx_spi_probe,
+	.id_table = st_lsm6dsx_spi_id_table,
+};
+module_spi_driver(st_lsm6dsx_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx spi driver");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

^ permalink raw reply related

* [PATCH v4 2/2] Documentation: dt: iio: add st_lsm6dsx sensor device binding
From: Lorenzo Bianconi @ 2017-01-10 21:55 UTC (permalink / raw)
  To: jic23-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, lorenzo.bianconi-qxv4g6HH51o
In-Reply-To: <20170110215519.960-1-lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi-qxv4g6HH51o@public.gmane.org>
---
 .../devicetree/bindings/iio/imu/st_lsm6dsx.txt     | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt

diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
new file mode 100644
index 0000000..ed3cdac
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
@@ -0,0 +1,24 @@
+* ST_LSM6DSx driver for STM 6-axis (acc + gyro) imu Mems sensors
+
+Required properties:
+- compatible: must be one of:
+  "st,lsm6ds3"
+  "st,lsm6dsm"
+- reg: i2c address of the sensor / spi cs line
+
+Optional properties:
+- interrupt-parent: should be the phandle for the interrupt controller
+- interrupts: interrupt mapping for IRQ. It should be configured with
+  flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING.
+
+  Refer to interrupt-controller/interrupts.txt for generic interrupt
+  client node bindings.
+
+Example:
+
+lsm6dsm@6b {
+	compatible = "st,lsm6dsm";
+	reg = <0x6b>;
+	interrupt-parent = <&gpio0>;
+	interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+};
-- 
2.9.3

^ permalink raw reply related

* Re: [PATCH v2 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: Andi Shyti @ 2017-01-10 22:45 UTC (permalink / raw)
  To: kbuild test robot
  Cc: sean.wang-NuS5LvNUpcJWk0Htik3J/w, kbuild-all-JC7UmRfGjtg,
	mchehab-JPH+aEBZ4P+UEJcrhfAQsw, hdegoede-H+wXaHxf7aLQT0dZR+AlfA,
	hkallweit1-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w,
	hverkuil-qWit8jRvyhVmR6Xm/wNWPw, sean-hENCXIMQXOg,
	ivo.g.dimitrov.75-Re5JQEeQqe8AvxtiuMwx3w,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	keyhaede-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <201701102015.fSM15CvI%fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

Hi Sean,

>    include/linux/compiler.h:253:8: sparse: attribute 'no_sanitize_address': unknown attribute
> >> drivers/media/rc/mtk-cir.c:215:41: sparse: too many arguments for function devm_rc_allocate_device
>    drivers/media/rc/mtk-cir.c: In function 'mtk_ir_probe':
>    drivers/media/rc/mtk-cir.c:215:11: error: too many arguments to function 'devm_rc_allocate_device'
>      ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
>               ^~~~~~~~~~~~~~~~~~~~~~~
>    In file included from drivers/media/rc/mtk-cir.c:22:0:
>    include/media/rc-core.h:213:16: note: declared here
>     struct rc_dev *devm_rc_allocate_device(struct device *dev);
>                    ^~~~~~~~~~~~~~~~~~~~~~~
> 
> vim +/devm_rc_allocate_device +215 drivers/media/rc/mtk-cir.c
> 
>    209		ir->base = devm_ioremap_resource(dev, res);
>    210		if (IS_ERR(ir->base)) {
>    211			dev_err(dev, "failed to map registers\n");
>    212			return PTR_ERR(ir->base);
>    213		}
>    214	
>  > 215		ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);

this error comes because the patches I pointed out have not been
applied yet. I guess you can ignore them as long as you tested
yours on top those patches.

Andi
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH linux 2/6] hwmon: occ: Add sysfs interface
From: Edward James @ 2017-01-10 23:01 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: andrew, Benjamin Herrenschmidt, corbet, devicetree, eajames.ibm,
	jdelvare, joel, linux-doc, linux-hwmon, linux-i2c, linux-kernel,
	mark.rutland, robh+dt, wsa
In-Reply-To: <20170110175112.GA13904@roeck-us.net>

[-- Attachment #1: Type: text/plain, Size: 3175 bytes --]



Guenter Roeck <linux@roeck-us.net> wrote on 01/10/2017 11:51:12 AM:

> From: Guenter Roeck <linux@roeck-us.net>
> To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Edward James/Austin/IBM@IBMUS, andrew@aj.id.au, corbet@lwn.net,
> devicetree@vger.kernel.org, eajames.ibm@gmail.com,
> jdelvare@suse.com, joel@jms.id.au, linux-doc@vger.kernel.org, linux-
> hwmon@vger.kernel.org, linux-i2c@vger.kernel.org, linux-
> kernel@vger.kernel.org, mark.rutland@arm.com, robh+dt@kernel.org,
> wsa@the-dreams.de
> Date: 01/10/2017 11:51 AM
> Subject: Re: [PATCH linux 2/6] hwmon: occ: Add sysfs interface
>
> On Tue, Jan 10, 2017 at 11:41:44AM -0600, Benjamin Herrenschmidt wrote:
> > On Sat, 2017-01-07 at 09:15 -0800, Guenter Roeck wrote:
> > > > Instead of the "online" attribute, what do you think about using
the
> > > > "bind"/"unbind" API to probe the device from user space once the
system
> > > > is powered on? All the hwmon registration would take place in the
probe
> > > > function, it would just occur some time after boot.
> > > >
> > >
> > > A more common approach would be to have a platform driver. That
platform
> > > driver would need a means to detect if the OCC is up and running, and
> > > instantiate everything else once it is.
> > >
> > > A trigger from user space is problematic because there is no
guarantee
> > > that the OCC is really up (or that it even exists).
> > >
> > > An alternative might be to have the hwmon driver poll for the OCC,
> > > but that would be a bit more difficult and might require a kernel
thread
> > > or maybe asynchronous probing.
> >
> > Hi Guenter !
> >
> > I'm not sure I agree with you here ;-)
> >
> > I'm don't know how much background you got (I missed the beginning of
> > the discussion) but basically this driver runs on the BMC (system
> > controller) of the POWER9 server, the OCC is inside the POWER9 chip
> > itself.
> >
> > So the presence/power state of the OCC doesn't depend on the BMC
> > platform kernel code. The BMC userspace controls power up and down
> to the POWER9, and thus it's the one to know whether the remote is up.
> >
> > If we were to create a "platform driver", all it would do is get input
> > from userspace exactly like that sysfs file :-)
> >
> > So if you don't like the sysfs file that registers/de-registers, which
> > I sort-of understand, it's a bit of a hack (though a rather efficient
> > one), I think the bind/unbind approach makes sense. However, I wonder
> > whether the simplest and most efficient (remember this BMC has a really
> > slow CPU) is an "online" file sysfs file, though rather than
> > registering/de-registering the hwmon it would simply make it stop
> > accessing the HW (and return some known "offline" values).
> >
>
> I don't like that too much either; it still looks like a hack.
> How about using bind/unbind then ?

Bind/unbind works very well in testing. Only thing we have to figure out is
how to stop the driver loading during BMC boot... but I don't think the
solution will be in this patch set. I'll put together a v2 for tomorrow.

Thanks,
Eddie

>
> Guenter
>

[-- Attachment #2: Type: text/html, Size: 3912 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/4] usb: dwc2: Add binding for AHB burst
From: Christian Lamparter @ 2017-01-10 23:01 UTC (permalink / raw)
  To: John Youn
  Cc: Felipe Balbi, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <e8fa98c7-0dbc-7be7-be54-b2a9114bc289-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>

On Tuesday, January 10, 2017 1:46:56 PM CET John Youn wrote:
> On 12/19/2016 6:49 AM, Christian Lamparter wrote:
> > (Lot's of old stuff, that doesn't matter anymore)

Hello John,
 
> This should be fixed against the latest dwc2 param rework series [1]
> which i hope to get queued for 4.11. If you can give it a test, that
> would be great.

oh Ok. I see you added it to
"[PATCH 16/21] usb: dwc2: Remove platform static params" [0].
Yes, I think this should work nicely. Thank you very much for
your time, even though it's just for like "one old board" :-).

Do you have a public git tree with your patches that I can
clone/checkout?  If not, I'll take some time on the weekend
for this and write back on monday. But yeah, this should 
work.

Regards,
Christian

[0] <https://www.spinics.net/lists/linux-usb/msg151709.html>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets
From: Andy Gross @ 2017-01-10 23:20 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, kishon-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, mark.rutland-5wv7dgnIgG8,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
	srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484045519-19030-5-git-send-email-vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Tue, Jan 10, 2017 at 04:21:59PM +0530, Vivek Gautam wrote:
> Qualcomm SOCs have QMP phy controller that provides support
> to a number of controller, viz. PCIe, UFS, and USB.
> Add a new driver, based on generic phy framework, for this
> phy controller.
> 
> Signed-off-by: Vivek Gautam <vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> Tested-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---

< snip>

> +static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
> +	{
> +		.compatible = "qcom,msm8996-qmp-pcie-phy",
> +		.data = &msm8996_pciephy_cfg,
> +	}, {
> +		.compatible = "qcom,msm8996-qmp-usb3-phy",
> +		.data = &msm8996_usb3phy_cfg,
> +	},

Which other chips would this driver support?


Regards,

Andy Gross
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/4] usb: dwc2: Add binding for AHB burst
From: John Youn @ 2017-01-10 23:23 UTC (permalink / raw)
  To: Christian Lamparter, John Youn
  Cc: Felipe Balbi, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1822229.eVKB2DLXUI@debian64>

On 1/10/2017 3:03 PM, Christian Lamparter wrote:
> On Tuesday, January 10, 2017 1:46:56 PM CET John Youn wrote:
>> On 12/19/2016 6:49 AM, Christian Lamparter wrote:
>>> (Lot's of old stuff, that doesn't matter anymore)
> 
> Hello John,
>  
>> This should be fixed against the latest dwc2 param rework series [1]
>> which i hope to get queued for 4.11. If you can give it a test, that
>> would be great.
> 
> oh Ok. I see you added it to
> "[PATCH 16/21] usb: dwc2: Remove platform static params" [0].
> Yes, I think this should work nicely. Thank you very much for
> your time, even though it's just for like "one old board" :-).

No problem. Sorry for the delay getting the param stuff sorted.

> 
> Do you have a public git tree with your patches that I can
> clone/checkout?  If not, I'll take some time on the weekend
> for this and write back on monday. But yeah, this should 
> work.

Yes check here on branch 'next'

https://github.com/synopsys-usb/linux.git

Regards,
John
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCHv3 3/8] rtc: add STM32 RTC driver
From: Alexandre Belloni @ 2017-01-11  0:08 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Alessandro Zummo, Rob Herring, Mark Rutland, Maxime Coquelin,
	Alexandre Torgue, Russell King, rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Gabriel Fernandez
In-Reply-To: <1483623809-29937-4-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>

Looks good to me, however...


On 05/01/2017 at 14:43:24 +0100, Amelie Delaunay wrote :
> +struct stm32_rtc {
> +	struct rtc_device *rtc_dev;
> +	void __iomem *base;
> +	struct clk *ck_rtc;
> +	spinlock_t lock; /* Protects registers accesses */

This spinlock seems to be useless, the rtc ops_lock is already
protecting everywhere it is taken.

> +	int irq_alarm;
> +};
> +

[...]

> +static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	struct rtc_time *tm = &alrm->time;
> +	unsigned long irqflags;
> +	unsigned int cr, isr, alrmar;
> +	int ret = 0;
> +
> +	if (rtc_valid_tm(tm)) {
> +		dev_err(dev, "Alarm time not valid.\n");
> +		return -EINVAL;

This will never happen, tm is already checked multiple times (up to
three) in the core before this function can be called.

> +	}
> +

You don't need to resend the whole series, just this patch. I'll take
2/8 and 3/8, the other ones can go through the stm32 tree.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* [PATCH] arm64: dts: exynos: Replace small letter of base address/offset on Exynos5433
From: Chanwoo Choi @ 2017-01-11  0:55 UTC (permalink / raw)
  To: kgene, krzk, javier
  Cc: robh+dt, mark.rutland, catalin.marinas, will.deacon, cw00.choi,
	s.nawrocki, m.szyprowski, a.hajda, chanwoo, linux-kernel,
	linux-samsung-soc, devicetree, linux-arm-kernel
In-Reply-To: <CGME20170111005552epcas1p4a1f6ed88022b46544dec4b3801583267@epcas1p4.samsung.com>

This patch replaces the small letter of base address, offset and hex value
with the capital letter to keep the consistency on Exynos5433.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index abaf6b4d599d..d7ed1a68b6fd 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -231,7 +231,7 @@
 		compatible = "arm,psci";
 		method = "smc";
 		cpu_off = <0x84000002>;
-		cpu_on = <0xC4000003>;
+		cpu_on = <0xc4000003>;
 	};
 
 	reboot: syscon-reboot {
@@ -753,7 +753,7 @@
 
 		dsi: dsi@13900000 {
 			compatible = "samsung,exynos5433-mipi-dsi";
-			reg = <0x13900000 0xC0>;
+			reg = <0x13900000 0xc0>;
 			interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
 			phys = <&mipi_phy 1>;
 			phy-names = "dsim";
@@ -880,9 +880,9 @@
 			iommus = <&sysmmu_jpeg>;
 		};
 
-		mfc: codec@152E0000 {
+		mfc: codec@152e0000 {
 			compatible = "samsung,exynos5433-mfc";
-			reg = <0x152E0000 0x10000>;
+			reg = <0x152e0000 0x10000>;
 			interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 			clock-names = "pclk", "aclk", "aclk_xiu";
 			clocks = <&cmu_mfc CLK_PCLK_MFC>,
@@ -914,7 +914,7 @@
 
 		sysmmu_gscl0: sysmmu@13c80000 {
 			compatible = "samsung,exynos-sysmmu";
-			reg = <0x13C80000 0x1000>;
+			reg = <0x13c80000 0x1000>;
 			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
 			clock-names = "aclk", "pclk";
 			clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL0>,
@@ -924,7 +924,7 @@
 
 		sysmmu_gscl1: sysmmu@13c90000 {
 			compatible = "samsung,exynos-sysmmu";
-			reg = <0x13C90000 0x1000>;
+			reg = <0x13c90000 0x1000>;
 			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
 			clock-names = "aclk", "pclk";
 			clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL1>,
@@ -934,7 +934,7 @@
 
 		sysmmu_gscl2: sysmmu@13ca0000 {
 			compatible = "samsung,exynos-sysmmu";
-			reg = <0x13CA0000 0x1000>;
+			reg = <0x13ca0000 0x1000>;
 			interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
 			clock-names = "aclk", "pclk";
 			clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL2>,
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v4 1/2] arm64: dts: rockchip: add "rockchip, grf" property for RK3399 PMUCRU/CRU
From: Xing Zheng @ 2017-01-11  1:04 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Heiko Stübner, open list:ARM/Rockchip SoC..., Rob Herring,
	Mark Rutland, Catalin Marinas, Will Deacon, Caesar Wang,
	Shawn Lin, Brian Norris, Jianqun Xu, Elaine Zhang, David Wu,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAD=FV=Wwu3q_LqwYUWcJQRvp5neVOS9szgsYFONWTRJ0X8hRTA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Hi Doug,

On 2017年01月11日 02:45, Doug Anderson wrote:
> Hi,
>
> On Mon, Jan 9, 2017 at 10:15 PM, Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org> wrote:
>> The structure rockchip_clk_provider needs to refer the GRF regmap
>> in somewhere, if the CRU node has not "rockchip,grf" property,
>> calling syscon_regmap_lookup_by_phandle will return an invalid GRF
>> regmap, and the MUXGRF type clock will be not supported.
>>
>> Therefore, we need to add them.
>>
>> Signed-off-by: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> ---
>>
>> Changes in v4:
>> - separte the binding patch
>>
>> Changes in v3:
>> - add optional roperty rockchip,grf in rockchip,rk3399-cru.txt
>>
>> Changes in v2:
>> - referring pmugrf for PMUGRU
>> - fix the typo "invaild" in COMMIT message
>>
>>   arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 ++
>>   1 file changed, 2 insertions(+)
> This seems fine to me, so:
>
> Reviewed-by: Douglas Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>
> ...but I will say that before you actually add any real "MUXGRF"
> clocks on rk3399 you _might_ need to rework the code to make things
> truly "optional".  If it turns out that any existing clocks that
> already exist today already go through one of these muxes in the GRF
> and we've always been assuming one setting of the mux, we'll need to
> make sure we keep assuming that setting of the mux even if the "grf"
> isn't specified.
>
> As I understand it, your motivation for this patch is to eventually be
> able to model the EDP reference clock which can either be xin24 or
> "edp osc".  Presumably the eDP "reference clock" isn't related to any
> of the pre-existing eDP clocks so that one should be safe.

Hmm... I had intended to use this patch for EDP reference clock, but we 
don't need to change the parent
clock (see the BUG: 61664).

I just woud like to add this patch to avoid getting some unavailable 
MUXGRF clock and need to debug it again,
if we support it one day in future.

Thanks.

-- 
- Xing Zheng


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] arm64: dts: exynos: Replace small letter of base address/offset on Exynos5433
From: Andi Shyti @ 2017-01-11  1:11 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: kgene, krzk, javier, robh+dt, mark.rutland, catalin.marinas,
	will.deacon, s.nawrocki, m.szyprowski, a.hajda, chanwoo,
	linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel
In-Reply-To: <1484096148-17120-1-git-send-email-cw00.choi@samsung.com>

Hi Chanwoo,

> This patch replaces the small letter of base address, offset and hex value
> with the capital letter to keep the consistency on Exynos5433.
> 
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

Reviewed-by: Andi Shyti <andi.shyti@samsung.com>

You will make Krzysztof happy by guessing the correct subject :)

Andi

^ permalink raw reply

* Re: [PATCH v4 1/2] arm64: dts: rockchip: add "rockchip, grf" property for RK3399 PMUCRU/CRU
From: Heiko Stuebner @ 2017-01-11  1:12 UTC (permalink / raw)
  To: Xing Zheng
  Cc: Doug Anderson, open list:ARM/Rockchip SoC..., Rob Herring,
	Mark Rutland, Catalin Marinas, Will Deacon, Caesar Wang,
	Shawn Lin, Brian Norris, Jianqun Xu, Elaine Zhang, David Wu,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <58758498.40309-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Am Mittwoch, 11. Januar 2017, 09:04:24 CET schrieb Xing Zheng:
> Hi Doug,
> 
> On 2017年01月11日 02:45, Doug Anderson wrote:
> > Hi,
> > 
> > On Mon, Jan 9, 2017 at 10:15 PM, Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org> 
wrote:
> >> The structure rockchip_clk_provider needs to refer the GRF regmap
> >> in somewhere, if the CRU node has not "rockchip,grf" property,
> >> calling syscon_regmap_lookup_by_phandle will return an invalid GRF
> >> regmap, and the MUXGRF type clock will be not supported.
> >> 
> >> Therefore, we need to add them.
> >> 
> >> Signed-off-by: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
> >> ---
> >> 
> >> Changes in v4:
> >> - separte the binding patch
> >> 
> >> Changes in v3:
> >> - add optional roperty rockchip,grf in rockchip,rk3399-cru.txt
> >> 
> >> Changes in v2:
> >> - referring pmugrf for PMUGRU
> >> - fix the typo "invaild" in COMMIT message
> >> 
> >>   arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 ++
> >>   1 file changed, 2 insertions(+)
> > 
> > This seems fine to me, so:
> > 
> > Reviewed-by: Douglas Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> > 
> > ...but I will say that before you actually add any real "MUXGRF"
> > clocks on rk3399 you _might_ need to rework the code to make things
> > truly "optional".  If it turns out that any existing clocks that
> > already exist today already go through one of these muxes in the GRF
> > and we've always been assuming one setting of the mux, we'll need to
> > make sure we keep assuming that setting of the mux even if the "grf"
> > isn't specified.
> > 
> > As I understand it, your motivation for this patch is to eventually be
> > able to model the EDP reference clock which can either be xin24 or
> > "edp osc".  Presumably the eDP "reference clock" isn't related to any
> > of the pre-existing eDP clocks so that one should be safe.
> 
> Hmm... I had intended to use this patch for EDP reference clock, but we
> don't need to change the parent
> clock (see the BUG: 61664).

Yep that sounds ok. As I said in my replies, we don't support the edp in the 
mainline kernel yet, so nothing old can break here :-)


> I just woud like to add this patch to avoid getting some unavailable
> MUXGRF clock and need to debug it again,
> if we support it one day in future.

could you just check, if we have any other grf-based muxes that we may need in 
the future. Right now I only see pclkin_isp1_wrapper describing such a mux, 
but it would be cool if you could check again.


Thanks
Heiko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 1/2] arm64: dts: rockchip: add "rockchip, grf" property for RK3399 PMUCRU/CRU
From: Xing Zheng @ 2017-01-11  2:02 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Doug Anderson, open list:ARM/Rockchip SoC..., Rob Herring,
	Mark Rutland, Catalin Marinas, Will Deacon, Caesar Wang,
	Shawn Lin, Brian Norris, Jianqun Xu, Elaine Zhang, David Wu,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1799437.apf7OqdtKq@phil>

Hi Heiko,

On 2017年01月11日 09:12, Heiko Stuebner wrote:
>> I just woud like to add this patch to avoid getting some unavailable
>> MUXGRF clock and need to debug it again,
>> if we support it one day in future.
> could you just check, if we have any other grf-based muxes that we may need in
> the future. Right now I only see pclkin_isp1_wrapper describing such a mux,
> but it would be cool if you could check again.
>
>
OK, we will check these.  :)

Thanks.

-- 
- Xing Zheng

^ permalink raw reply

* Re: [PATCH v4 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets
From: Vivek Gautam @ 2017-01-11  3:36 UTC (permalink / raw)
  To: Andy Gross
  Cc: robh+dt, kishon, linux-kernel, devicetree, mark.rutland, sboyd,
	bjorn.andersson, srinivas.kandagatla, linux-arm-msm
In-Reply-To: <20170110232045.GE5710@hector.attlocal.net>

Hi,


On 01/11/2017 04:50 AM, Andy Gross wrote:
> On Tue, Jan 10, 2017 at 04:21:59PM +0530, Vivek Gautam wrote:
>> Qualcomm SOCs have QMP phy controller that provides support
>> to a number of controller, viz. PCIe, UFS, and USB.
>> Add a new driver, based on generic phy framework, for this
>> phy controller.
>>
>> Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
>> Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
> < snip>
>
>> +static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
>> +	{
>> +		.compatible = "qcom,msm8996-qmp-pcie-phy",
>> +		.data = &msm8996_pciephy_cfg,
>> +	}, {
>> +		.compatible = "qcom,msm8996-qmp-usb3-phy",
>> +		.data = &msm8996_usb3phy_cfg,
>> +	},
> Which other chips would this driver support?

msm8998 has the same combo PHY IP. We may need
minor changes in the initialization tables to support that.


Regards
Vivek

>
>
> Regards,
>
> Andy Gross
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

^ permalink raw reply

* Re: Re: [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU
From: Icenowy Zheng @ 2017-01-11  3:55 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA, linux-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Stephen Boyd,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Linus Walleij,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Chen-Yu Tsai


2017年1月11日 02:10于 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>写道:
>
> On Tue, Jan 03, 2017 at 11:16:26PM +0800, Icenowy Zheng wrote: 
> > V3s has a similar but cut-down CCU to H3. 
> > 
> > Add support for it. 
> > 
> > Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org> 
>
> It looks like there's nothing different but the clocks that you 
> register with the H3, please just use the H3 driver. 

USB gate part is different, and many things have gone.

>
> Thanks! 
> Maxime 
>
> -- 
> Maxime Ripard, Free Electrons 
> Embedded Linux and Kernel engineering 
> http://free-electrons.com 
>
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group. 
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org 
> For more options, visit https://groups.google.com/d/optout. 

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: Re: [PATCH 4/5] ARM: dts: sunxi: add dtsi file for V3s SoC
From: Icenowy Zheng @ 2017-01-11  3:56 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA, linux-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Stephen Boyd,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Linus Walleij,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Chen-Yu Tsai


2017年1月11日 02:21于 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>写道:
>
> On Tue, Jan 03, 2017 at 11:16:28PM +0800, Icenowy Zheng wrote: 
> > + uart0_pins_a: uart0@0 { 
> > + pins = "PB8", "PB9"; 
> > + function = "uart0"; 
> > + bias-pull-up; 
>
> Why do you need a pullup here? 

I think TX needs one, but RX do not need.

>
> Looks good otherwise. 
>
> Thanks! 
> Maxime 
>
> -- 
> Maxime Ripard, Free Electrons 
> Embedded Linux and Kernel engineering 
> http://free-electrons.com 
>
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group. 
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org 
> For more options, visit https://groups.google.com/d/optout. 

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH v7 1/4] drm/exynos: mic: Add mode_set callback function
From: Inki Dae @ 2017-01-11  5:33 UTC (permalink / raw)
  To: Hoegeun Kwon, robh-DgEjT+Ai2ygdnm+yROfE0A,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w, airlied-cv59FeDIM0c,
	kgene-DgEjT+Ai2ygdnm+yROfE0A, krzk-DgEjT+Ai2ygdnm+yROfE0A
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ, cw00.choi-Sze3O3UU22JBDgjK7y7TUQ,
	jh80.chung-Sze3O3UU22JBDgjK7y7TUQ
In-Reply-To: <1483611609-23522-2-git-send-email-hoegeun.kwon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

Applied.

Thanks.

2017년 01월 05일 19:20에 Hoegeun Kwon 이(가) 쓴 글:
> Before applying the patch, used the of_get_videomode function to
> parse the display-timings in the panel which is the child driver
> of dsi in the devicetree. this is wrong. So removed the
> of_get_videomode and fixed to get videomode struct through
> mode_set callback function.
> 
> Signed-off-by: Hoegeun Kwon <hoegeun.kwon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Reviewed-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_mic.c | 19 ++++++++++++-------
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> index a0def0b..fed1a94 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> @@ -286,13 +286,6 @@ static int parse_dt(struct exynos_mic *mic)
>  			}
>  			nodes[j++] = remote_node;
>  
> -			ret = of_get_videomode(remote_node,
> -							&mic->vm, 0);
> -			if (ret) {
> -				DRM_ERROR("mic: failed to get videomode");
> -				goto exit;
> -			}
> -
>  			break;
>  		default:
>  			DRM_ERROR("mic: Unknown endpoint from MIC");
> @@ -329,6 +322,17 @@ static void mic_post_disable(struct drm_bridge *bridge)
>  	mutex_unlock(&mic_mutex);
>  }
>  
> +static void mic_mode_set(struct drm_bridge *bridge,
> +			struct drm_display_mode *mode,
> +			struct drm_display_mode *adjusted_mode)
> +{
> +	struct exynos_mic *mic = bridge->driver_private;
> +
> +	mutex_lock(&mic_mutex);
> +	drm_display_mode_to_videomode(mode, &mic->vm);
> +	mutex_unlock(&mic_mutex);
> +}
> +
>  static void mic_pre_enable(struct drm_bridge *bridge)
>  {
>  	struct exynos_mic *mic = bridge->driver_private;
> @@ -377,6 +381,7 @@ static void mic_enable(struct drm_bridge *bridge) { }
>  static const struct drm_bridge_funcs mic_bridge_funcs = {
>  	.disable = mic_disable,
>  	.post_disable = mic_post_disable,
> +	.mode_set = mic_mode_set,
>  	.pre_enable = mic_pre_enable,
>  	.enable = mic_enable,
>  };
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


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