* Re: [PATCH 3/3] iio: remove iio_triggered_buffer_postenable()/iio_triggered_buffer_predisable()
From: Jonathan Cameron @ 2020-05-24 13:38 UTC (permalink / raw)
To: Alexandru Ardelean
Cc: linus.walleij, Lars-Peter Clausen, alexandre.torgue, linux-iio,
s.hauer, linux-kernel, songqiang1304521, mcoquelin.stm32,
lorenzo.bianconi83, shawnguo, linux-stm32, linux-arm-kernel
In-Reply-To: <20200522104632.517470-3-alexandru.ardelean@analog.com>
On Fri, 22 May 2020 13:46:32 +0300
Alexandru Ardelean <alexandru.ardelean@analog.com> wrote:
> From: Lars-Peter Clausen <lars@metafoo.de>
>
> This patch should be squashed into the first one, as the first one is
> breaking the build (intentionally) to make the IIO core files easier to
> review.
>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Yeah! Didn't realise you'd finally gotten to the end of your mammoth rework
leading to this.
A few really minor things inline to tidy up.
Thanks,
Jonathan
> diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c
> index b5c814ef1637..c87f9a7d2453 100644
> --- a/drivers/iio/accel/st_accel_buffer.c
> +++ b/drivers/iio/accel/st_accel_buffer.c
> @@ -33,13 +33,9 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
> {
> int err;
>
> - err = iio_triggered_buffer_postenable(indio_dev);
> - if (err < 0)
> - return err;
> -
> err = st_sensors_set_axis_enable(indio_dev, indio_dev->active_scan_mask[0]);
> if (err < 0)
> - goto st_accel_buffer_predisable;
> + return err;
>
> err = st_sensors_set_enable(indio_dev, true);
> if (err < 0)
> @@ -49,8 +45,6 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
>
> st_accel_buffer_enable_all_axis:
> st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
> -st_accel_buffer_predisable:
> - iio_triggered_buffer_predisable(indio_dev);
> return err;
> }
>
> @@ -60,12 +54,10 @@ static int st_accel_buffer_predisable(struct iio_dev *indio_dev)
>
> err = st_sensors_set_enable(indio_dev, false);
> if (err < 0)
> - goto st_accel_buffer_predisable;
> -
> - err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
> + return err;
>
> -st_accel_buffer_predisable:
> - err2 = iio_triggered_buffer_predisable(indio_dev);
> + err2 = st_sensors_set_axis_enable(indio_dev,
> + ST_SENSORS_ENABLE_ALL_AXIS);
> if (!err)
I don't think you can get here with err set.
> err = err2;
>
...
> diff --git a/drivers/iio/gyro/st_gyro_buffer.c b/drivers/iio/gyro/st_gyro_buffer.c
> index 9c92ff7a82be..7b86502d5da3 100644
> --- a/drivers/iio/gyro/st_gyro_buffer.c
> +++ b/drivers/iio/gyro/st_gyro_buffer.c
> @@ -33,13 +33,9 @@ static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
> {
> int err;
>
> - err = iio_triggered_buffer_postenable(indio_dev);
> - if (err < 0)
> - return err;
> -
> err = st_sensors_set_axis_enable(indio_dev, indio_dev->active_scan_mask[0]);
> if (err < 0)
> - goto st_gyro_buffer_predisable;
> + return err;
>
> err = st_sensors_set_enable(indio_dev, true);
> if (err < 0)
> @@ -49,8 +45,6 @@ static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
>
> st_gyro_buffer_enable_all_axis:
> st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
> -st_gyro_buffer_predisable:
> - iio_triggered_buffer_predisable(indio_dev);
> return err;
> }
>
> @@ -59,13 +53,8 @@ static int st_gyro_buffer_predisable(struct iio_dev *indio_dev)
> int err, err2;
>
> err = st_sensors_set_enable(indio_dev, false);
> - if (err < 0)
> - goto st_gyro_buffer_predisable;
Previously we didn't bother trying to carry on if this failed. I don't think we
should start doing so now.
> -
> - err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
>
> -st_gyro_buffer_predisable:
> - err2 = iio_triggered_buffer_predisable(indio_dev);
> + err2 = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
> if (!err)
> err = err2;
>
...
> diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
> index 070d4cd0cf54..29d7af33efa1 100644
> --- a/drivers/iio/light/gp2ap020a00f.c
> +++ b/drivers/iio/light/gp2ap020a00f.c
> @@ -1390,12 +1390,6 @@ static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
>
> mutex_lock(&data->lock);
I guess it doesn't matter, but no idea why this was ever under the local lock!
>
> - err = iio_triggered_buffer_postenable(indio_dev);
> - if (err < 0) {
> - mutex_unlock(&data->lock);
> - return err;
> - }
> -
> /*
> * Enable triggers according to the scan_mask. Enabling either
> * LIGHT_CLEAR or LIGHT_IR scan mode results in enabling ALS
> @@ -1430,8 +1424,6 @@ static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
> err = -ENOMEM;
>
> error_unlock:
> - if (err < 0)
> - iio_triggered_buffer_predisable(indio_dev);
> mutex_unlock(&data->lock);
>
> return err;
> @@ -1465,8 +1457,6 @@ static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
> if (err == 0)
> kfree(data->buffer);
>
> - iio_triggered_buffer_predisable(indio_dev);
> -
> mutex_unlock(&data->lock);
>
> return err;
...
> diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
> index 2a4b3d331055..0fee767af026 100644
> --- a/drivers/iio/light/vcnl4000.c
> +++ b/drivers/iio/light/vcnl4000.c
> @@ -957,29 +957,20 @@ static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
> int ret;
> int cmd;
>
> - ret = iio_triggered_buffer_postenable(indio_dev);
> - if (ret)
> - return ret;
> -
> /* Do not enable the buffer if we are already capturing events. */
> - if (vcnl4010_is_in_periodic_mode(data)) {
> - ret = -EBUSY;
> - goto end;
> - }
> + if (vcnl4010_is_in_periodic_mode(data))
> + return -EBUSY;
>
> ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
> VCNL4010_INT_PROX_EN);
> if (ret < 0)
> - goto end;
> + return ret;
>
> cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
> +
> ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd);
> if (ret < 0)
> - goto end;
> -
> - return 0;
> -end:
> - iio_triggered_buffer_predisable(indio_dev);
> + i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
>
> return ret;
> }
> @@ -987,18 +978,14 @@ static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
> static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev)
> {
> struct vcnl4000_data *data = iio_priv(indio_dev);
> - int ret, ret_disable;
> + int ret, ret2;
>
> ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
> - if (ret < 0)
> - goto end;
>
> - ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
> + ret2 = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
hmm. This does change the flow a tiny bit. I wonder if we really
care about carrying on if we get an error on the first write?
We are device not responding territory at that point. Maybe just return
immediately and avoid the dance with the two ret variables?
>
> -end:
> - ret_disable = iio_triggered_buffer_predisable(indio_dev);
> if (ret == 0)
> - ret = ret_disable;
> + ret = ret2;
>
> return ret;
> }
...
> static const struct iio_buffer_setup_ops st_press_buffer_setup_ops = {
> diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
> index 37fe851f89af..e082ad007b22 100644
> --- a/drivers/iio/pressure/zpa2326.c
> +++ b/drivers/iio/pressure/zpa2326.c
> @@ -1240,12 +1240,7 @@ static int zpa2326_preenable_buffer(struct iio_dev *indio_dev)
> static int zpa2326_postenable_buffer(struct iio_dev *indio_dev)
> {
> const struct zpa2326_private *priv = iio_priv(indio_dev);
> - int err;
> -
> - /* Plug our own trigger event handler. */
> - err = iio_triggered_buffer_postenable(indio_dev);
> - if (err)
> - goto err;
> + int err = 0;
>
> if (!priv->waken) {
> /*
> @@ -1254,7 +1249,7 @@ static int zpa2326_postenable_buffer(struct iio_dev *indio_dev)
> */
> err = zpa2326_clear_fifo(indio_dev, 0);
> if (err)
> - goto err_buffer_predisable;
> + goto out;
> }
>
> if (!iio_trigger_using_own(indio_dev) && priv->waken) {
> @@ -1264,14 +1259,10 @@ static int zpa2326_postenable_buffer(struct iio_dev *indio_dev)
> */
> err = zpa2326_config_oneshot(indio_dev, priv->irq);
> if (err)
> - goto err_buffer_predisable;
> + goto out;
> }
>
> - return 0;
> -
> -err_buffer_predisable:
> - iio_triggered_buffer_predisable(indio_dev);
> -err:
> +out:
> zpa2326_err(indio_dev, "failed to enable buffering (%d)", err);
Doesn't this now print the error in the good path?
Probably still want the return 0. It's a bit messier but I'd
just move the prints into the error paths and return directly from
each. Will be cleaner code that this.
>
> return err;
> @@ -1287,7 +1278,6 @@ static int zpa2326_postdisable_buffer(struct iio_dev *indio_dev)
> static const struct iio_buffer_setup_ops zpa2326_buffer_setup_ops = {
> .preenable = zpa2326_preenable_buffer,
> .postenable = zpa2326_postenable_buffer,
> - .predisable = iio_triggered_buffer_predisable,
> .postdisable = zpa2326_postdisable_buffer
> };
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] iio: stm32-dfsdm-adc: keep a reference to the iio device on the state struct
From: Jonathan Cameron @ 2020-05-24 13:13 UTC (permalink / raw)
To: Alexandru Ardelean
Cc: alexandre.torgue, linux-iio, linux-kernel, mcoquelin.stm32,
linux-stm32, linux-arm-kernel
In-Reply-To: <20200522130804.631508-1-alexandru.ardelean@analog.com>
On Fri, 22 May 2020 16:08:04 +0300
Alexandru Ardelean <alexandru.ardelean@analog.com> wrote:
> We may want to get rid of the iio_priv_to_dev() helper. The reason is that
> we will hide some of the members of the iio_dev structure (to prevent
> drivers from accessing them directly), and that will also mean hiding the
> implementation of the iio_priv_to_dev() helper inside the IIO core.
>
> Hiding the implementation of iio_priv_to_dev() implies that some fast-paths
> may not be fast anymore, so a general idea is to try to get rid of the
> iio_priv_to_dev() altogether.
> The iio_priv() helper won't be affected by the rework.
>
> For this driver, not using iio_priv_to_dev(), means keeping a reference to
> the IIO device on the state struct.
>
> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
As this one is a bit simpler, I think the case for just changing the callbacks
to take the iio_dev directly is stronger than adding this level of indirection.
Again, perhaps I'm missing something.
Jonathan
> ---
> drivers/iio/adc/stm32-dfsdm-adc.c | 20 +++++++++++---------
> 1 file changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> index 76a60d93fe23..ff7a6afa4558 100644
> --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> @@ -69,6 +69,7 @@ struct stm32_dfsdm_dev_data {
>
> struct stm32_dfsdm_adc {
> struct stm32_dfsdm *dfsdm;
> + struct iio_dev *indio_dev;
> const struct stm32_dfsdm_dev_data *dev_data;
> unsigned int fl_id;
> unsigned int nconv;
> @@ -332,7 +333,7 @@ static int stm32_dfsdm_compute_all_osrs(struct iio_dev *indio_dev,
>
> static int stm32_dfsdm_start_channel(struct stm32_dfsdm_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> const struct iio_chan_spec *chan;
> unsigned int bit;
> @@ -352,7 +353,7 @@ static int stm32_dfsdm_start_channel(struct stm32_dfsdm_adc *adc)
>
> static void stm32_dfsdm_stop_channel(struct stm32_dfsdm_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> const struct iio_chan_spec *chan;
> unsigned int bit;
> @@ -422,7 +423,7 @@ static int stm32_dfsdm_filter_set_trig(struct stm32_dfsdm_adc *adc,
> unsigned int fl_id,
> struct iio_trigger *trig)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> u32 jextsel = 0, jexten = STM32_DFSDM_JEXTEN_DISABLED;
> int ret;
> @@ -451,7 +452,7 @@ static int stm32_dfsdm_channels_configure(struct stm32_dfsdm_adc *adc,
> unsigned int fl_id,
> struct iio_trigger *trig)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id];
> struct stm32_dfsdm_filter_osr *flo = &fl->flo[0];
> @@ -495,7 +496,7 @@ static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc,
> unsigned int fl_id,
> struct iio_trigger *trig)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id];
> struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast];
> @@ -1314,7 +1315,7 @@ static const struct iio_info stm32_dfsdm_info_adc = {
> static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> {
> struct stm32_dfsdm_adc *adc = arg;
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> struct regmap *regmap = adc->dfsdm->regmap;
> unsigned int status, int_en;
>
> @@ -1569,6 +1570,7 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
>
> adc = iio_priv(iio);
> adc->dfsdm = dev_get_drvdata(dev->parent);
> + adc->indio_dev = iio;
>
> iio->dev.parent = dev;
> iio->dev.of_node = np;
> @@ -1651,7 +1653,7 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
> static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
> {
> struct stm32_dfsdm_adc *adc = platform_get_drvdata(pdev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
>
> if (adc->dev_data->type == DFSDM_AUDIO)
> of_platform_depopulate(&pdev->dev);
> @@ -1664,7 +1666,7 @@ static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
> static int __maybe_unused stm32_dfsdm_adc_suspend(struct device *dev)
> {
> struct stm32_dfsdm_adc *adc = dev_get_drvdata(dev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
>
> if (iio_buffer_enabled(indio_dev))
> __stm32_dfsdm_predisable(indio_dev);
> @@ -1675,7 +1677,7 @@ static int __maybe_unused stm32_dfsdm_adc_suspend(struct device *dev)
> static int __maybe_unused stm32_dfsdm_adc_resume(struct device *dev)
> {
> struct stm32_dfsdm_adc *adc = dev_get_drvdata(dev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> const struct iio_chan_spec *chan;
> struct stm32_dfsdm_channel *ch;
> int i, ret;
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] iio: stm32-adc: keep a reference to the iio device on the state struct
From: Jonathan Cameron @ 2020-05-24 13:09 UTC (permalink / raw)
To: Alexandru Ardelean
Cc: alexandre.torgue, linux-iio, linux-kernel, mcoquelin.stm32,
linux-stm32, linux-arm-kernel
In-Reply-To: <20200522130719.630714-1-alexandru.ardelean@analog.com>
On Fri, 22 May 2020 16:07:19 +0300
Alexandru Ardelean <alexandru.ardelean@analog.com> wrote:
> We may want to get rid of the iio_priv_to_dev() helper. The reason is that
> we will hide some of the members of the iio_dev structure (to prevent
> drivers from accessing them directly), and that will also mean hiding the
> implementation of the iio_priv_to_dev() helper inside the IIO core.
>
> Hiding the implementation of iio_priv_to_dev() implies that some fast-paths
> may not be fast anymore, so a general idea is to try to get rid of the
> iio_priv_to_dev() altogether.
> The iio_priv() helper won't be affected by the rework.
>
> For this driver, not using iio_priv_to_dev(), means keeping a reference to
> the IIO device on the state struct.
>
> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
I don't particularly mind this approach, but an alternative would be to
change the callbacks to take an iio_dev rather than the iio_priv()
structure. It's more invasive though as need to change what is
provided via dev_get_drvdata for the adc device.
It's possible I missed a path where this won't work for some reason though.
Up to the driver maintainers on which one they prefer.
Thanks,
Jonathan
> ---
> drivers/iio/adc/stm32-adc.c | 27 +++++++++++++++------------
> 1 file changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index ae622ee6d08c..7e58c4443e3f 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -171,6 +171,7 @@ struct stm32_adc_cfg {
>
> /**
> * struct stm32_adc - private data of each ADC IIO instance
> + * @indio_dev: back-reference to the IIO device object
> * @common: reference to ADC block common data
> * @offset: ADC instance register offset in ADC block
> * @cfg: compatible configuration data
> @@ -194,6 +195,7 @@ struct stm32_adc_cfg {
> * @chan_name: channel name array
> */
> struct stm32_adc {
> + struct iio_dev *indio_dev;
> struct stm32_adc_common *common;
> u32 offset;
> const struct stm32_adc_cfg *cfg;
> @@ -637,7 +639,7 @@ static void stm32h7_adc_start_conv(struct stm32_adc *adc, bool dma)
>
> static void stm32h7_adc_stop_conv(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
> u32 val;
>
> @@ -654,7 +656,7 @@ static void stm32h7_adc_stop_conv(struct stm32_adc *adc)
>
> static int stm32h7_adc_exit_pwr_down(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
> u32 val;
>
> @@ -692,7 +694,7 @@ static void stm32h7_adc_enter_pwr_down(struct stm32_adc *adc)
>
> static int stm32h7_adc_enable(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
> u32 val;
>
> @@ -715,7 +717,7 @@ static int stm32h7_adc_enable(struct stm32_adc *adc)
>
> static void stm32h7_adc_disable(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
> u32 val;
>
> @@ -735,7 +737,7 @@ static void stm32h7_adc_disable(struct stm32_adc *adc)
> */
> static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int i, ret;
> u32 lincalrdyw_mask, val;
>
> @@ -779,7 +781,7 @@ static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc)
> */
> static int stm32h7_adc_restore_selfcalib(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int i, ret;
> u32 lincalrdyw_mask, val;
>
> @@ -852,7 +854,7 @@ static int stm32h7_adc_restore_selfcalib(struct stm32_adc *adc)
> */
> static int stm32h7_adc_selfcalib(struct stm32_adc *adc)
> {
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
> u32 val;
>
> @@ -1228,7 +1230,7 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
> static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
> {
> struct stm32_adc *adc = data;
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> const struct stm32_adc_regspec *regs = adc->cfg->regs;
> u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
>
> @@ -1241,7 +1243,7 @@ static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
> static irqreturn_t stm32_adc_isr(int irq, void *data)
> {
> struct stm32_adc *adc = data;
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> const struct stm32_adc_regspec *regs = adc->cfg->regs;
> u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
>
> @@ -1879,6 +1881,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> adc = iio_priv(indio_dev);
> + adc->indio_dev = indio_dev;
> adc->common = dev_get_drvdata(pdev->dev.parent);
> spin_lock_init(&adc->lock);
> init_completion(&adc->completion);
> @@ -1990,7 +1993,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
> static int stm32_adc_remove(struct platform_device *pdev)
> {
> struct stm32_adc *adc = platform_get_drvdata(pdev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
>
> pm_runtime_get_sync(&pdev->dev);
> iio_device_unregister(indio_dev);
> @@ -2013,7 +2016,7 @@ static int stm32_adc_remove(struct platform_device *pdev)
> static int stm32_adc_suspend(struct device *dev)
> {
> struct stm32_adc *adc = dev_get_drvdata(dev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
>
> if (iio_buffer_enabled(indio_dev))
> __stm32_adc_buffer_predisable(indio_dev);
> @@ -2024,7 +2027,7 @@ static int stm32_adc_suspend(struct device *dev)
> static int stm32_adc_resume(struct device *dev)
> {
> struct stm32_adc *adc = dev_get_drvdata(dev);
> - struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> + struct iio_dev *indio_dev = adc->indio_dev;
> int ret;
>
> ret = pm_runtime_force_resume(dev);
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: KASAN: use-after-free Read in uif_close
From: Arnd Bergmann @ 2020-05-24 11:14 UTC (permalink / raw)
To: Richard Weinberger
Cc: syzbot, Vignesh Raghavendra, festevam, Sascha Hauer,
Miquel Raynal, syzkaller-bugs, linux-kernel, Oleksij Rempel,
linux-mtd, linux-imx, kernel, Greg Kroah-Hartman, shawnguo,
daniel baluta, linux-arm-kernel
In-Reply-To: <768166145.263589.1590307748272.JavaMail.zimbra@nod.at>
On Sun, May 24, 2020 at 10:09 AM Richard Weinberger <richard@nod.at> wrote:
>
> ----- Ursprüngliche Mail -----
> > Von: "syzbot" <syzbot+0ce97ea45b008ba3b8bd@syzkaller.appspotmail.com>
> > An: "Arnd Bergmann" <arnd@arndb.de>, "daniel baluta" <daniel.baluta@nxp.com>, "festevam" <festevam@gmail.com>, "Greg
> > Kroah-Hartman" <gregkh@linuxfoundation.org>, "kernel" <kernel@pengutronix.de>, "linux-arm-kernel"
> > <linux-arm-kernel@lists.infradead.org>, "linux-imx" <linux-imx@nxp.com>, "linux-kernel" <linux-kernel@vger.kernel.org>,
> > "linux-mtd" <linux-mtd@lists.infradead.org>, linux@rempel-privat.de, "Miquel Raynal" <miquel.raynal@bootlin.com>,
> > "richard" <richard@nod.at>, "Sascha Hauer" <s.hauer@pengutronix.de>, "shawnguo" <shawnguo@kernel.org>,
> > syzkaller-bugs@googlegroups.com, "Vignesh Raghavendra" <vigneshr@ti.com>
> > Gesendet: Sonntag, 24. Mai 2020 08:03:03
> > Betreff: Re: KASAN: use-after-free Read in uif_close
>
> > syzbot has bisected this bug to:
> >
> > commit 32ec783ae19d48084b893cc54747fed37b07eb0c
> > Author: Arnd Bergmann <arnd@arndb.de>
> > Date: Wed Apr 8 19:02:57 2020 +0000
> >
> > firmware: imx: fix compile-testing
>
> Hmm, from a quick check I don't see how this is related.
> Arnd?
I suppose this was a randconfig build for a configuration that did not build
until I fixed the build stage, and then it failed at runtime, so the bug would
have been in earlier releases as well, it was just not observed.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH v2 1/3] printk: Add function to set console to preferred console's driver
From: Daniel Vetter @ 2020-05-24 10:01 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Petr Mladek, Arvind Sankar, Benjamin Herrenschmidt,
Greg Kroah-Hartman, Linux Kernel Mailing List, Steven Rostedt,
Alper Nebi Yasak, linux-serial, Jiri Slaby, Andrew Morton,
Andy Shevchenko, Feng Tang, David S. Miller, Linux ARM
In-Reply-To: <20200513053529.GL413@jagdpanzerIV.localdomain>
On Wed, May 13, 2020 at 7:35 AM Sergey Senozhatsky
<sergey.senozhatsky@gmail.com> wrote:
>
> On (20/04/30 19:14), Alper Nebi Yasak wrote:
> [..]
> > +int update_console_to_preferred(void)
> > +{
> > + struct console_cmdline *c = NULL;
> > + struct console *con = NULL;
> > + struct console *tmp = NULL;
> > +
> > + if (preferred_console >= 0)
> > + c = &console_cmdline[preferred_console];
> > +
> > + if (!c || !c->name[0])
> > + return 0;
> > +
> > + for_each_console(con) {
> > + if (!con->next || !(con->next->flags & CON_ENABLED))
> > + continue;
> > + if (strcmp(c->name, con->next->name) != 0)
> > + continue;
>
> This matches the consoles by exact name. Consoles can have aliases,
> but matching by alias is rather complex and it has some side effects.
>
> Let me Cc more people on this. VT has a console takeover logic,
> I wonder if we can extend the takeover code somehow.
>
> Daniel, any thoughts?
Apologies for late reply, but nope, no thoughts. I have some ideas for
the locking in the console subsystem, but that's just to untangle it
from gpu drivers as much as possible. Otherwise I'm trying to stay
away from it as far as I can :-)
Cheers, Daniel
>
> https://lore.kernel.org/lkml/20200430161438.17640-1-alpernebiyasak@gmail.com
>
> -ss
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v13 1/3] dt-bindings: i2c: npcm7xx: add NPCM I2C controller
From: Tali Perry @ 2020-05-24 8:35 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree, Benjamin Fair, kfting, Avi Fishman, Patrick Venture,
OpenBMC Maillist, Wolfram Sang, Brendan Higgins,
linux-kernel@vger.kernel.org, Ofer Yehielli, Nancy Yuen,
Linux I2C, Andy Shevchenko,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Tomer Maimon
In-Reply-To: <CAL_JsqLKaWkSs8vMB4+kBL+AzAU6A4KCVJRNFtvmYfATKR1H=w@mail.gmail.com>
Hi Rob,
On Sat, May 23, 2020 at 1:47 AM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Fri, May 22, 2020 at 4:42 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Fri, 22 May 2020 14:33:10 +0300, Tali Perry wrote:
> > > Added device tree binding documentation for Nuvoton BMC
> > > NPCM I2C controller.
> > >
> > > Signed-off-by: Tali Perry <tali.perry1@gmail.com>
> > > ---
> > > .../bindings/i2c/nuvoton,npcm7xx-i2c.yaml | 60 +++++++++++++++++++
> > > 1 file changed, 60 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml
> > >
> >
> >
> > My bot found errors running 'make dt_binding_check' on your patch:
> >
> > Error: Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dts:22.28-29 syntax error
> > FATAL ERROR: Unable to parse input tree
> > scripts/Makefile.lib:312: recipe for target 'Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dt.yaml' failed
> > make[1]: *** [Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dt.yaml] Error 1
> > make[1]: *** Waiting for unfinished jobs....
> > Makefile:1300: recipe for target 'dt_binding_check' failed
> > make: *** [dt_binding_check] Error 2
> >
> > See https://patchwork.ozlabs.org/patch/1296162
> >
> > If you already ran 'make dt_binding_check' and didn't see the above
> > error(s), then make sure dt-schema is up to date:
> >
> > pip3 install git+https://github.com/devicetree-org/dt-schema.git@master --upgrade
> >
> > Please check and re-submit.
>
> Why do you keep sending new versions with the same problem? It won't
> get reviewed until this is fixed. This isn't a free automated service
> to throw things at to see if they work. I have to review the failures.
>
> Rob
Definitely not trying to use the Bot to check my yaml. On the first
version the dt-check was not updated on my side.
On the previous version I updated according to the bot explanations.
Found an error and fixed it. Now I don't see any errors. with latest
dt-check.
I did:
pip3 install git+https://github.com/devicetree-org/dt-schema.git@master
--upgrade
make dt_binding_check
And got a clean log, no warnings or errors. Was I suppose to check
anything else?
Thanks,
Tali
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: KASAN: use-after-free Read in uif_close
From: Richard Weinberger @ 2020-05-24 8:09 UTC (permalink / raw)
To: syzbot
Cc: Vignesh Raghavendra, Arnd Bergmann, daniel baluta, Sascha Hauer,
Miquel Raynal, syzkaller-bugs, linux-kernel, linux, linux-mtd,
linux-imx, kernel, Greg Kroah-Hartman, shawnguo, festevam,
linux-arm-kernel
In-Reply-To: <000000000000861e3305a65e9d74@google.com>
----- Ursprüngliche Mail -----
> Von: "syzbot" <syzbot+0ce97ea45b008ba3b8bd@syzkaller.appspotmail.com>
> An: "Arnd Bergmann" <arnd@arndb.de>, "daniel baluta" <daniel.baluta@nxp.com>, "festevam" <festevam@gmail.com>, "Greg
> Kroah-Hartman" <gregkh@linuxfoundation.org>, "kernel" <kernel@pengutronix.de>, "linux-arm-kernel"
> <linux-arm-kernel@lists.infradead.org>, "linux-imx" <linux-imx@nxp.com>, "linux-kernel" <linux-kernel@vger.kernel.org>,
> "linux-mtd" <linux-mtd@lists.infradead.org>, linux@rempel-privat.de, "Miquel Raynal" <miquel.raynal@bootlin.com>,
> "richard" <richard@nod.at>, "Sascha Hauer" <s.hauer@pengutronix.de>, "shawnguo" <shawnguo@kernel.org>,
> syzkaller-bugs@googlegroups.com, "Vignesh Raghavendra" <vigneshr@ti.com>
> Gesendet: Sonntag, 24. Mai 2020 08:03:03
> Betreff: Re: KASAN: use-after-free Read in uif_close
> syzbot has bisected this bug to:
>
> commit 32ec783ae19d48084b893cc54747fed37b07eb0c
> Author: Arnd Bergmann <arnd@arndb.de>
> Date: Wed Apr 8 19:02:57 2020 +0000
>
> firmware: imx: fix compile-testing
Hmm, from a quick check I don't see how this is related.
Arnd?
Thanks,
//richard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/7] Record the mm_struct in the page table pages
From: Mike Rapoport @ 2020-05-24 7:42 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Catalin Marinas, linux-kernel, Russell King, linux-mm, linux-m68k,
Geert Uytterhoeven, Kirill A. Shutemov, Will Deacon,
linux-arm-kernel
In-Reply-To: <20200429015126.GP29705@bombadil.infradead.org>
On Tue, Apr 28, 2020 at 06:51:26PM -0700, Matthew Wilcox wrote:
> On Wed, Apr 29, 2020 at 03:26:24AM +0300, Kirill A. Shutemov wrote:
> > On Tue, Apr 28, 2020 at 12:44:42PM -0700, Matthew Wilcox wrote:
> > > From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> > >
> > > Pages which are in use as page tables have some space unused in struct
> > > page. It would be handy to have a pointer to the struct mm_struct that
> > > they belong to so that we can handle uncorrectable errors in page tables
> > > more gracefully. There are a few other things we could use it for too,
> > > such as checking that the page table entry actually belongs to the task
> > > we think it ought to. This patch series does none of that, but does
> > > lay the groundwork for it.
> > >
> > > Matthew Wilcox (Oracle) (7):
> >
> > How does it work for kernel side of virtual address space?
>
> init_mm
A note to keep in mind is that most of the kernel page tables are seen
as PG_reserved rather than PageTable().
> > And your employer may be interested in semantics around
> > CONFIG_ARCH_WANT_HUGE_PMD_SHARE :P
>
> I was thinking about that. Right now, it's only useful for debugging
> purposes (as you point out in a later email). I think it's OK if shared
> PMDs aren't supported as well as regular PTEs, just because there are
> so few of them that uncorrectable errors are less likely to strike in
> those pages.
>
--
Sincerely yours,
Mike.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: arm64: Register modification during syscall entry/exit stop
From: Keno Fischer @ 2020-05-24 6:56 UTC (permalink / raw)
To: Will Deacon
Cc: Catalin Marinas, Kyle Huey, Oleg Nesterov, linux-arm-kernel,
Linux Kernel Mailing List
In-Reply-To: <CABV8kRzjCCsjVeRsBD7U_Lo0==sBw9EKm=1z7g=60KyJvJLZBQ@mail.gmail.com>
Just ran into this issue again, with what I think may be most compelling
example yet why this is problematic:
The tracee incurred a signal, we PTRACE_SYSEMU'd to the rt_sigreturn,
which the tracer tried to emulate by applying the state from the signal frame.
However, the PTRACE_SYSEMU stop is a syscall-stop, so the tracer's write
to x7 was ignored and x7 retained the value it had in the signal handler,
which broke the tracee.
Keno
On Sat, May 23, 2020 at 1:35 AM Keno Fischer <keno@juliacomputing.com> wrote:
>
> I got bitten by this again, so I decided to write up a simple example
> that shows the problem:
>
> https://gist.github.com/Keno/cde691b26e32373307fb7449ad305739
>
> This runs the same child twice. First vanilla where it prints "Hello world".
> The second time, using a textbook ptrace example, to only print "world".
> The problem here is that by the time the ptracer gets around to restoring
> the registers, it's no longer in a syscall stop, so the write to x7 does not
> get ignored and the correct value of x7 gets clobbered.
> I copied the syscall definition from musl, so the compiler thinks x7 is
> live, and we can see an assertion.
>
> Output on my machine (will depend on compiler version, etc.):
> ```
> $ gcc -g3 -O3 ptrace_lies.c
> $ ./a.out
> Hello World
> World
> a.out: ptrace_lies.c:49: do_child: Assertion `v3 == values[2]' failed.
> a.out: ptrace_lies.c:134: main: Assertion `WIFEXITED(status) &&
> WEXITSTATUS(status) == 0' failed.
> Aborted (core dumped)
> ```
>
> However, I don't think that whether or not the compiler thinks that x7 is
> live is the problem here. The problem is entirely that this mechanism
> prevents the ptracer from precisely controlling the register state. While
> basic ptracers don't need this feature (strace),
> more advanced ptracers (think criu, etc.) absolutely do want to precisely
> control what the register state is.
> The ptracer I'm working on (https://rr-project.org/)
> happens to be an extreme case of this, where it wants *bitwise* equivalent
> register states such that it can run the same code many times and get
> the exact same results.
>
> Also, if the issue was just that the kernel clobbered x7, that would be fine
> we could deal with that no problem. However, it's much worse than that,
> because the behavior of the kernel with respect to x7 depends on what
> kind of ptrace stop we're in and even worse, in some kinds of stop,
> there's absolutely no way to get at the actual value of x7.
>
> > Hmm, does that actually result in the SVC instruction getting inlined? I
> > think that's quite dangerous, since we document that we can trash the SVE
> > register state on a system call, for example. I'm also surprised that
> > the register variables are honoured by compilers if that inlining can occur.
>
> I haven't gotten to trying SVE yet, so I appreciate the warning :). That said,
> deterministic clobbering of registers is fine. Even changing the registers to
> random junk is fine. We're happy to read those registers through ptrace.
> The problem here is that the kernel lies about what the contents of the x7
> register is and discards any writes to it.
>
> I really hope we can come up with a solution here, I'm already dreading
> the next time I unexpectedly run into this and have to add yet
> another special case :(.
>
> Keno
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: KASAN: use-after-free Read in uif_close
From: syzbot @ 2020-05-24 6:03 UTC (permalink / raw)
To: arnd, daniel.baluta, festevam, gregkh, kernel, linux-arm-kernel,
linux-imx, linux-kernel, linux-mtd, linux, miquel.raynal, richard,
s.hauer, shawnguo, syzkaller-bugs, vigneshr
In-Reply-To: <000000000000ba47b705a6443a0d@google.com>
syzbot has bisected this bug to:
commit 32ec783ae19d48084b893cc54747fed37b07eb0c
Author: Arnd Bergmann <arnd@arndb.de>
Date: Wed Apr 8 19:02:57 2020 +0000
firmware: imx: fix compile-testing
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=15b22972100000
start commit: c11d28ab Add linux-next specific files for 20200522
git tree: linux-next
final crash: https://syzkaller.appspot.com/x/report.txt?x=17b22972100000
console output: https://syzkaller.appspot.com/x/log.txt?x=13b22972100000
kernel config: https://syzkaller.appspot.com/x/.config?x=3f6dbdea4159fb66
dashboard link: https://syzkaller.appspot.com/bug?extid=0ce97ea45b008ba3b8bd
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=14b23f06100000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=111b0172100000
Reported-by: syzbot+0ce97ea45b008ba3b8bd@syzkaller.appspotmail.com
Fixes: 32ec783ae19d ("firmware: imx: fix compile-testing")
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] dmaengine: stm32-dmamux: Fix runtime PM imbalance on error
From: Dinghao Liu @ 2020-05-24 6:02 UTC (permalink / raw)
To: dinghao.liu, kjlu
Cc: Alexandre Torgue, linux-kernel, Vinod Koul, Maxime Coquelin,
dmaengine, Dan Williams, linux-stm32, linux-arm-kernel
In stm32_dmamux_route_allocate(), pm_runtime_get_sync() increments
the runtime PM usage counter even when it returns an error code.
Thus a pairing decrement is needed on the error handling path to
keep the counter balanced.
In stm32_dmamux_probe(), when platform_get_resource() returns an
error code, a pairing runtime PM usage counter decrement is needed
to keep the counter balanced. For error paths after this call,
things are the same.
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
---
drivers/dma/stm32-dmamux.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index 12f7637e13a1..e68e7078ff94 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -139,6 +139,7 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
spin_lock_irqsave(&dmamux->lock, flags);
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
+ pm_runtime_put_noidle(&pdev->dev);
spin_unlock_irqrestore(&dmamux->lock, flags);
goto error;
}
@@ -246,8 +247,10 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iomem = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(iomem))
+ if (IS_ERR(iomem)) {
+ pm_runtime_put_noidle(&pdev->dev);
return PTR_ERR(iomem);
+ }
spin_lock_init(&stm32_dmamux->lock);
@@ -256,12 +259,14 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
ret = PTR_ERR(stm32_dmamux->clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Missing clock controller\n");
+ pm_runtime_put_noidle(&pdev->dev);
return ret;
}
ret = clk_prepare_enable(stm32_dmamux->clk);
if (ret < 0) {
dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret);
+ pm_runtime_put_noidle(&pdev->dev);
return ret;
}
@@ -300,6 +305,7 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
return 0;
err_clk:
+ pm_runtime_put_noidle(&pdev->dev);
clk_disable_unprepare(stm32_dmamux->clk);
return ret;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v7 4/4] gpio: xilinx: Utilize for_each_set_clump macro
From: Syed Nayyar Waris @ 2020-05-24 5:06 UTC (permalink / raw)
To: linus.walleij, akpm
Cc: linux-gpio, linux-kernel, vilhelm.gray, michal.simek,
bgolaszewski, andriy.shevchenko, linux-arm-kernel
In-Reply-To: <cover.1590017578.git.syednwaris@gmail.com>
This patch reimplements the xgpio_set_multiple function in
drivers/gpio/gpio-xilinx.c to use the new for_each_set_clump macro.
Instead of looping for each bit in xgpio_set_multiple
function, now we can check each channel at a time and save cycles.
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
---
Changes in v7:
- No change.
Changes in v6:
- No change.
Changes in v5:
- Minor change: Inline values '32' and '64' in code for better
code readability.
Changes in v4:
- Minor change: Inline values '32' and '64' in code for better
code readability.
Changes in v3:
- No change.
Changes in v2:
- No change.
drivers/gpio/gpio-xilinx.c | 62 ++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 30 deletions(-)
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 67f9f82e0db0..e81092dea27e 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -136,39 +136,41 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
unsigned long *bits)
{
- unsigned long flags;
+ unsigned long flags[2];
struct xgpio_instance *chip = gpiochip_get_data(gc);
- int index = xgpio_index(chip, 0);
- int offset, i;
-
- spin_lock_irqsave(&chip->gpio_lock[index], flags);
-
- /* Write to GPIO signals */
- for (i = 0; i < gc->ngpio; i++) {
- if (*mask == 0)
- break;
- /* Once finished with an index write it out to the register */
- if (index != xgpio_index(chip, i)) {
- xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
- index * XGPIO_CHANNEL_OFFSET,
- chip->gpio_state[index]);
- spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
- index = xgpio_index(chip, i);
- spin_lock_irqsave(&chip->gpio_lock[index], flags);
- }
- if (__test_and_clear_bit(i, mask)) {
- offset = xgpio_offset(chip, i);
- if (test_bit(i, bits))
- chip->gpio_state[index] |= BIT(offset);
- else
- chip->gpio_state[index] &= ~BIT(offset);
- }
+ u32 *const state = chip->gpio_state;
+ unsigned int *const width = chip->gpio_width;
+ unsigned long offset, clump;
+ size_t index;
+
+ DECLARE_BITMAP(old, 64);
+ DECLARE_BITMAP(new, 64);
+ DECLARE_BITMAP(changed, 64);
+
+ spin_lock_irqsave(&chip->gpio_lock[0], flags[0]);
+ spin_lock_irqsave(&chip->gpio_lock[1], flags[1]);
+
+ bitmap_set_value(old, state[0], 0, width[0]);
+ bitmap_set_value(old, state[1], width[0], width[1]);
+ bitmap_replace(new, old, bits, mask, gc->ngpio);
+
+ bitmap_set_value(old, state[0], 0, 32);
+ bitmap_set_value(old, state[1], 32, 32);
+ state[0] = bitmap_get_value(new, 0, width[0]);
+ state[1] = bitmap_get_value(new, width[0], width[1]);
+ bitmap_set_value(new, state[0], 0, 32);
+ bitmap_set_value(new, state[1], 32, 32);
+ bitmap_xor(changed, old, new, 64);
+
+ for_each_set_clump(offset, clump, changed, 64, 32) {
+ index = offset / 32;
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
+ index * XGPIO_CHANNEL_OFFSET,
+ state[index]);
}
- xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
- index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
-
- spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
+ spin_unlock_irqrestore(&chip->gpio_lock[1], flags[1]);
+ spin_unlock_irqrestore(&chip->gpio_lock[0], flags[0]);
}
/**
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH V3] thermal: imx: Add missing of_node_put()
From: Daniel Lezcano @ 2020-05-24 5:05 UTC (permalink / raw)
To: Anson Huang, rui.zhang@intel.com, amit.kucheria@verdurent.com,
shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com,
linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: dl-linux-imx
In-Reply-To: <DB3PR0402MB391639FE30CD00F3371A0763F5B20@DB3PR0402MB3916.eurprd04.prod.outlook.com>
On 24/05/2020 05:26, Anson Huang wrote:
> Gentle ping...
It is applied, sorry for not letting you know.
>> Subject: [PATCH V3] thermal: imx: Add missing of_node_put()
>>
>> After finishing using cpu node got from of_get_cpu_node(), of_node_put()
>> needs to be called, the cpufreq policy also needs to be put unconditionally.
>>
>> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
>> ---
>> Changes since V2:
>> - call cpufreq_cpu_put() unconditionally after cooling register done.
>> ---
>> drivers/thermal/imx_thermal.c | 13 ++++++-------
>> 1 file changed, 6 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
>> index e761c9b..8764cb5 100644
>> --- a/drivers/thermal/imx_thermal.c
>> +++ b/drivers/thermal/imx_thermal.c
>> @@ -649,7 +649,7 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
>> static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
>> {
>> struct device_node *np;
>> - int ret;
>> + int ret = 0;
>>
>> data->policy = cpufreq_cpu_get(0);
>> if (!data->policy) {
>> @@ -661,20 +661,19 @@ static int
>> imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
>>
>> if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
>> data->cdev = cpufreq_cooling_register(data->policy);
>> - if (IS_ERR(data->cdev)) {
>> + if (IS_ERR(data->cdev))
>> ret = PTR_ERR(data->cdev);
>> - cpufreq_cpu_put(data->policy);
>> - return ret;
>> - }
>> }
>>
>> - return 0;
>> + cpufreq_cpu_put(data->policy);
>> + of_node_put(np);
>> +
>> + return ret;
>> }
>>
>> static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data
>> *data) {
>> cpufreq_cooling_unregister(data->cdev);
>> - cpufreq_cpu_put(data->policy);
>> }
>>
>> #else
>> --
>> 2.7.4
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v7 0/4] Introduce the for_each_set_clump macro
From: Syed Nayyar Waris @ 2020-05-24 5:00 UTC (permalink / raw)
To: linus.walleij, akpm
Cc: linux-arch, amit.kucheria, arnd, yamada.masahiro, linux-kernel,
linus.walleij, daniel.lezcano, vilhelm.gray, michal.simek,
bgolaszewski, rrichter, linux-gpio, linux-pm, rui.zhang,
andriy.shevchenko, linux-arm-kernel
Hello Linus,
Since this patchset primarily affects GPIO drivers, would you like
to pick it up through your GPIO tree?
This patchset introduces a new generic version of for_each_set_clump.
The previous version of for_each_set_clump8 used a fixed size 8-bit
clump, but the new generic version can work with clump of any size but
less than or equal to BITS_PER_LONG. The patchset utilizes the new macro
in several GPIO drivers.
The earlier 8-bit for_each_set_clump8 facilitated a
for-loop syntax that iterates over a memory region entire groups of set
bits at a time.
For example, suppose you would like to iterate over a 32-bit integer 8
bits at a time, skipping over 8-bit groups with no set bit, where
XXXXXXXX represents the current 8-bit group:
Example: 10111110 00000000 11111111 00110011
First loop: 10111110 00000000 11111111 XXXXXXXX
Second loop: 10111110 00000000 XXXXXXXX 00110011
Third loop: XXXXXXXX 00000000 11111111 00110011
Each iteration of the loop returns the next 8-bit group that has at
least one set bit.
But with the new for_each_set_clump the clump size can be different from 8 bits.
Moreover, the clump can be split at word boundary in situations where word
size is not multiple of clump size. Following are examples showing the working
of new macro for clump sizes of 24 bits and 6 bits.
Example 1:
clump size: 24 bits, Number of clumps (or ports): 10
bitmap stores the bit information from where successive clumps are retrieved.
/* bitmap memory region */
0x00aa0000ff000000; /* Most significant bits */
0xaaaaaa0000ff0000;
0x000000aa000000aa;
0xbbbbabcdeffedcba; /* Least significant bits */
Different iterations of for_each_set_clump:-
'offset' is the bit position and 'clump' is the 24 bit clump from the
above bitmap.
Iteration first: offset: 0 clump: 0xfedcba
Iteration second: offset: 24 clump: 0xabcdef
Iteration third: offset: 48 clump: 0xaabbbb
Iteration fourth: offset: 96 clump: 0xaa
Iteration fifth: offset: 144 clump: 0xff
Iteration sixth: offset: 168 clump: 0xaaaaaa
Iteration seventh: offset: 216 clump: 0xff
Loop breaks because in the end the remaining bits (0x00aa) size was less
than clump size of 24 bits.
In above example it can be seen that in iteration third, the 24 bit clump
that was retrieved was split between bitmap[0] and bitmap[1]. This example
also shows that 24 bit zeroes if present in between, were skipped (preserving
the previous for_each_set_macro8 behaviour).
Example 2:
clump size = 6 bits, Number of clumps (or ports) = 3.
/* bitmap memory region */
0x00aa0000ff000000; /* Most significant bits */
0xaaaaaa0000ff0000;
0x0f00000000000000;
0x0000000000000ac0; /* Least significant bits */
Different iterations of for_each_set_clump:
'offset' is the bit position and 'clump' is the 6 bit clump from the
above bitmap.
Iteration first: offset: 6 clump: 0x2b
Loop breaks because 6 * 3 = 18 bits traversed in bitmap.
Here 6 * 3 is clump size * no. of clumps.
Changes in v7:
- [Patch 2/4]: Minor changes: Use macro 'DECLARE_BITMAP()' and split 'struct'
definition and test data.
Changes in v6:
- [Patch 2/4]: Make 'for loop' inside test_for_each_set_clump more
succinct.
Changes in v5:
- [Patch 4/4]: Minor change: Hardcode value for better code readability.
Changes in v4:
- [Patch 2/4]: Use 'for' loop in test function of for_each_set_clump.
- [Patch 3/4]: Minor change: Inline value for better code readability.
- [Patch 4/4]: Minor change: Inline value for better code readability.
Changes in v3:
- [Patch 3/4]: Change datatype of some variables from u64 to unsigned long
in function thunderx_gpio_set_multiple.
CHanges in v2:
- [Patch 2/4]: Unify different tests for 'for_each_set_clump'. Pass test data as
function parameters.
- [Patch 2/4]: Remove unnecessary bitmap_zero calls.
Syed Nayyar Waris (4):
bitops: Introduce the the for_each_set_clump macro
lib/test_bitmap.c: Add for_each_set_clump test cases
gpio: thunderx: Utilize for_each_set_clump macro
gpio: xilinx: Utilize for_each_set_clump macro
drivers/gpio/gpio-thunderx.c | 11 ++-
drivers/gpio/gpio-xilinx.c | 62 ++++++-------
include/asm-generic/bitops/find.h | 19 ++++
include/linux/bitmap.h | 61 +++++++++++++
include/linux/bitops.h | 13 +++
lib/find_bit.c | 14 +++
lib/test_bitmap.c | 144 ++++++++++++++++++++++++++++++
7 files changed, 290 insertions(+), 34 deletions(-)
base-commit: b9bbe6ed63b2b9f2c9ee5cbd0f2c946a2723f4ce
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] arm64: ptrace: Fix PTRACE_SINGLESTEP into signal handler
From: Keno Fischer @ 2020-05-24 4:38 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, will, oleg, linux-kernel
Executing PTRACE_SINGLESTEP at a signal stop is special. It
is supposed to step merely the signal setup work that the
kernel does, but not any instructions in user space. Since
not all architectures have the ability to generate a
single-step exception directly upon return from user-space,
there is a generic pseudo-single-step-stop that may be used
for this purpose (tracehook_signal_handler). Now, arm64 does
have the ability to generate single-step exceptions directly
upon return to userspace and was using this capability (rather
than the generic pseudo-trap) to obtain a similar effect. However,
there is actually a subtle difference that becomes noticeable
when the signal handler in question attempts to block SIGTRAP
(either because it is set in sa_mask, or because it is a handler
for SIGTRAP itself and SA_NODEFER is not set). In such a
situation, a real single step exception will cause the SIGTRAP
signal to be forcibly unblocked and the signal disposition
to be reset to SIG_DFL. The generic pseudo-single-step does
not suffer from this problem, because the SIGTRAP it delivers
is not real. The arm64 behavior is problematic, because a forced
reset of the signal disposition can be quite disruptive to the
userspace program. This patch brings the arm64 behavior in line
with the other major architectures by using the generic
pseudo-single-step-stop, avoiding the problematic interaction
with SIGTRAP masks.
Fixes: 2c020ed8 ("arm64: Signal handling support")
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
---
arch/arm64/kernel/signal.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 339882db5a91..cf237ee9443b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -808,14 +808,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
*/
ret |= !valid_user_regs(®s->user_regs, current);
- /*
- * Fast forward the stepping logic so we step into the signal
- * handler.
- */
- if (!ret)
- user_fastforward_single_step(tsk);
-
- signal_setup_done(ret, ksig, 0);
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2] mt76: mt7615: add support for MT7611N
From: DENG Qingfang @ 2020-05-24 3:41 UTC (permalink / raw)
To: linux-wireless
Cc: ryder.lee, matthias.bgg, linux-mediatek, kvalo, royluo,
lorenzo.bianconi83, linux-arm-kernel, nbd
MT7611N is basically the same as MT7615N, except it only supports 5GHz
It is used by some TP-Link and Mercury wireless routers
Signed-off-by: DENG Qingfang <dqfext@gmail.com>
---
v1 -> v2:
make is_mt7615(&dev->mt76) return true for mt7611
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 7 +++++++
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 7 ++++++-
drivers/net/wireless/mediatek/mt76/mt7615/pci.c | 1 +
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
index 6a5ae047c63b..edac37e7847b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
@@ -111,6 +111,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
return;
}
+ if (is_mt7611(&dev->mt76)) {
+ /* 5GHz only */
+ dev->mt76.cap.has_5ghz = true;
+ return;
+ }
+
val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
eeprom[MT_EE_WIFI_CONF]);
switch (val) {
@@ -310,6 +316,7 @@ static void mt7615_cal_free_data(struct mt7615_dev *dev)
mt7622_apply_cal_free_data(dev);
break;
case 0x7615:
+ case 0x7611:
mt7615_apply_cal_free_data(dev);
break;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index ebdfca64b079..4ce8b379a147 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -411,7 +411,7 @@ static inline bool is_mt7622(struct mt76_dev *dev)
static inline bool is_mt7615(struct mt76_dev *dev)
{
- return mt76_chip(dev) == 0x7615;
+ return mt76_chip(dev) == 0x7615 || mt76_chip(dev) == 0x7611;
}
static inline bool is_mt7663(struct mt76_dev *dev)
@@ -419,6 +419,11 @@ static inline bool is_mt7663(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7663;
}
+static inline bool is_mt7611(struct mt76_dev *dev)
+{
+ return mt76_chip(dev) == 0x7611;
+}
+
static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
{
mt76_set_irq_mask(&dev->mt76, 0, 0, mask);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
index 88ff14564521..b09d08d0dac9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
@@ -14,6 +14,7 @@
static const struct pci_device_id mt7615_pci_device_table[] = {
{ PCI_DEVICE(0x14c3, 0x7615) },
{ PCI_DEVICE(0x14c3, 0x7663) },
+ { PCI_DEVICE(0x14c3, 0x7611) },
{ },
};
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] media: exynos4-is: Fix runtime PM imbalance in isp_video_open
From: Dinghao Liu @ 2020-05-24 3:34 UTC (permalink / raw)
To: dinghao.liu, kjlu
Cc: linux-samsung-soc, linux-kernel, Krzysztof Kozlowski,
Kyungmin Park, Kukjin Kim, Sylwester Nawrocki,
Mauro Carvalho Chehab, linux-arm-kernel, linux-media
pm_runtime_get_sync() increments the runtime PM usage counter even
when it returns an error code. Thus a pairing decrement is needed on
the error handling path to keep the counter balanced.
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
---
drivers/media/platform/exynos4-is/fimc-isp-video.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 15f443fa7208..612b9872afc8 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -293,6 +293,7 @@ static int isp_video_open(struct file *file)
if (!ret)
goto unlock;
rel_fh:
+ pm_runtime_put_noidle(&isp->pdev->dev);
v4l2_fh_release(file);
unlock:
mutex_unlock(&isp->video_lock);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* RE: [PATCH V3] thermal: imx: Add missing of_node_put()
From: Anson Huang @ 2020-05-24 3:26 UTC (permalink / raw)
To: Anson Huang, rui.zhang@intel.com, daniel.lezcano@linaro.org,
amit.kucheria@verdurent.com, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: dl-linux-imx
In-Reply-To: <1588128570-12917-1-git-send-email-Anson.Huang@nxp.com>
Gentle ping...
> Subject: [PATCH V3] thermal: imx: Add missing of_node_put()
>
> After finishing using cpu node got from of_get_cpu_node(), of_node_put()
> needs to be called, the cpufreq policy also needs to be put unconditionally.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> Changes since V2:
> - call cpufreq_cpu_put() unconditionally after cooling register done.
> ---
> drivers/thermal/imx_thermal.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index e761c9b..8764cb5 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -649,7 +649,7 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
> static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
> {
> struct device_node *np;
> - int ret;
> + int ret = 0;
>
> data->policy = cpufreq_cpu_get(0);
> if (!data->policy) {
> @@ -661,20 +661,19 @@ static int
> imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
>
> if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
> data->cdev = cpufreq_cooling_register(data->policy);
> - if (IS_ERR(data->cdev)) {
> + if (IS_ERR(data->cdev))
> ret = PTR_ERR(data->cdev);
> - cpufreq_cpu_put(data->policy);
> - return ret;
> - }
> }
>
> - return 0;
> + cpufreq_cpu_put(data->policy);
> + of_node_put(np);
> +
> + return ret;
> }
>
> static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data
> *data) {
> cpufreq_cooling_unregister(data->cdev);
> - cpufreq_cpu_put(data->policy);
> }
>
> #else
> --
> 2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] media: exynos4-is: Fix runtime PM imbalance in fimc_is_probe
From: Dinghao Liu @ 2020-05-24 2:59 UTC (permalink / raw)
To: dinghao.liu, kjlu
Cc: linux-samsung-soc, linux-kernel, Krzysztof Kozlowski,
Kyungmin Park, Kukjin Kim, Sylwester Nawrocki,
Mauro Carvalho Chehab, linux-arm-kernel, linux-media
pm_runtime_get_sync() increments the runtime PM usage counter even
when it returns an error code. Thus a pairing decrement is needed on
the error handling path to keep the counter balanced. For all error
paths after pm_runtime_get_sync(), things are the same.
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
---
drivers/media/platform/exynos4-is/fimc-is.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 64148b7e0d98..a474014f0a0f 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -871,6 +871,7 @@ static int fimc_is_probe(struct platform_device *pdev)
err_sd:
fimc_is_unregister_subdevs(is);
err_pm:
+ pm_runtime_put_noidle(dev);
if (!pm_runtime_enabled(dev))
fimc_is_runtime_suspend(dev);
err_irq:
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v13 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Laurent Pinchart @ 2020-05-24 2:27 UTC (permalink / raw)
To: Vishal Sagar
Cc: mark.rutland, devicetree, Jacopo Mondi, Dinesh Kumar, Hyun Kwon,
Hyun Kwon, Sandip Kothari, linux-kernel, robh+dt, Michal Simek,
Luca Ceresoli, hans.verkuil, mchehab, linux-arm-kernel,
linux-media
In-Reply-To: <20200512151947.120348-3-vishal.sagar@xilinx.com>
Hi Vishal,
Thank you for the patch.
On Tue, May 12, 2020 at 08:49:47PM +0530, Vishal Sagar wrote:
> The Xilinx MIPI CSI-2 Rx Subsystem soft IP is used to capture images
> from MIPI CSI-2 camera sensors and output AXI4-Stream video data ready
> for image processing. Please refer to PG232 for details.
>
> The CSI2 Rx controller filters out all packets except for the packets
> with data type fixed in hardware. RAW8 packets are always allowed to
> pass through.
>
> It is also used to setup and handle interrupts and enable the core. It
> logs all the events in respective counters between streaming on and off.
>
> The driver supports only the video format bridge enabled configuration.
> Some data types like YUV 422 10bpc, RAW16, RAW20 are supported when the
> CSI v2.0 feature is enabled in design. When the VCX feature is enabled,
> the maximum number of virtual channels becomes 16 from 4.
>
> Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> v13
> - Based on Laurent's suggestions
> - Removed unnecessary debug statement for vep
> - Added TODO for clock to enable disable at streamon/off
> - Fix for index to start from 0 for get_nth_mbus_format
> - Removed macro XCSI_TIMEOUT_VAL
> - Remove ndelay from hard reset
> - Remove hard reset from irq handler
> - Fix short packet fifo clear
> - Add TODO for v4l2_subdev_notify for SLBF error
> - Fix the enable condition in s_stream
> - Fix condition in xcsi2rxss_set_format
> - Fix enum_mbus_code for double enumeration of RAW8 Data type
> - Removed core struct
> - Added reviewed by Laurent
>
> v12
> - Changes done as suggested by Laurent Pinchart and Luca Ceresoli
> - Removed unused macros
> - No local storage of supported formats
> - Dropped init mbus fmts and removed xcsi2rxss_init_mbus_fmts()
> - XCSI_GET_BITSET_STR removed
> - Add data type and mbus LUT
> - Added xcsi2rxss_get_nth_mbus() and xcsi2rxss_get_dt()
> - Replaced all core->dev with dev in dev_dbg() and related debug prints
> - Replaced xcsi2rxss_log_ipconfig() with single line
> - Removed small functions to enable/disable interrupts and core
> - Now save remote subdev in state struct before streaming on
> - Made xcsi2rxss_reset as soft_reset()
> - Added hard reset using video-reset gpio
> - 2 modes one with delay and another sleep
> - Instead of reset-gpios it is not video-reset-gpios
> - In irq handler
> - Moved clearing of ISR up
> - Dump / empty short packet fifo
> - Irq handler is now threaded
> - Added init_cfg pad ops and removed open()
> - Updated xcsi2rxss_set_format(), xcsi2rxss_enum_mbus_code() to use the dt mbus lut
> - xcsi2rxss_set_default_format() updated
> - Moved mutex_init()
> - Updated graph handling
> - Removed unnecessary prints
> - Use devm_platform_ioremap_resource() and platform_get_irq()
> - Update KConfig description
>
> v11
> - Fixed changes as suggested by Sakari Ailus
> - Removed VIDEO_XILINX from KConfig
> - Minor formatting
> - Start / Stop upstream sub-device in xcsi2rxss_start_stream()
> and xcsi2rxss_stop_stream()
> - Added v4l2_subdev_link_validate_default() in v4l2_subdev_pad_ops()
> - Use fwnode_graph_get_endpoint_by_id() instead of parsing by self
> - Set bus type as V4L2_MBUS_CSI2_DPHY in struct v4l2_fwnode_endpoint
> - Remove num_clks from core. Instead use ARRAY_SIZE()
> - Fixed SPDX header to GPL-2.0
> - Update copyright year to 2020
>
> v10
> - Removed all V4L2 controls and events based on Sakari's comments.
> - Now stop_stream() before toggling rst_gpio
> - Updated init_mbus() to throw error on array out of bound access
> - Make events and vcx_events as counters instead of structures
> - Minor fixes in set_format() enum_mbus_code() as suggested by Sakari
>
> v9
> - Moved all controls and events to xilinx-csi2rxss.h
> - Updated name and description of controls and events
> - Get control base address from v4l2-controls.h (0x10c0)
> - Fix KConfig for dependency on VIDEO_XILINX
> - Added enum_mbus_code() support
> - Added default format to be returned on open()
> - Mark variables are const
> - Remove references to short packet in comments
> - Add check for streaming before setting active lanes control
> - strlcpy -> strscpy
> - Fix xcsi2rxss_set_format()
>
> v8
> - Use clk_bulk* APIs
> - Add gpio reset for asserting video_aresetn when stream line buffer occurs
> - Removed short packet related events and irq handling
> - V4L2_EVENT_XLNXCSIRX_SPKT and V4L2_EVENT_XLNXCSIRX_SPKT_OVF removed
> - Removed frame counter control V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER
> and xcsi2rxss_g_volatile_ctrl()
> - Minor formatting fixes
>
> v7
> - No change
>
> v6
> - No change
>
> v5
> - Removed bayer and updated related parts like set default format based
> on Luca Cersoli's comments.
> - Added correct YUV422 10bpc media bus format
>
> v4
> - Removed irq member from core structure
> - Consolidated IP config prints in xcsi2rxss_log_ipconfig()
> - Return -EINVAL in case of invalid ioctl
> - Code formatting
> - Added reviewed by Hyun Kwon
>
> v3
> - Fixed comments given by Hyun.
> - Removed DPHY 200 MHz clock. This will be controlled by DPHY driver
> - Minor code formatting
> - en_csi_v20 and vfb members removed from struct and made local to dt parsing
> - lock description updated
> - changed to ratelimited type for all dev prints in irq handler
> - Removed YUV 422 10bpc media format
>
> v2
> - Fixed comments given by Hyun and Sakari.
> - Made all bitmask using BIT() and GENMASK()
> - Removed unused definitions
> - Removed DPHY access. This will be done by separate DPHY PHY driver.
> - Added support for CSI v2.0 for YUV 422 10bpc, RAW16, RAW20 and extra
> virtual channels
> - Fixed the ports as sink and source
> - Now use the v4l2fwnode API to get number of data-lanes
> - Added clock framework support
> - Removed the close() function
> - updated the set format function
> - support only VFB enabled configuration
>
> drivers/media/platform/xilinx/Kconfig | 7 +
> drivers/media/platform/xilinx/Makefile | 1 +
> .../media/platform/xilinx/xilinx-csi2rxss.c | 1114 +++++++++++++++++
> 3 files changed, 1122 insertions(+)
> create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c
>
> diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
> index 01c96fb66414..44587dccacf1 100644
> --- a/drivers/media/platform/xilinx/Kconfig
> +++ b/drivers/media/platform/xilinx/Kconfig
> @@ -12,6 +12,13 @@ config VIDEO_XILINX
>
> if VIDEO_XILINX
>
> +config VIDEO_XILINX_CSI2RXSS
> + tristate "Xilinx CSI-2 Rx Subsystem"
> + help
> + Driver for Xilinx MIPI CSI-2 Rx Subsystem. This is a V4L sub-device
> + based driver that takes input from CSI-2 Tx source and converts
> + it into an AXI4-Stream.
> +
> config VIDEO_XILINX_TPG
> tristate "Xilinx Video Test Pattern Generator"
> depends on VIDEO_XILINX
> diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
> index 4cdc0b1ec7a5..6119a34f3043 100644
> --- a/drivers/media/platform/xilinx/Makefile
> +++ b/drivers/media/platform/xilinx/Makefile
> @@ -3,5 +3,6 @@
> xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
>
> obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
> +obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
> obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
> obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
> diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> new file mode 100644
> index 000000000000..cac08149ae7a
> --- /dev/null
> +++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> @@ -0,0 +1,1114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Xilinx MIPI CSI-2 Rx Subsystem
> + *
> + * Copyright (C) 2016 - 2020 Xilinx, Inc.
> + *
> + * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
> + *
> + */
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/v4l2-subdev.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +#include "xilinx-vip.h"
> +
> +/* Register register map */
> +#define XCSI_CCR_OFFSET 0x00
> +#define XCSI_CCR_SOFTRESET BIT(1)
> +#define XCSI_CCR_ENABLE BIT(0)
> +
> +#define XCSI_PCR_OFFSET 0x04
> +#define XCSI_PCR_MAXLANES_MASK GENMASK(4, 3)
> +#define XCSI_PCR_ACTLANES_MASK GENMASK(1, 0)
> +
> +#define XCSI_CSR_OFFSET 0x10
> +#define XCSI_CSR_PKTCNT GENMASK(31, 16)
> +#define XCSI_CSR_SPFIFOFULL BIT(3)
> +#define XCSI_CSR_SPFIFONE BIT(2)
> +#define XCSI_CSR_SLBF BIT(1)
> +#define XCSI_CSR_RIPCD BIT(0)
> +
> +#define XCSI_GIER_OFFSET 0x20
> +#define XCSI_GIER_GIE BIT(0)
> +
> +#define XCSI_ISR_OFFSET 0x24
> +#define XCSI_IER_OFFSET 0x28
> +
> +#define XCSI_ISR_FR BIT(31)
> +#define XCSI_ISR_VCXFE BIT(30)
> +#define XCSI_ISR_WCC BIT(22)
> +#define XCSI_ISR_ILC BIT(21)
> +#define XCSI_ISR_SPFIFOF BIT(20)
> +#define XCSI_ISR_SPFIFONE BIT(19)
> +#define XCSI_ISR_SLBF BIT(18)
> +#define XCSI_ISR_STOP BIT(17)
> +#define XCSI_ISR_SOTERR BIT(13)
> +#define XCSI_ISR_SOTSYNCERR BIT(12)
> +#define XCSI_ISR_ECC2BERR BIT(11)
> +#define XCSI_ISR_ECC1BERR BIT(10)
> +#define XCSI_ISR_CRCERR BIT(9)
> +#define XCSI_ISR_DATAIDERR BIT(8)
> +#define XCSI_ISR_VC3FSYNCERR BIT(7)
> +#define XCSI_ISR_VC3FLVLERR BIT(6)
> +#define XCSI_ISR_VC2FSYNCERR BIT(5)
> +#define XCSI_ISR_VC2FLVLERR BIT(4)
> +#define XCSI_ISR_VC1FSYNCERR BIT(3)
> +#define XCSI_ISR_VC1FLVLERR BIT(2)
> +#define XCSI_ISR_VC0FSYNCERR BIT(1)
> +#define XCSI_ISR_VC0FLVLERR BIT(0)
> +
> +#define XCSI_ISR_ALLINTR_MASK (0xc07e3fff)
> +
> +/*
> + * Removed VCXFE mask as it doesn't exist in IER
> + * Removed STOP state irq as this will keep driver in irq handler only
> + */
> +#define XCSI_IER_INTR_MASK (XCSI_ISR_ALLINTR_MASK &\
> + ~(XCSI_ISR_STOP | XCSI_ISR_VCXFE))
> +
> +#define XCSI_SPKTR_OFFSET 0x30
> +#define XCSI_SPKTR_DATA GENMASK(23, 8)
> +#define XCSI_SPKTR_VC GENMASK(7, 6)
> +#define XCSI_SPKTR_DT GENMASK(5, 0)
> +#define XCSI_SPKT_FIFO_DEPTH 31
> +
> +#define XCSI_VCXR_OFFSET 0x34
> +#define XCSI_VCXR_VCERR GENMASK(23, 0)
> +#define XCSI_VCXR_FSYNCERR BIT(1)
> +#define XCSI_VCXR_FLVLERR BIT(0)
> +
> +#define XCSI_CLKINFR_OFFSET 0x3C
> +#define XCSI_CLKINFR_STOP BIT(1)
> +
> +#define XCSI_DLXINFR_OFFSET 0x40
> +#define XCSI_DLXINFR_STOP BIT(5)
> +#define XCSI_DLXINFR_SOTERR BIT(1)
> +#define XCSI_DLXINFR_SOTSYNCERR BIT(0)
> +#define XCSI_MAXDL_COUNT 0x4
> +
> +#define XCSI_VCXINF1R_OFFSET 0x60
> +#define XCSI_VCXINF1R_LINECOUNT GENMASK(31, 16)
> +#define XCSI_VCXINF1R_LINECOUNT_SHIFT 16
> +#define XCSI_VCXINF1R_BYTECOUNT GENMASK(15, 0)
> +
> +#define XCSI_VCXINF2R_OFFSET 0x64
> +#define XCSI_VCXINF2R_DT GENMASK(5, 0)
> +#define XCSI_MAXVCX_COUNT 16
> +
> +/*
> + * Sink pad connected to sensor source pad.
> + * Source pad connected to next module like demosaic.
> + */
> +#define XCSI_MEDIA_PADS 2
> +#define XCSI_DEFAULT_WIDTH 1920
> +#define XCSI_DEFAULT_HEIGHT 1080
> +
> +/* MIPI CSI-2 Data Types from spec */
> +#define XCSI_DT_YUV4228B 0x1e
> +#define XCSI_DT_YUV42210B 0x1f
> +#define XCSI_DT_RGB444 0x20
> +#define XCSI_DT_RGB555 0x21
> +#define XCSI_DT_RGB565 0x22
> +#define XCSI_DT_RGB666 0x23
> +#define XCSI_DT_RGB888 0x24
> +#define XCSI_DT_RAW6 0x28
> +#define XCSI_DT_RAW7 0x29
> +#define XCSI_DT_RAW8 0x2a
> +#define XCSI_DT_RAW10 0x2b
> +#define XCSI_DT_RAW12 0x2c
> +#define XCSI_DT_RAW14 0x2d
> +#define XCSI_DT_RAW16 0x2e
> +#define XCSI_DT_RAW20 0x2f
> +
> +#define XCSI_VCX_START 4
> +#define XCSI_MAX_VC 4
> +#define XCSI_MAX_VCX 16
> +
> +#define XCSI_NEXTREG_OFFSET 4
> +
> +/* There are 2 events frame sync and frame level error per VC */
> +#define XCSI_VCX_NUM_EVENTS ((XCSI_MAX_VCX - XCSI_MAX_VC) * 2)
> +
> +/**
> + * struct xcsi2rxss_event - Event log structure
> + * @mask: Event mask
> + * @name: Name of the event
> + */
> +struct xcsi2rxss_event {
> + u32 mask;
> + const char *name;
> +};
> +
> +static const struct xcsi2rxss_event xcsi2rxss_events[] = {
> + { XCSI_ISR_FR, "Frame Received" },
> + { XCSI_ISR_VCXFE, "VCX Frame Errors" },
> + { XCSI_ISR_WCC, "Word Count Errors" },
> + { XCSI_ISR_ILC, "Invalid Lane Count Error" },
> + { XCSI_ISR_SPFIFOF, "Short Packet FIFO OverFlow Error" },
> + { XCSI_ISR_SPFIFONE, "Short Packet FIFO Not Empty" },
> + { XCSI_ISR_SLBF, "Streamline Buffer Full Error" },
> + { XCSI_ISR_STOP, "Lane Stop State" },
> + { XCSI_ISR_SOTERR, "SOT Error" },
> + { XCSI_ISR_SOTSYNCERR, "SOT Sync Error" },
> + { XCSI_ISR_ECC2BERR, "2 Bit ECC Unrecoverable Error" },
> + { XCSI_ISR_ECC1BERR, "1 Bit ECC Recoverable Error" },
> + { XCSI_ISR_CRCERR, "CRC Error" },
> + { XCSI_ISR_DATAIDERR, "Data Id Error" },
> + { XCSI_ISR_VC3FSYNCERR, "Virtual Channel 3 Frame Sync Error" },
> + { XCSI_ISR_VC3FLVLERR, "Virtual Channel 3 Frame Level Error" },
> + { XCSI_ISR_VC2FSYNCERR, "Virtual Channel 2 Frame Sync Error" },
> + { XCSI_ISR_VC2FLVLERR, "Virtual Channel 2 Frame Level Error" },
> + { XCSI_ISR_VC1FSYNCERR, "Virtual Channel 1 Frame Sync Error" },
> + { XCSI_ISR_VC1FLVLERR, "Virtual Channel 1 Frame Level Error" },
> + { XCSI_ISR_VC0FSYNCERR, "Virtual Channel 0 Frame Sync Error" },
> + { XCSI_ISR_VC0FLVLERR, "Virtual Channel 0 Frame Level Error" }
> +};
> +
> +#define XCSI_NUM_EVENTS ARRAY_SIZE(xcsi2rxss_events)
> +
> +/*
> + * This table provides a mapping between CSI-2 Data type
> + * and media bus formats
> + */
> +static const u32 xcsi2dt_mbus_lut[][2] = {
> + { XCSI_DT_YUV4228B, MEDIA_BUS_FMT_UYVY8_1X16 },
> + { XCSI_DT_YUV42210B, MEDIA_BUS_FMT_UYVY10_1X20 },
> + { XCSI_DT_RGB444, 0 },
> + { XCSI_DT_RGB555, 0 },
> + { XCSI_DT_RGB565, 0 },
> + { XCSI_DT_RGB666, 0 },
> + { XCSI_DT_RGB888, MEDIA_BUS_FMT_RBG888_1X24 },
> + { XCSI_DT_RAW6, 0 },
> + { XCSI_DT_RAW7, 0 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SRGGB8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SBGGR8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGBRG8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGRBG8_1X8 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SRGGB10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SBGGR10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGBRG10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGRBG10_1X10 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SRGGB12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SBGGR12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGBRG12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGRBG12_1X12 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SRGGB16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SBGGR16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGBRG16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGRBG16_1X16 },
> + { XCSI_DT_RAW20, 0 },
> +};
> +
> +/**
> + * struct xcsi2rxss_state - CSI-2 Rx Subsystem device structure
> + * @subdev: The v4l2 subdev structure
> + * @format: Active V4L2 formats on each pad
> + * @default_format: Default V4L2 format
> + * @events: counter for events
> + * @vcx_events: counter for vcx_events
> + * @dev: Platform structure
> + * @rsubdev: Remote subdev connected to sink pad
> + * @rst_gpio: reset to video_aresetn
> + * @clks: array of clocks
> + * @iomem: Base address of subsystem
> + * @max_num_lanes: Maximum number of lanes present
> + * @datatype: Data type filter
> + * @lock: mutex for accessing this structure
> + * @pads: media pads
> + * @streaming: Flag for storing streaming state
> + * @enable_active_lanes: If number of active lanes can be modified
> + * @en_vcx: If more than 4 VC are enabled
> + *
> + * This structure contains the device driver related parameters
> + */
> +struct xcsi2rxss_state {
> + struct v4l2_subdev subdev;
> + struct v4l2_mbus_framefmt format;
> + struct v4l2_mbus_framefmt default_format;
> + u32 events[XCSI_NUM_EVENTS];
> + u32 vcx_events[XCSI_VCX_NUM_EVENTS];
> + struct device *dev;
> + struct v4l2_subdev *rsubdev;
> + struct gpio_desc *rst_gpio;
> + struct clk_bulk_data *clks;
> + void __iomem *iomem;
> + u32 max_num_lanes;
> + u32 datatype;
> + /* used to protect access to this struct */
> + struct mutex lock;
> + struct media_pad pads[XCSI_MEDIA_PADS];
> + bool streaming;
> + bool enable_active_lanes;
> + bool en_vcx;
> +};
> +
> +static const struct clk_bulk_data xcsi2rxss_clks[] = {
> + { .id = "lite_aclk" },
> + { .id = "video_aclk" },
> +};
> +
> +static inline struct xcsi2rxss_state *
> +to_xcsi2rxssstate(struct v4l2_subdev *subdev)
> +{
> + return container_of(subdev, struct xcsi2rxss_state, subdev);
> +}
> +
> +/*
> + * Register related operations
> + */
> +static inline u32 xcsi2rxss_read(struct xcsi2rxss_state *xcsi2rxss, u32 addr)
> +{
> + return ioread32(xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_write(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 value)
> +{
> + iowrite32(value, xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_clr(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 clr)
> +{
> + xcsi2rxss_write(xcsi2rxss, addr,
> + xcsi2rxss_read(xcsi2rxss, addr) & ~clr);
> +}
> +
> +static inline void xcsi2rxss_set(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 set)
> +{
> + xcsi2rxss_write(xcsi2rxss, addr, xcsi2rxss_read(xcsi2rxss, addr) | set);
> +}
> +
> +/*
> + * This function returns the nth mbus for a data type.
> + * In case of error, mbus code returned is 0.
> + */
> +static u32 xcsi2rxss_get_nth_mbus(u32 dt, u32 n)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
> + if (xcsi2dt_mbus_lut[i][0] == dt) {
> + if (n-- == 0)
> + return xcsi2dt_mbus_lut[i][1];
> + }
> + }
> +
> + return 0;
> +}
> +
> +/* This returns the data type for a media bus format else 0 */
> +static u32 xcsi2rxss_get_dt(u32 mbus)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
> + if (xcsi2dt_mbus_lut[i][1] == mbus)
> + return xcsi2dt_mbus_lut[i][0];
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_soft_reset - Does a soft reset of the MIPI CSI-2 Rx Subsystem
> + * @state: Xilinx CSI-2 Rx Subsystem structure pointer
> + *
> + * Core takes less than 100 video clock cycles to reset.
> + * So a larger timeout value is chosen for margin.
> + *
> + * Return: 0 - on success OR -ETIME if reset times out
> + */
> +static int xcsi2rxss_soft_reset(struct xcsi2rxss_state *state)
> +{
> + u32 timeout = 1000; /* us */
> +
> + xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
> +
> + while (xcsi2rxss_read(state, XCSI_CSR_OFFSET) & XCSI_CSR_RIPCD) {
> + if (timeout == 0) {
> + dev_err(state->dev, "soft reset timed out!\n");
> + return -ETIME;
> + }
> +
> + timeout--;
> + udelay(1);
> + }
> +
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
> + return 0;
> +}
> +
> +static void xcsi2rxss_hard_reset(struct xcsi2rxss_state *state)
> +{
> + if (!state->rst_gpio)
> + return;
> +
> + /* minimum of 40 dphy_clk_200M cycles */
> + gpiod_set_value_cansleep(state->rst_gpio, 1);
> + usleep_range(1, 2);
> + gpiod_set_value_cansleep(state->rst_gpio, 0);
> +}
> +
> +static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++)
> + state->events[i] = 0;
> +
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++)
> + state->vcx_events[i] = 0;
> +}
> +
> +/* Print event counters */
> +static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
> +{
> + struct device *dev = state->dev;
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> + if (state->events[i] > 0) {
> + dev_info(dev, "%s events: %d\n",
> + xcsi2rxss_events[i].name,
> + state->events[i]);
> + }
> + }
> +
> + if (state->en_vcx) {
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> + if (state->vcx_events[i] > 0) {
> + dev_info(dev,
> + "VC %d Frame %s err vcx events: %d\n",
> + (i / 2) + XCSI_VCX_START,
> + i & 1 ? "Sync" : "Level",
> + state->vcx_events[i]);
> + }
> + }
> + }
> +}
> +
> +/**
> + * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
> + * @sd: Pointer to V4L2 subdevice structure
> + *
> + * This function prints the current status of Xilinx MIPI CSI-2
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct device *dev = xcsi2rxss->dev;
> + const char *tr = "true";
> + const char *fa = "false";
I didn't notice this in the previous version, but you could just write
"true" and "false" below. The compiler should perform string
de-duplication automatically.
> + u32 reg, data;
> + unsigned int i, max_vc;
> +
> + mutex_lock(&xcsi2rxss->lock);
> +
> + xcsi2rxss_log_counters(xcsi2rxss);
> +
> + dev_info(dev, "***** Core Status *****\n");
> + data = xcsi2rxss_read(xcsi2rxss, XCSI_CSR_OFFSET);
> + dev_info(dev, "Short Packet FIFO Full = %s\n",
> + data & XCSI_CSR_SPFIFOFULL ? tr : fa);
> + dev_info(dev, "Short Packet FIFO Not Empty = %s\n",
> + data & XCSI_CSR_SPFIFONE ? tr : fa);
> + dev_info(dev, "Stream line buffer full = %s\n",
> + data & XCSI_CSR_SLBF ? tr : fa);
> + dev_info(dev, "Soft reset/Core disable in progress = %s\n",
> + data & XCSI_CSR_RIPCD ? tr : fa);
> +
> + /* Clk & Lane Info */
> + dev_info(dev, "******** Clock Lane Info *********\n");
> + data = xcsi2rxss_read(xcsi2rxss, XCSI_CLKINFR_OFFSET);
> + dev_info(dev, "Clock Lane in Stop State = %s\n",
> + data & XCSI_CLKINFR_STOP ? tr : fa);
> +
> + dev_info(dev, "******** Data Lane Info *********\n");
> + dev_info(dev, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
> + reg = XCSI_DLXINFR_OFFSET;
> + for (i = 0; i < XCSI_MAXDL_COUNT; i++) {
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> +
> + dev_info(dev, "%d\t%s\t\t%s\t\t%s\n", i,
> + data & XCSI_DLXINFR_SOTERR ? tr : fa,
> + data & XCSI_DLXINFR_SOTSYNCERR ? tr : fa,
> + data & XCSI_DLXINFR_STOP ? tr : fa);
> +
> + reg += XCSI_NEXTREG_OFFSET;
> + }
> +
> + /* Virtual Channel Image Information */
> + dev_info(dev, "********** Virtual Channel Info ************\n");
> + dev_info(dev, "VC\tLine Count\tByte Count\tData Type\n");
> + if (xcsi2rxss->en_vcx)
> + max_vc = XCSI_MAX_VCX;
> + else
> + max_vc = XCSI_MAX_VC;
> +
> + reg = XCSI_VCXINF1R_OFFSET;
> + for (i = 0; i < max_vc; i++) {
> + u32 line_count, byte_count, data_type;
> +
> + /* Get line and byte count from VCXINFR1 Register */
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> + byte_count = data & XCSI_VCXINF1R_BYTECOUNT;
> + line_count = data & XCSI_VCXINF1R_LINECOUNT;
> + line_count >>= XCSI_VCXINF1R_LINECOUNT_SHIFT;
> +
> + /* Get data type from VCXINFR2 Register */
> + reg += XCSI_NEXTREG_OFFSET;
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> + data_type = data & XCSI_VCXINF2R_DT;
> +
> + dev_info(dev, "%d\t%d\t\t%d\t\t0x%x\n", i, line_count,
> + byte_count, data_type);
> +
> + /* Move to next pair of VC Info registers */
> + reg += XCSI_NEXTREG_OFFSET;
> + }
> +
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +static struct v4l2_subdev *xcsi2rxss_get_remote_subdev(struct media_pad *local)
> +{
> + struct media_pad *remote;
> +
> + remote = media_entity_remote_pad(local);
> + if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
> + return NULL;
> +
> + return media_entity_to_v4l2_subdev(remote->entity);
> +}
> +
> +static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
> +{
> + int ret = 0;
> +
> + /* enable core */
> + xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> +
> + ret = xcsi2rxss_soft_reset(state);
> + if (ret < 0) {
> + state->streaming = false;
> + return ret;
> + }
> +
> + /* enable interrupts */
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> + xcsi2rxss_write(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_set(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + state->streaming = true;
> +
> + state->rsubdev =
> + xcsi2rxss_get_remote_subdev(&state->pads[XVIP_PAD_SINK]);
> +
> + ret = v4l2_subdev_call(state->rsubdev, video, s_stream, 1);
> + if (ret) {
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
> + }
> +
> + return ret;
> +}
> +
> +static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
> +{
> + v4l2_subdev_call(state->rsubdev, video, s_stream, 0);
> +
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
> +}
> +
> +/**
> + * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
> + * @irq: IRQ number
> + * @data: Pointer to device state
> + *
> + * In the interrupt handler, a list of event counters are updated for
> + * corresponding interrupts. This is useful to get status / debug.
> + *
> + * Return: IRQ_HANDLED after handling interrupts
> + */
> +static irqreturn_t xcsi2rxss_irq_handler(int irq, void *data)
> +{
> + struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)data;
> + struct device *dev = state->dev;
> + u32 status;
> +
> + status = xcsi2rxss_read(state, XCSI_ISR_OFFSET) & XCSI_ISR_ALLINTR_MASK;
> + xcsi2rxss_write(state, XCSI_ISR_OFFSET, status);
> +
> + /* Received a short packet */
> + if (status & XCSI_ISR_SPFIFONE) {
> + u32 count = 0;
> +
> + /*
> + * Drain generic short packet FIFO by reading max 31
> + * (fifo depth) short packets from fifo or till fifo is empty.
> + */
> + for (count = 0; count < XCSI_SPKT_FIFO_DEPTH; ++count) {
> + u32 spfifostat, spkt;
> +
> + spkt = xcsi2rxss_read(state, XCSI_SPKTR_OFFSET);
> + dev_dbg(dev, "Short packet = 0x%08x\n", spkt);
> + spfifostat = xcsi2rxss_read(state, XCSI_ISR_OFFSET);
> + spfifostat &= XCSI_ISR_SPFIFONE;
> + if (!spfifostat)
> + break;
> + xcsi2rxss_write(state, XCSI_ISR_OFFSET, spfifostat);
> + }
> + }
> +
> + /* Short packet FIFO overflow */
> + if (status & XCSI_ISR_SPFIFOF)
> + dev_dbg_ratelimited(dev, "Short packet FIFO overflowed\n");
> +
> + /*
> + * Stream line buffer full
> + * This means there is a backpressure from downstream IP
> + */
> + if (status & XCSI_ISR_SLBF) {
> + dev_alert_ratelimited(dev, "Stream Line Buffer Full!\n");
> +
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
If you set streaming to false, a later call to xcsi2rxss_s_stream(0)
will consider that the stream is already stopped, and skip calling
xcsi2rxss_stop_stream() and xcsi2rxss_hard_reset(). Now that you have
dropped the hard reset from the interrupt handler, we need to rely on it
being called at stream stop time. Should you just drop the line here ?
> +
> + /*
> + * The IP needs to be hard reset before it can be used now.
> + * This will be done in streamoff.
> + */
> +
> + /*
> + * TODO: Notify the whole pipeline with v4l2_subdev_notify() to
> + * inform userspace.
> + */
> + }
> +
> + /* Increment event counters */
> + if (status & XCSI_ISR_ALLINTR_MASK) {
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> + if (!(status & xcsi2rxss_events[i].mask))
> + continue;
> + state->events[i]++;
> + dev_dbg_ratelimited(dev, "%s: %u\n",
> + xcsi2rxss_events[i].name,
> + state->events[i]);
> + }
> +
> + if (status & XCSI_ISR_VCXFE && state->en_vcx) {
> + u32 vcxstatus;
> +
> + vcxstatus = xcsi2rxss_read(state, XCSI_VCXR_OFFSET);
> + vcxstatus &= XCSI_VCXR_VCERR;
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> + if (!(vcxstatus & (1 << i)))
> + continue;
> + state->vcx_events[i]++;
> + }
> + xcsi2rxss_write(state, XCSI_VCXR_OFFSET, vcxstatus);
> + }
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
> +/**
> + * xcsi2rxss_s_stream - It is used to start/stop the streaming.
> + * @sd: V4L2 Sub device
> + * @enable: Flag (True / False)
> + *
> + * This function controls the start or stop of streaming for the
> + * Xilinx MIPI CSI-2 Rx Subsystem.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + int ret = 0;
> +
> + mutex_lock(&xcsi2rxss->lock);
> +
> + if (enable == xcsi2rxss->streaming)
> + goto stream_done;
> +
> + if (enable) {
> + xcsi2rxss_reset_event_counters(xcsi2rxss);
> + ret = xcsi2rxss_start_stream(xcsi2rxss);
> + } else {
> + xcsi2rxss_stop_stream(xcsi2rxss);
> + xcsi2rxss_hard_reset(xcsi2rxss);
> + }
> +
> +stream_done:
> + mutex_unlock(&xcsi2rxss->lock);
> + return ret;
> +}
> +
> +static struct v4l2_mbus_framefmt *
> +__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
> + struct v4l2_subdev_pad_config *cfg,
> + unsigned int pad, u32 which)
> +{
> + switch (which) {
> + case V4L2_SUBDEV_FORMAT_TRY:
> + return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
> + case V4L2_SUBDEV_FORMAT_ACTIVE:
> + return &xcsi2rxss->format;
> + default:
> + return NULL;
> + }
> +}
> +
> +/**
> + * xcsi2rxss_init_cfg - Initialise the pad format config to default
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + *
> + * This function is used to initialize the pad format with the default
> + * values.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct v4l2_mbus_framefmt *format;
> + unsigned int i;
> +
> + mutex_lock(&xcsi2rxss->lock);
> + for (i = 0; i < XCSI_MEDIA_PADS; i++) {
> + format = v4l2_subdev_get_try_format(sd, cfg, i);
> + *format = xcsi2rxss->default_format;
> + }
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_get_format - Get the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to get the pad format information.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> + mutex_lock(&xcsi2rxss->lock);
> + fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad,
> + fmt->which);
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_set_format - This is used to set the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to set the pad format. Since the pad format is fixed
> + * in hardware, it can't be modified on run time. So when a format set is
> + * requested by application, all parameters except the format type is saved
> + * for the pad and the original pad format is sent back to the application.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct v4l2_mbus_framefmt *__format;
> + u32 dt;
> +
> + /* only sink pad format can be updated */
> + mutex_lock(&xcsi2rxss->lock);
> +
> + /*
> + * Only the format->code parameter matters for CSI as the
> + * CSI format cannot be changed at runtime.
> + * Ensure that format to set is copied to over to CSI pad format
> + */
> + __format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
> + fmt->pad, fmt->which);
> +
> + if (fmt->pad == XVIP_PAD_SOURCE) {
> + fmt->format = *__format;
> + mutex_unlock(&xcsi2rxss->lock);
> + return 0;
> + }
> +
> + /*
> + * RAW8 is supported in all datatypes. So if requested media bus format
> + * is of RAW8 type, then allow to be set. In case core is configured to
> + * other RAW, YUV422 8/10 or RGB888, set appropriate media bus format.
> + */
> + dt = xcsi2rxss_get_dt(fmt->format.code);
> + if (dt != xcsi2rxss->datatype && dt != XCSI_DT_RAW8) {
> + dev_dbg(xcsi2rxss->dev, "Unsupported media bus format");
> + /* set the default format for the data type */
> + fmt->format.code = xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype,
> + 0);
> + }
> +
> + *__format = fmt->format;
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/*
> + * xcsi2rxss_enum_mbus_code - Handle pixel format enumeration
> + * @sd : pointer to v4l2 subdev structure
> + * @cfg: V4L2 subdev pad configuration
> + * @code : pointer to v4l2_subdev_mbus_code_enum structure
> + *
> + * Return: -EINVAL or zero on success
> + */
> +int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_mbus_code_enum *code)
As commented by the kbuild bot, this function should be static.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Good to go :-)
> +{
> + struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd);
> + u32 dt, n;
> + int ret = 0;
> +
> + /* RAW8 dt packets are available in all DT configurations */
> + if (code->index < 4) {
> + n = code->index;
> + dt = XCSI_DT_RAW8;
> + } else if (state->datatype != XCSI_DT_RAW8) {
> + n = code->index - 4;
> + dt = state->datatype;
> + } else {
> + return -EINVAL;
> + }
> +
> + code->code = xcsi2rxss_get_nth_mbus(dt, n);
> + if (!code->code)
> + ret = -EINVAL;
> +
> + return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Media Operations
> + */
> +
> +static const struct media_entity_operations xcsi2rxss_media_ops = {
> + .link_validate = v4l2_subdev_link_validate
> +};
> +
> +static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
> + .log_status = xcsi2rxss_log_status,
> +};
> +
> +static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
> + .s_stream = xcsi2rxss_s_stream
> +};
> +
> +static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
> + .init_cfg = xcsi2rxss_init_cfg,
> + .get_fmt = xcsi2rxss_get_format,
> + .set_fmt = xcsi2rxss_set_format,
> + .enum_mbus_code = xcsi2rxss_enum_mbus_code,
> + .link_validate = v4l2_subdev_link_validate_default,
> +};
> +
> +static const struct v4l2_subdev_ops xcsi2rxss_ops = {
> + .core = &xcsi2rxss_core_ops,
> + .video = &xcsi2rxss_video_ops,
> + .pad = &xcsi2rxss_pad_ops
> +};
> +
> +static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
> +{
> + struct device *dev = xcsi2rxss->dev;
> + struct device_node *node = dev->of_node;
> +
> + struct fwnode_handle *ep;
> + struct v4l2_fwnode_endpoint vep = {
> + .bus_type = V4L2_MBUS_CSI2_DPHY
> + };
> + bool en_csi_v20, vfb;
> + int ret;
> +
> + en_csi_v20 = of_property_read_bool(node, "xlnx,en-csi-v2-0");
> + if (en_csi_v20)
> + xcsi2rxss->en_vcx = of_property_read_bool(node, "xlnx,en-vcx");
> +
> + xcsi2rxss->enable_active_lanes =
> + of_property_read_bool(node, "xlnx,en-active-lanes");
> +
> + ret = of_property_read_u32(node, "xlnx,csi-pxl-format",
> + &xcsi2rxss->datatype);
> + if (ret < 0) {
> + dev_err(dev, "missing xlnx,csi-pxl-format property\n");
> + return ret;
> + }
> +
> + switch (xcsi2rxss->datatype) {
> + case XCSI_DT_YUV4228B:
> + case XCSI_DT_RGB444:
> + case XCSI_DT_RGB555:
> + case XCSI_DT_RGB565:
> + case XCSI_DT_RGB666:
> + case XCSI_DT_RGB888:
> + case XCSI_DT_RAW6:
> + case XCSI_DT_RAW7:
> + case XCSI_DT_RAW8:
> + case XCSI_DT_RAW10:
> + case XCSI_DT_RAW12:
> + case XCSI_DT_RAW14:
> + break;
> + case XCSI_DT_YUV42210B:
> + case XCSI_DT_RAW16:
> + case XCSI_DT_RAW20:
> + if (!en_csi_v20) {
> + ret = -EINVAL;
> + dev_dbg(dev, "enable csi v2 for this pixel format");
> + }
> + break;
> + default:
> + ret = -EINVAL;
> + }
> + if (ret < 0) {
> + dev_err(dev, "invalid csi-pxl-format property!\n");
> + return ret;
> + }
> +
> + vfb = of_property_read_bool(node, "xlnx,vfb");
> + if (!vfb) {
> + dev_err(dev, "operation without VFB is not supported\n");
> + return -EINVAL;
> + }
> +
> + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
> + XVIP_PAD_SINK, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!ep) {
> + dev_err(dev, "no sink port found");
> + return -EINVAL;
> + }
> +
> + ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> + fwnode_handle_put(ep);
> + if (ret) {
> + dev_err(dev, "error parsing sink port");
> + return ret;
> + }
> +
> + dev_dbg(dev, "mipi number lanes = %d\n",
> + vep.bus.mipi_csi2.num_data_lanes);
> +
> + xcsi2rxss->max_num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> +
> + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
> + XVIP_PAD_SOURCE, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!ep) {
> + dev_err(dev, "no source port found");
> + return -EINVAL;
> + }
> +
> + fwnode_handle_put(ep);
> +
> + dev_dbg(dev, "vcx %s, %u data lanes (%s), data type 0x%02x\n",
> + xcsi2rxss->en_vcx ? "enabled" : "disabled",
> + xcsi2rxss->max_num_lanes,
> + xcsi2rxss->enable_active_lanes ? "dynamic" : "static",
> + xcsi2rxss->datatype);
> +
> + return 0;
> +}
> +
> +static int xcsi2rxss_probe(struct platform_device *pdev)
> +{
> + struct v4l2_subdev *subdev;
> + struct xcsi2rxss_state *xcsi2rxss;
> + int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
> + struct device *dev = &pdev->dev;
> + int irq, ret;
> +
> + xcsi2rxss = devm_kzalloc(dev, sizeof(*xcsi2rxss), GFP_KERNEL);
> + if (!xcsi2rxss)
> + return -ENOMEM;
> +
> + xcsi2rxss->dev = dev;
> +
> + xcsi2rxss->clks = devm_kmemdup(dev, xcsi2rxss_clks,
> + sizeof(xcsi2rxss_clks), GFP_KERNEL);
> + if (!xcsi2rxss->clks)
> + return -ENOMEM;
> +
> + /* Reset GPIO */
> + xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(xcsi2rxss->rst_gpio)) {
> + if (PTR_ERR(xcsi2rxss->rst_gpio) != -EPROBE_DEFER)
> + dev_err(dev, "Video Reset GPIO not setup in DT");
> + return PTR_ERR(xcsi2rxss->rst_gpio);
> + }
> +
> + ret = xcsi2rxss_parse_of(xcsi2rxss);
> + if (ret < 0)
> + return ret;
> +
> + xcsi2rxss->iomem = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(xcsi2rxss->iomem))
> + return PTR_ERR(xcsi2rxss->iomem);
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return irq;
> +
> + ret = devm_request_threaded_irq(dev, irq, NULL,
> + xcsi2rxss_irq_handler, IRQF_ONESHOT,
> + dev_name(dev), xcsi2rxss);
> + if (ret) {
> + dev_err(dev, "Err = %d Interrupt handler reg failed!\n", ret);
> + return ret;
> + }
> +
> + ret = clk_bulk_get(dev, num_clks, xcsi2rxss->clks);
> + if (ret)
> + return ret;
> +
> + /* TODO: Enable/disable clocks at stream on/off time. */
> + ret = clk_bulk_prepare_enable(num_clks, xcsi2rxss->clks);
> + if (ret)
> + goto err_clk_put;
> +
> + mutex_init(&xcsi2rxss->lock);
> +
> + xcsi2rxss_hard_reset(xcsi2rxss);
> + xcsi2rxss_soft_reset(xcsi2rxss);
> +
> + /* Initialize V4L2 subdevice and media entity */
> + xcsi2rxss->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> + xcsi2rxss->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> +
> + /* Initialize the default format */
> + xcsi2rxss->default_format.code =
> + xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype, 0);
> + xcsi2rxss->default_format.field = V4L2_FIELD_NONE;
> + xcsi2rxss->default_format.colorspace = V4L2_COLORSPACE_SRGB;
> + xcsi2rxss->default_format.width = XCSI_DEFAULT_WIDTH;
> + xcsi2rxss->default_format.height = XCSI_DEFAULT_HEIGHT;
> + xcsi2rxss->format = xcsi2rxss->default_format;
> +
> + /* Initialize V4L2 subdevice and media entity */
> + subdev = &xcsi2rxss->subdev;
> + v4l2_subdev_init(subdev, &xcsi2rxss_ops);
> + subdev->dev = dev;
> + strscpy(subdev->name, dev_name(dev), sizeof(subdev->name));
> + subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
> + subdev->entity.ops = &xcsi2rxss_media_ops;
> + v4l2_set_subdevdata(subdev, xcsi2rxss);
> +
> + ret = media_entity_pads_init(&subdev->entity, XCSI_MEDIA_PADS,
> + xcsi2rxss->pads);
> + if (ret < 0)
> + goto error;
> +
> + platform_set_drvdata(pdev, xcsi2rxss);
> +
> + ret = v4l2_async_register_subdev(subdev);
> + if (ret < 0) {
> + dev_err(dev, "failed to register subdev\n");
> + goto error;
> + }
> +
> + return 0;
> +error:
> + media_entity_cleanup(&subdev->entity);
> + mutex_destroy(&xcsi2rxss->lock);
> + clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
> +err_clk_put:
> + clk_bulk_put(num_clks, xcsi2rxss->clks);
> + return ret;
> +}
> +
> +static int xcsi2rxss_remove(struct platform_device *pdev)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
> + struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
> + int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
> +
> + v4l2_async_unregister_subdev(subdev);
> + media_entity_cleanup(&subdev->entity);
> + mutex_destroy(&xcsi2rxss->lock);
> + clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
> + clk_bulk_put(num_clks, xcsi2rxss->clks);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id xcsi2rxss_of_id_table[] = {
> + { .compatible = "xlnx,mipi-csi2-rx-subsystem-5.0", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
> +
> +static struct platform_driver xcsi2rxss_driver = {
> + .driver = {
> + .name = "xilinx-csi2rxss",
> + .of_match_table = xcsi2rxss_of_id_table,
> + },
> + .probe = xcsi2rxss_probe,
> + .remove = xcsi2rxss_remove,
> +};
> +
> +module_platform_driver(xcsi2rxss_driver);
> +
> +MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
> +MODULE_DESCRIPTION("Xilinx MIPI CSI-2 Rx Subsystem Driver");
> +MODULE_LICENSE("GPL v2");
--
Regards,
Laurent Pinchart
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH v12 10/11] arm64: add mechanism to let user choose which counter to return
From: Richard Cochran @ 2020-05-24 2:11 UTC (permalink / raw)
To: Jianyong Wu
Cc: Mark.Rutland, maz, justin.he, Wei.Chen, kvm, suzuki.poulose,
netdev, Steve.Capper, linux-kernel, sean.j.christopherson,
steven.price, Kaly.Xin, john.stultz, yangbo.lu, pbonzini, tglx,
nd, will, kvmarm, linux-arm-kernel
In-Reply-To: <20200522083724.38182-11-jianyong.wu@arm.com>
On Fri, May 22, 2020 at 04:37:23PM +0800, Jianyong Wu wrote:
> In general, vm inside will use virtual counter compered with host use
> phyical counter. But in some special scenarios, like nested
> virtualization, phyical counter maybe used by vm. A interface added in
> ptp_kvm driver to offer a mechanism to let user choose which counter
> should be return from host.
Sounds like you have two time sources, one for normal guest, and one
for nested. Why not simply offer the correct one to user space
automatically? If that cannot be done, then just offer two PHC
devices with descriptive names.
> diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
> index fef72f29f3c8..8b0a7b328bcd 100644
> --- a/drivers/ptp/ptp_chardev.c
> +++ b/drivers/ptp/ptp_chardev.c
> @@ -123,6 +123,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
> struct timespec64 ts;
> int enable, err = 0;
>
> +#ifdef CONFIG_ARM64
> + static long flag;
static? This is not going to fly.
> + * In most cases, we just need virtual counter from host and
> + * there is limited scenario using this to get physical counter
> + * in guest.
> + * Be careful to use this as there is no way to set it back
> + * unless you reinstall the module.
How on earth is the user supposed to know this?
From your description, this "flag" really should be a module
parameter.
Thanks,
Richard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v13 1/2] media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
From: Laurent Pinchart @ 2020-05-24 2:02 UTC (permalink / raw)
To: Vishal Sagar
Cc: mark.rutland, devicetree, Jacopo Mondi, Dinesh Kumar, Hyun Kwon,
Hyun Kwon, Sandip Kothari, linux-kernel, robh+dt, Michal Simek,
Luca Ceresoli, hans.verkuil, mchehab, Rob Herring,
linux-arm-kernel, linux-media
In-Reply-To: <20200512151947.120348-2-vishal.sagar@xilinx.com>
Hi Vishal,
Thank you for the patch.
On Tue, May 12, 2020 at 08:49:46PM +0530, Vishal Sagar wrote:
> Add bindings documentation for Xilinx MIPI CSI-2 Rx Subsystem.
>
> The Xilinx MIPI CSI-2 Rx Subsystem consists of a CSI-2 Rx controller, a
> D-PHY in Rx mode and a Video Format Bridge.
>
> Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> v13
> - Based on Laurent's suggestions
> - Fixed the datatypes values as minimum and maximum
> - condition added for en-vcx property
>
> v12
> - Moved to yaml format
> - Update CSI-2 and D-PHY
> - Mention that bindings for D-PHY not here
> - reset -> video-reset
>
> v11
> - Modify compatible string from 4.0 to 5.0
>
> v10
> - No changes
>
> v9
> - Fix xlnx,vfb description.
> - s/Optional/Required endpoint property.
> - Move data-lanes description from Ports to endpoint property section.
>
> v8
> - Added reset-gpios optional property to assert video_aresetn
>
> v7
> - Removed the control name from dt bindings
> - Updated the example dt node name to csi2rx
>
> v6
> - Added "control" after V4L2_CID_XILINX_MIPICSISS_ACT_LANES as suggested by Luca
> - Added reviewed by Rob Herring
>
> v5
> - Incorporated comments by Luca Cersoli
> - Removed DPHY clock from description and example
> - Removed bayer pattern from device tree MIPI CSI IP
> doesn't deal with bayer pattern.
>
> v4
> - Added reviewed by Hyun Kwon
>
> v3
> - removed interrupt parent as suggested by Rob
> - removed dphy clock
> - moved vfb to optional properties
> - Added required and optional port properties section
> - Added endpoint property section
>
> v2
> - updated the compatible string to latest version supported
> - removed DPHY related parameters
> - added CSI v2.0 related property (including VCX for supporting upto 16
> virtual channels).
> - modified csi-pxl-format from string to unsigned int type where the value
> is as per the CSI specification
> - Defined port 0 and port 1 as sink and source ports.
> - Removed max-lanes property as suggested by Rob and Sakari
> .../bindings/media/xilinx/xlnx,csi2rxss.yaml | 226 ++++++++++++++++++
> 1 file changed, 226 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
>
> diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> new file mode 100644
> index 000000000000..b0885f461785
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> @@ -0,0 +1,226 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/xilinx/xlnx,csi2rxss.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Xilinx MIPI CSI-2 Receiver Subsystem
> +
> +maintainers:
> + - Vishal Sagar <vishal.sagar@xilinx.com>
> +
> +description: |
> + The Xilinx MIPI CSI-2 Receiver Subsystem is used to capture MIPI CSI-2
> + traffic from compliant camera sensors and send the output as AXI4 Stream
> + video data for image processing.
> + The subsystem consists of a MIPI D-PHY in slave mode which captures the
> + data packets. This is passed along the MIPI CSI-2 Rx IP which extracts the
> + packet data. The optional Video Format Bridge (VFB) converts this data to
> + AXI4 Stream video data.
> + For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
> + Please note that this bindings includes only the MIPI CSI-2 Rx controller
> + and Video Format Bridge and not D-PHY.
> +
> +properties:
> + compatible:
> + items:
> + - enum:
> + - xlnx,mipi-csi2-rx-subsystem-5.0
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + clocks:
> + description: List of clock specifiers
> + items:
> + - description: AXI Lite clock
> + - description: Video clock
> +
> + clock-names:
> + items:
> + - const: lite_aclk
> + - const: video_aclk
> +
> + xlnx,csi-pxl-format:
> + description: |
> + This denotes the CSI Data type selected in hw design.
> + Packets other than this data type (except for RAW8 and
> + User defined data types) will be filtered out.
> + Possible values are as below -
> + 0x1e - YUV4228B
> + 0x1f - YUV42210B
> + 0x20 - RGB444
> + 0x21 - RGB555
> + 0x22 - RGB565
> + 0x23 - RGB666
> + 0x24 - RGB888
> + 0x28 - RAW6
> + 0x29 - RAW7
> + 0x2a - RAW8
> + 0x2b - RAW10
> + 0x2c - RAW12
> + 0x2d - RAW14
> + 0x2e - RAW16
> + 0x2f - RAW20
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> + - anyOf:
> + - minimum: 0x1e
> + - maximum: 0x24
> + - minimum: 0x28
> + - maximum: 0x2f
> +
> + xlnx,vfb:
> + type: boolean
> + description: Present when Video Format Bridge is enabled in IP configuration
> +
> + xlnx,en-csi-v2-0:
> + type: boolean
> + description: Present if CSI v2 is enabled in IP configuration.
> +
> + xlnx,en-vcx:
> + type: boolean
> + description: |
> + When present, there are maximum 16 virtual channels, else only 4.
> +
> + xlnx,en-active-lanes:
> + type: boolean
> + description: |
> + Present if the number of active lanes can be re-configured at
> + runtime in the Protocol Configuration Register. Otherwise all lanes,
> + as set in IP configuration, are always active.
> +
> + video-reset-gpios:
> + description: Optional specifier for a GPIO that asserts video_aresetn.
> + maxItems: 1
> +
> + ports:
> + type: object
> +
> + properties:
> + port@0:
> + type: object
> + description: |
> + Input / sink port node, single endpoint describing the
> + CSI-2 transmitter.
> +
> + properties:
> + reg:
> + const: 0
> +
> + endpoint:
> + type: object
> +
> + properties:
> +
> + data-lanes:
> + description: |
> + This is required only in the sink port 0 endpoint which
> + connects to MIPI CSI-2 source like sensor.
> + The possible values are -
> + 1 - For 1 lane enabled in IP.
> + 1 2 - For 2 lanes enabled in IP.
> + 1 2 3 - For 3 lanes enabled in IP.
> + 1 2 3 4 - For 4 lanes enabled in IP.
> + items:
> + - const: 1
> + - const: 2
> + - const: 3
> + - const: 4
> +
> + remote-endpoint: true
> +
> + required:
> + - data-lanes
> + - remote-endpoint
> +
> + additionalProperties: false
> +
> + additionalProperties: false
> +
> + port@1:
> + type: object
> + description: |
> + Output / source port node, endpoint describing modules
> + connected the CSI-2 receiver.
> +
> + properties:
> +
> + reg:
> + const: 1
> +
> + endpoint:
> + type: object
> +
> + properties:
> +
> + remote-endpoint: true
> +
> + required:
> + - remote-endpoint
> +
> + additionalProperties: false
> +
> + additionalProperties: false
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - clocks
> + - clock-names
> + - xlnx,csi-pxl-format
> + - ports
> +
> +if:
> + not:
> + required:
> + - xlnx,en-csi-v2-0
> +then:
> + properties:
> + xlnx,en-vcx: false
As I've just commented on v12, I think we should condition the
xlnx,csi-pxl-format property to xlnx,vfb being set. xlnx,csi-pxl-format
should be removed from the required properties above, and the following
conditions added:
allOf:
- if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
- if:
not:
required:
- xlnx,en-csi-v2-0
then:
properties:
xlnx,en-vcx: false
The 'allOf' is needed as you can't have two 'if' constructs at the top
level.
Please however let me know if my understanding is wrong and
xlnx,csi-pxl-format is needed even when xlnx,vfb is not set. In that
case please ignore this change (but please add the ... below).
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + xcsi2rxss_1: csi2rx@a0020000 {
> + compatible = "xlnx,mipi-csi2-rx-subsystem-5.0";
> + reg = <0x0 0xa0020000 0x0 0x10000>;
> + interrupt-parent = <&gic>;
> + interrupts = <0 95 4>;
> + xlnx,csi-pxl-format = <0x2a>;
> + xlnx,vfb;
> + xlnx,en-active-lanes;
> + xlnx,en-csi-v2-0;
> + xlnx,en-vcx;
> + clock-names = "lite_aclk", "video_aclk";
> + clocks = <&misc_clk_0>, <&misc_clk_1>;
> + video-reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + /* Sink port */
> + reg = <0>;
> + csiss_in: endpoint {
> + data-lanes = <1 2 3 4>;
> + /* MIPI CSI-2 Camera handle */
> + remote-endpoint = <&camera_out>;
> + };
> + };
> + port@1 {
> + /* Source port */
> + reg = <1>;
> + csiss_out: endpoint {
> + remote-endpoint = <&vproc_in>;
> + };
> + };
> + };
> + };
YAML files usually end with
...
on the last line to mark the end of file.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH v12 10/11] arm64: add mechanism to let user choose which counter to return
From: Richard Cochran @ 2020-05-24 1:47 UTC (permalink / raw)
To: Jianyong Wu
Cc: Mark.Rutland, maz, justin.he, Wei.Chen, kvm, suzuki.poulose,
netdev, Steve.Capper, linux-kernel, sean.j.christopherson,
steven.price, Kaly.Xin, john.stultz, yangbo.lu, pbonzini, tglx,
nd, will, kvmarm, linux-arm-kernel
In-Reply-To: <20200522083724.38182-11-jianyong.wu@arm.com>
On Fri, May 22, 2020 at 04:37:23PM +0800, Jianyong Wu wrote:
> To use this feature, you should call PTP_EXTTS_REQUEST(2) ioctl with flag
> set bit PTP_KVM_ARM_PHY_COUNTER in its argument then call
> PTP_SYS_OFFSET_PRECISE(2) ioctl to get the cross timestamp and phyical
> counter will return. If the bit not set or no call for PTP_EXTTS_REQUEST2,
> virtual counter will return by default.
I'm sorry, but NAK on this completely bizarre twisting of the user
space API.
> diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
> index fef72f29f3c8..8b0a7b328bcd 100644
> --- a/drivers/ptp/ptp_chardev.c
> +++ b/drivers/ptp/ptp_chardev.c
> @@ -123,6 +123,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
> struct timespec64 ts;
> int enable, err = 0;
>
> +#ifdef CONFIG_ARM64
> + static long flag;
> +#endif
> switch (cmd) {
>
> case PTP_CLOCK_GETCAPS:
> @@ -149,6 +152,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
> err = -EFAULT;
> break;
> }
> +
> +#ifdef CONFIG_ARM64
> + /*
> + * Just using this ioctl to tell kvm ptp driver to get PHC
> + * with physical counter, so if bit PTP_KVM_ARM_PHY_COUNTER
> + * is set then just exit directly.
> + * In most cases, we just need virtual counter from host and
> + * there is limited scenario using this to get physical counter
> + * in guest.
> + * Be careful to use this as there is no way to set it back
> + * unless you reinstall the module.
> + * This is only for arm64.
> + */
> + if (req.extts.flags & PTP_KVM_ARM_PHY_COUNTER) {
> + flag = 1;
> + break;
> + }
> +#endif
This file contains the generic PTP Hardware Clock character device
implementation. It is no place for platform specific hacks.
Sorry,
Richard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v12 1/2] media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
From: Laurent Pinchart @ 2020-05-24 1:45 UTC (permalink / raw)
To: Vishal Sagar
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, Jacopo Mondi,
Dinesh Kumar, Hyun Kwon, Sandip Kothari,
linux-kernel@vger.kernel.org, robh+dt@kernel.org,
hans.verkuil@cisco.com, Luca Ceresoli, Michal Simek,
mchehab@kernel.org, Rob Herring,
linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org
In-Reply-To: <BY5PR02MB68679AA1B7CDDC16293EEC12A7A20@BY5PR02MB6867.namprd02.prod.outlook.com>
Hi Vishal,
On Fri, May 08, 2020 at 01:52:36PM +0000, Vishal Sagar wrote:
> On Tuesday, May 5, 2020 7:53 PM, Laurent Pinchart wrote:
> > On Thu, Apr 23, 2020 at 09:00:37PM +0530, Vishal Sagar wrote:
> > > Add bindings documentation for Xilinx MIPI CSI-2 Rx Subsystem.
> > >
> > > The Xilinx MIPI CSI-2 Rx Subsystem consists of a CSI-2 Rx controller,
> > > a D-PHY in Rx mode and a Video Format Bridge.
> > >
> > > Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> > > Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> > > Reviewed-by: Rob Herring <robh@kernel.org>
> > > Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
> > > ---
> > > v12
> > > - Moved to yaml format
> > > - Update CSI-2 and D-PHY
> > > - Mention that bindings for D-PHY not here
> > > - reset -> video-reset
> > >
> > > v11
> > > - Modify compatible string from 4.0 to 5.0
> > >
> > > v10
> > > - No changes
> > >
> > > v9
> > > - Fix xlnx,vfb description.
> > > - s/Optional/Required endpoint property.
> > > - Move data-lanes description from Ports to endpoint property section.
> > >
> > > v8
> > > - Added reset-gpios optional property to assert video_aresetn
> > >
> > > v7
> > > - Removed the control name from dt bindings
> > > - Updated the example dt node name to csi2rx
> > >
> > > v6
> > > - Added "control" after V4L2_CID_XILINX_MIPICSISS_ACT_LANES as
> > > suggested by Luca
> > > - Added reviewed by Rob Herring
> > >
> > > v5
> > > - Incorporated comments by Luca Cersoli
> > > - Removed DPHY clock from description and example
> > > - Removed bayer pattern from device tree MIPI CSI IP
> > > doesn't deal with bayer pattern.
> > >
> > > v4
> > > - Added reviewed by Hyun Kwon
> > >
> > > v3
> > > - removed interrupt parent as suggested by Rob
> > > - removed dphy clock
> > > - moved vfb to optional properties
> > > - Added required and optional port properties section
> > > - Added endpoint property section
> > >
> > > v2
> > > - updated the compatible string to latest version supported
> > > - removed DPHY related parameters
> > > - added CSI v2.0 related property (including VCX for supporting upto 16
> > > virtual channels).
> > > - modified csi-pxl-format from string to unsigned int type where the value
> > > is as per the CSI specification
> > > - Defined port 0 and port 1 as sink and source ports.
> > > - Removed max-lanes property as suggested by Rob and Sakari
> > > .../bindings/media/xilinx/xlnx,csi2rxss.yaml | 215 ++++++++++++++++++
> > > 1 file changed, 215 insertions(+)
> > > create mode 100644
> > > Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > >
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > > b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > > new file mode 100644
> > > index 000000000000..365084e27f7e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yam
> > > +++ l
> > > @@ -0,0 +1,215 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/xilinx/xlnx,csi2rxss.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Xilinx MIPI CSI-2 Receiver Subsystem
> > > +
> > > +maintainers:
> > > + - Vishal Sagar <vishal.sagar@xilinx.com>
> > > +
> > > +description: |
> > > + The Xilinx MIPI CSI-2 Receiver Subsystem is used to capture MIPI CSI-2
> > > + traffic from compliant camera sensors and send the output as AXI4 Stream
> > > + video data for image processing.
> > > + The subsystem consists of a MIPI D-PHY in slave mode which captures the
> > > + data packets. This is passed along the MIPI CSI-2 Rx IP which extracts the
> > > + packet data. The optional Video Format Bridge (VFB) converts this data to
> > > + AXI4 Stream video data.
> > > + For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
> > > + Please note that this bindings includes only the MIPI CSI-2 Rx controller
> > > + and Video Format Bridge and not D-PHY.
> >
> > How should the D-PHY be handled, when DPY_EN_REG_IF is set to true ?
>
> It was suggested in v3 to have a separate D-PHY phy driver which would be initialized / configured from MIPI CSI-2 Rx driver.
> Currently with the D-PHY register interface enabled, we don't have to really configure anything but the following parameters
> 1 - init
> 2 - hs_settle
> 3 - hs_timeout (High Speed mode timeout)
> 4 - esc_timeout (Escape mode timeout)
> 5 - idelay tap
>
> The D-PHY Rx can be enabled/disabled and has a soft reset bit.
> The HS and Escape mode timeout registers can be enabled with a default value via the Vivado IP GUI.
>
> The above parameters would have to be passed to D-PHY driver as custom control via MIPI CSI-2 Rx driver
> as these depend on the sensor connected.
> Probably these can be a new common control in V4L2 framework for CSI Rx controllers.
It seems that in that case, regardless of whether we go for a separate
PHY driver or not, we will be able to extend the DT bindings, either
with a phys property, or with an additional reg entry. That should be
backward-compatible, so I'm not concerned.
> > > +
> > > +properties:
> > > + compatible:
> > > + items:
> > > + - enum:
> > > + - xlnx,mipi-csi2-rx-subsystem-5.0
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + interrupts:
> > > + maxItems: 1
> > > +
> > > + clocks:
> > > + description: List of clock specifiers
> > > + items:
> > > + - description: AXI Lite clock
> > > + - description: Video clock
> > > +
> > > + clock-names:
> > > + items:
> > > + - const: lite_aclk
> > > + - const: video_aclk
> > > +
> > > + xlnx,csi-pxl-format:
> > > + description: |
> > > + This denotes the CSI Data type selected in hw design.
> > > + Packets other than this data type (except for RAW8 and
> > > + User defined data types) will be filtered out.
> > > + Possible values are as below -
> > > + 0x1e - YUV4228B
> > > + 0x1f - YUV42210B
> > > + 0x20 - RGB444
> > > + 0x21 - RGB555
> > > + 0x22 - RGB565
> > > + 0x23 - RGB666
> > > + 0x24 - RGB888
> > > + 0x28 - RAW6
> > > + 0x29 - RAW7
> > > + 0x2a - RAW8
> > > + 0x2b - RAW10
> > > + 0x2c - RAW12
> > > + 0x2d - RAW14
> > > + 0x2e - RAW16
> > > + 0x2f - RAW20
> > > + allOf:
> > > + - $ref: /schemas/types.yaml#/definitions/uint32
> > > + - enum: [0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x28, 0x29,
> > > + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f]
> >
> > This could also be written
> >
> > allOf:
> > - $ref: /schemas/types.yaml#/definitions/uint32
> > - anyOf:
> > - minimum: 0x1e
> > maximum: 0x24
> > - minimum: 0x28
> > maximum: 0x2f
> >
> > if you want to make it a bit more compact (in the number of values, not the
> > number of lines obviously), up to you.
>
> Thanks for sharing this method. I will update this in next version.
>
> > I will also quote the question (and your answer) from the previous
> > version:
> >
> > > > Isn't this property required only when the VFB is present ?
> > >
> > > This will be present irrespective of VFB being enabled.
> > > With VFB, the data on the bus will be as per Xilinx UG934 which is similar to media bus formats.
> > >
> > > Without VFB, it will just be plain data as it comes in data packets.
> > > Refer to the Xilinx PG 232 "Pixel Packing When Video Format Bridge is Not Present"
> > >
> > > So the driver is currently made to load only in case VFB is enabled.
> >
> > I understand that the driver doesn't support the case where the VFB is
> > disabled, but the DT bindings shouldn't care about that. The document of
> > v4.1 of the subsystem states that the width of the video_out port is then
> > selected under "CSI-2 Options TDATA width" (page 11). I however don't such
> > such an option described on pages 55 or 56, but there's an
> > AXIS_TDATA_WIDTH parameter on page 61.
> >
> > Is the pixel format relevant when the VFB is disabled ?
>
> When the VFB is disabled, all supported data types will be allowed i.e. no filtering will occur.
> But the data output will be in 32/64 bit TDATA width (no dependence on pixels per clock) and
> will adhere to the "Recommended Memory Storage" section of the CSI spec.
> In this case data being sent on the bus won't compare to what media bus format documentation describes.
My understanding is that, in the case xlnx,vfb would be absent (not
supported in the driver yet), the xlnx,csi-pxl-format should not be set
? If that's correct, I'd like to capture that in the bindings already.
It could be expressed by dropping xlnx,csi-pxl-format from the required
section, and adding
if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
As you will have two conditions defined, they should be grouped with
allOf:
- if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
- if:
not:
required:
- xlnx,en-csi-v2-0
then:
properties:
xlnx,en-vcx: false
> > > +
> > > + xlnx,vfb:
> > > + type: boolean
> > > + description: Present when Video Format Bridge is enabled in IP
> > > + configuration
> > > +
> > > + xlnx,en-csi-v2-0:
> > > + type: boolean
> > > + description: Present if CSI v2 is enabled in IP configuration.
> > > +
> > > + xlnx,en-vcx:
> > > + type: boolean
> > > + description: |
> > > + When present, there are maximum 16 virtual channels, else
> > > + only 4. This is present only if xlnx,en-csi-v2-0 is present.
> >
> > The last sentence should be removed, and replaced with
> >
> > if:
> > not:
> > required:
> > - xlnx,en-csi-v2-0
> > then:
> > properties:
> > xlnx,en-vcx: false
> >
> > (to be placed after required: and before additionalProperties:).
>
> Got it. Thanks for the tips on YAML.
> I will update this in next version.
>
> > > +
> > > + xlnx,en-active-lanes:
> > > + type: boolean
> > > + description: |
> > > + Present if the number of active lanes can be re-configured at
> > > + runtime in the Protocol Configuration Register. Otherwise all lanes,
> > > + as set in IP configuration, are always active.
> > > +
> > > + video-reset-gpios:
> > > + description: Optional specifier for a GPIO that asserts video_aresetn.
> > > + maxItems: 1
> > > +
> > > + ports:
> > > + type: object
> > > +
> > > + properties:
> > > + port@0:
> > > + type: object
> > > + description: |
> > > + Input / sink port node, single endpoint describing the
> > > + CSI-2 transmitter.
> > > +
> > > + properties:
> > > + reg:
> > > + const: 0
> > > +
> > > + endpoint:
> > > + type: object
> > > +
> > > + properties:
> > > +
> > > + data-lanes:
> > > + description: |
> > > + This is required only in the sink port 0 endpoint which
> > > + connects to MIPI CSI-2 source like sensor.
> > > + The possible values are -
> > > + 1 - For 1 lane enabled in IP.
> > > + 1 2 - For 2 lanes enabled in IP.
> > > + 1 2 3 - For 3 lanes enabled in IP.
> > > + 1 2 3 4 - For 4 lanes enabled in IP.
> > > + items:
> > > + - const: 1
> > > + - const: 2
> > > + - const: 3
> > > + - const: 4
> > > +
> > > + remote-endpoint: true
> > > +
> > > + required:
> > > + - data-lanes
> > > + - remote-endpoint
> > > +
> > > + additionalProperties: false
> > > +
> > > + additionalProperties: false
> > > +
> > > + port@1:
> > > + type: object
> > > + description: |
> > > + Output / source port node, endpoint describing modules
> > > + connected the CSI-2 receiver.
> > > +
> > > + properties:
> > > +
> > > + reg:
> > > + const: 1
> > > +
> > > + endpoint:
> > > + type: object
> > > +
> > > + properties:
> > > +
> > > + remote-endpoint: true
> > > +
> > > + required:
> > > + - remote-endpoint
> > > +
> > > + additionalProperties: false
> > > +
> > > + additionalProperties: false
> > > +
> > > +required:
> > > + - compatible
> > > + - reg
> > > + - interrupts
> > > + - clocks
> > > + - clock-names
> > > + - xlnx,csi-pxl-format
> > > + - ports
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > + - |
> > > + #include <dt-bindings/gpio/gpio.h>
> > > + xcsi2rxss_1: csi2rx@a0020000 {
> > > + compatible = "xlnx,mipi-csi2-rx-subsystem-5.0";
> > > + reg = <0x0 0xa0020000 0x0 0x10000>;
> > > + interrupt-parent = <&gic>;
> > > + interrupts = <0 95 4>;
> > > + xlnx,csi-pxl-format = <0x2a>;
> > > + xlnx,vfb;
> > > + xlnx,en-active-lanes;
> > > + xlnx,en-csi-v2-0;
> > > + xlnx,en-vcx;
> > > + clock-names = "lite_aclk", "video_aclk";
> > > + clocks = <&misc_clk_0>, <&misc_clk_1>;
> > > + video-reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
> > > +
> > > + ports {
> > > + #address-cells = <1>;
> > > + #size-cells = <0>;
> > > +
> > > + port@0 {
> > > + /* Sink port */
> > > + reg = <0>;
> > > + csiss_in: endpoint {
> > > + data-lanes = <1 2 3 4>;
> > > + /* MIPI CSI-2 Camera handle */
> > > + remote-endpoint = <&camera_out>;
> > > + };
> > > + };
> > > + port@1 {
> > > + /* Source port */
> > > + reg = <1>;
> > > + csiss_out: endpoint {
> > > + remote-endpoint = <&vproc_in>;
> > > + };
> > > + };
> > > + };
> > > + };
--
Regards,
Laurent Pinchart
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH v12 09/11] ptp: extend input argument for getcrosstimestamp API
From: Richard Cochran @ 2020-05-24 1:42 UTC (permalink / raw)
To: Jianyong Wu
Cc: Mark.Rutland, maz, justin.he, Wei.Chen, kvm, suzuki.poulose,
netdev, Steve.Capper, linux-kernel, sean.j.christopherson,
steven.price, Kaly.Xin, john.stultz, yangbo.lu, pbonzini, tglx,
nd, will, kvmarm, linux-arm-kernel
In-Reply-To: <20200522083724.38182-10-jianyong.wu@arm.com>
On Fri, May 22, 2020 at 04:37:22PM +0800, Jianyong Wu wrote:
> sometimes we may need tell getcrosstimestamp call back how to perform
> itself. Extending input arguments for getcrosstimestamp API to offer more
> exquisite control for the operation.
This text does not offer any justification for the change in API.
> diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
> index c602670bbffb..ba765647e54b 100644
> --- a/include/linux/ptp_clock_kernel.h
> +++ b/include/linux/ptp_clock_kernel.h
> @@ -133,7 +133,8 @@ struct ptp_clock_info {
> int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts,
> struct ptp_system_timestamp *sts);
> int (*getcrosststamp)(struct ptp_clock_info *ptp,
> - struct system_device_crosststamp *cts);
> + struct system_device_crosststamp *cts,
> + long *flag);
Well, you ignored the kernel doc completely. But in any case, I must
NAK this completely opaque and mysterious change. You want to add a
random pointer to some flag? I don't think so.
Thanks,
Richard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox