[PATCH] staging: pi433: fix potential null dereference
Add a test for successful call to cdev_alloc() to avoid potential null dereference. Issue reported by smatch. Signed-off-by: Michael Straube --- drivers/staging/pi433/pi433_if.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c index 786478671190..d72de2105053 100644 --- a/drivers/staging/pi433/pi433_if.c +++ b/drivers/staging/pi433/pi433_if.c @@ -1245,6 +1245,10 @@ static int pi433_probe(struct spi_device *spi) /* create cdev */ device->cdev = cdev_alloc(); + if (!device->cdev) { + dev_dbg(device->dev, "allocation of cdev failed"); + goto cdev_failed; + } device->cdev->owner = THIS_MODULE; cdev_init(device->cdev, &pi433_fops); retval = cdev_add(device->cdev, device->devt, 1); -- 2.19.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 7/7] staging:iio:ad2s90: Move out of staging
On Fri, 23 Nov 2018 22:23:12 -0200 Matheus Tavares wrote: > Move ad2s90 resolver driver out of staging to the main tree. > > Signed-off-by: Matheus Tavares > Signed-off-by: Victor Colombo Hi. One totally trivial comment inline, but if you want to clean that up, do it after we have moved this out of staging (unless respinning for some other reason). However, I would like to let this sit on the mailing list for a little longer to let others comment and perhaps to pick up a review of the DT binding doc (which looks fine to me, but I am forever missing issues in those!) Good work and I'll probably pick this up later in the week. Thanks, Jonathan > --- > Changes in v3: > - none > > Changes in v2: > - Disabled git move detection, to see the whole code, as Jonathan > suggested > > drivers/iio/resolver/Kconfig | 10 ++ > drivers/iio/resolver/Makefile | 1 + > drivers/iio/resolver/ad2s90.c | 131 ++ > drivers/staging/iio/resolver/Kconfig | 10 -- > drivers/staging/iio/resolver/Makefile | 1 - > drivers/staging/iio/resolver/ad2s90.c | 131 -- > 6 files changed, 142 insertions(+), 142 deletions(-) > create mode 100644 drivers/iio/resolver/ad2s90.c > delete mode 100644 drivers/staging/iio/resolver/ad2s90.c > > diff --git a/drivers/iio/resolver/Kconfig b/drivers/iio/resolver/Kconfig > index 2ced9f22aa70..786801be54f6 100644 > --- a/drivers/iio/resolver/Kconfig > +++ b/drivers/iio/resolver/Kconfig > @@ -3,6 +3,16 @@ > # > menu "Resolver to digital converters" > > +config AD2S90 > + tristate "Analog Devices ad2s90 driver" > + depends on SPI > + help > + Say yes here to build support for Analog Devices spi resolver > + to digital converters, ad2s90, provides direct access via sysfs. > + > + To compile this driver as a module, choose M here: the > + module will be called ad2s90. > + > config AD2S1200 > tristate "Analog Devices ad2s1200/ad2s1205 driver" > depends on SPI > diff --git a/drivers/iio/resolver/Makefile b/drivers/iio/resolver/Makefile > index 4e1dccae07e7..398d82d50028 100644 > --- a/drivers/iio/resolver/Makefile > +++ b/drivers/iio/resolver/Makefile > @@ -2,4 +2,5 @@ > # Makefile for Resolver/Synchro drivers > # > > +obj-$(CONFIG_AD2S90) += ad2s90.o > obj-$(CONFIG_AD2S1200) += ad2s1200.o > diff --git a/drivers/iio/resolver/ad2s90.c b/drivers/iio/resolver/ad2s90.c > new file mode 100644 > index ..a41f5cb10da5 > --- /dev/null > +++ b/drivers/iio/resolver/ad2s90.c > @@ -0,0 +1,131 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ad2s90.c simple support for the ADI Resolver to Digital Converters: AD2S90 > + * > + * Copyright (c) 2010-2010 Analog Devices Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include We are into the truely trivial realms now - alphabetical order preferred for includes. > + > +#include > +#include > + > +/* > + * Although chip's max frequency is 2Mhz, it needs 600ns between CS and the > + * first falling edge of SCLK, so frequency should be at most 1 / (2 * 6e-7) > + */ > +#define AD2S90_MAX_SPI_FREQ_HZ 83 > + > +struct ad2s90_state { > + struct mutex lock; /* lock to protect rx buffer */ > + struct spi_device *sdev; > + u8 rx[2] cacheline_aligned; > +}; > + > +static int ad2s90_read_raw(struct iio_dev *indio_dev, > +struct iio_chan_spec const *chan, > +int *val, > +int *val2, > +long m) > +{ > + int ret; > + struct ad2s90_state *st = iio_priv(indio_dev); > + > + if (chan->type != IIO_ANGL) > + return -EINVAL; > + > + switch (m) { > + case IIO_CHAN_INFO_SCALE: > + /* 2 * Pi / 2^12 */ > + *val = 6283; /* mV */ > + *val2 = 12; > + return IIO_VAL_FRACTIONAL_LOG2; > + case IIO_CHAN_INFO_RAW: > + mutex_lock(&st->lock); > + ret = spi_read(st->sdev, st->rx, 2); > + if (ret < 0) { > + mutex_unlock(&st->lock); > + return ret; > + } > + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); > + > + mutex_unlock(&st->lock); > + > + return IIO_VAL_INT; > + default: > + break; > + } > + > + return -EINVAL; > +} > + > +static const struct iio_info ad2s90_info = { > + .read_raw = ad2s90_read_raw, > +}; > + > +static const struct iio_chan_spec ad2s90_chan = { > + .type = IIO_ANGL, > + .indexed = 1, > + .channel = 0, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), > +}; > + > +static int ad2s90_probe(struct spi_device *spi) > +{ > + struct iio_dev *indio_dev; > + struct ad2s90_state *st; > + > + if (spi->max_speed_hz > AD2S90_MAX_SPI_FREQ_HZ) { > + dev_err(&spi->dev,
Re: [PATCH v2] staging: iio: ad5933: add device tree support
On Sat, 24 Nov 2018 11:18:57 -0200 Marcelo Schmitt wrote: > Add a of_device_id struct variable and subsequent call to > MODULE_DEVICE_TABLE macro to complete device tree support. > > Signed-off-by: Marcelo Schmitt Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Note we'll need a binding doc for this before it can leave staging. Thanks, Jonathan > --- > drivers/staging/iio/impedance-analyzer/ad5933.c | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c > b/drivers/staging/iio/impedance-analyzer/ad5933.c > index edb8b540bbf1..6faa2700dc8d 100644 > --- a/drivers/staging/iio/impedance-analyzer/ad5933.c > +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c > @@ -771,9 +771,18 @@ static const struct i2c_device_id ad5933_id[] = { > > MODULE_DEVICE_TABLE(i2c, ad5933_id); > > +static const struct of_device_id ad5933_of_match[] = { > + { .compatible = "adi,ad5933" }, > + { .compatible = "adi,ad5934" }, > + { }, > +}; > + > +MODULE_DEVICE_TABLE(of, ad5933_of_match); > + > static struct i2c_driver ad5933_driver = { > .driver = { > .name = "ad5933", > + .of_match_table = ad5933_of_match, > }, > .probe = ad5933_probe, > .remove = ad5933_remove, ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v4] staging: olpc_dcon: olpc_dcon_xo_1.c: Switch to the gpio descriptor interface
Hi! > Use the gpiod interface instead of the deprecated old non-descriptor > interface in olpc_dcon_xo_1.c. > > Signed-off-by: Nishad Kamdar You may want to cc: lkund...@v3.sk, he was doing great work on OLPC lately... Best regards, Pavel > --- > Changes in v4: > - Move changelog after signed-off line. > Changes in v3: > - Resolve a few compilation errors. > Changes in v2: > - Resolve a few compilation errors. > - Add a level of indirection to read and write gpios. > --- > drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | 90 +++--- > 1 file changed, 47 insertions(+), 43 deletions(-) > > diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c > b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c > index ff145d493e1b..80b8d4153414 100644 > --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c > +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c > @@ -11,35 +11,51 @@ > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > #include > -#include > +#include > #include > +#include > #include > > #include "olpc_dcon.h" > > +enum dcon_gpios { > + OLPC_DCON_STAT0, > + OLPC_DCON_STAT1, > + OLPC_DCON_IRQ, > + OLPC_DCON_LOAD, > + OLPC_DCON_BLANK, > +}; > + > +struct dcon_gpio { > + const char *name; > + unsigned long flags; > +}; > + > +static const struct dcon_gpio gpios_asis[] = { > + [OLPC_DCON_STAT0] = { .name = "dcon_stat0", .flags = GPIOD_ASIS }, > + [OLPC_DCON_STAT1] = { .name = "dcon_stat1", .flags = GPIOD_ASIS }, > + [OLPC_DCON_IRQ] = { .name = "dcon_irq", .flags = GPIOD_ASIS }, > + [OLPC_DCON_LOAD] = { .name = "dcon_load", .flags = GPIOD_ASIS }, > + [OLPC_DCON_BLANK] = { .name = "dcon_blank", .flags = GPIOD_ASIS }, > +}; > + > +struct gpio_desc *gpios[5]; > + > static int dcon_init_xo_1(struct dcon_priv *dcon) > { > unsigned char lob; > - > - if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) { > - pr_err("failed to request STAT0 GPIO\n"); > - return -EIO; > - } > - if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) { > - pr_err("failed to request STAT1 GPIO\n"); > - goto err_gp_stat1; > - } > - if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) { > - pr_err("failed to request IRQ GPIO\n"); > - goto err_gp_irq; > - } > - if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) { > - pr_err("failed to request LOAD GPIO\n"); > - goto err_gp_load; > - } > - if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) { > - pr_err("failed to request BLANK GPIO\n"); > - goto err_gp_blank; > + int ret, i; > + struct dcon_gpio *pin = &gpios_asis[0]; > + > + for (i = 0; i < ARRAY_SIZE(gpios_asis); i++) { > + gpios[i] = devm_gpiod_get(&dcon->client->dev, pin[i].name, > + pin[i].flags); > + if (IS_ERR(gpios[i])) { > + ret = PTR_ERR(gpios[i]); > + pr_err("failed to request %s GPIO: %d\n", pin[i].name, > +ret); > + return ret; > + } > } > > /* Turn off the event enable for GPIO7 just to be safe */ > @@ -61,12 +77,12 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) > dcon->pending_src = dcon->curr_src; > > /* Set the directions for the GPIO pins */ > - gpio_direction_input(OLPC_GPIO_DCON_STAT0); > - gpio_direction_input(OLPC_GPIO_DCON_STAT1); > - gpio_direction_input(OLPC_GPIO_DCON_IRQ); > - gpio_direction_input(OLPC_GPIO_DCON_BLANK); > - gpio_direction_output(OLPC_GPIO_DCON_LOAD, > - dcon->curr_src == DCON_SOURCE_CPU); > + gpiod_direction_input(gpios[OLPC_DCON_STAT0]); > + gpiod_direction_input(gpios[OLPC_DCON_STAT1]); > + gpiod_direction_input(gpios[OLPC_DCON_IRQ]); > + gpiod_direction_input(gpios[OLPC_DCON_BLANK]); > + gpiod_direction_output(gpios[OLPC_DCON_LOAD], > +dcon->curr_src == DCON_SOURCE_CPU); > > /* Set up the interrupt mappings */ > > @@ -84,7 +100,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) > /* Register the interrupt handler */ > if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) { > pr_err("failed to request DCON's irq\n"); > - goto err_req_irq; > + return -EIO; > } > > /* Clear INV_EN for GPIO7 (DCONIRQ) */ > @@ -125,18 +141,6 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) > cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_EVENTS_ENABLE); > > return 0; > - > -err_req_irq: > - gpio_free(OLPC_GPIO_DCON_BLANK); > -err_gp_blank: > - gpio_free(OLPC_GPIO_DCON_LOAD); > -err_gp_load: > - gpio_free(OLPC_GPIO_DCON_IRQ); > -err_gp_irq: > - gpio_free(OLPC_GPIO_DCON_STAT1); > -err_gp_stat1: > - gpio_free(OLPC_GPI
Re: [PATCH] staging: iio: ad5933: replaced kfifo by triggered_buffer
On Thu, 22 Nov 2018 10:53:47 -0200 Marcelo Schmitt wrote: > Previously, there was an implicit creation of a kfifo which was replaced > by a call to triggered_buffer_setup, which is already implemented in iio > infrastructure. > > Signed-off-by: Marcelo Schmitt I'm a little surprised that this would work without screaming a lot as it will register an interrupt with no handlers. Do you have this device to test? It's rapidly heading in the direction of too complex a driver to fix without test hardware. Also, semantically this change is not sensible as it implies an operating mode which the driver is not using. There are fundamental questions about how we handle an autotriggered sweep that need answering before this driver can move forwards. It needs some concept of a higher level trigger rather than a per sample one like we typically use in IIO. The main focus in the short term should be around defining that ABI as it may fundamentally change the structure of the driver. If you want to take this on (and it'll be a big job I think!) then it may be possible to source some hardware to support that effort. Thanks, Jonathan > --- > .../staging/iio/impedance-analyzer/Kconfig| 2 +- > .../staging/iio/impedance-analyzer/ad5933.c | 25 --- > 2 files changed, 6 insertions(+), 21 deletions(-) > > diff --git a/drivers/staging/iio/impedance-analyzer/Kconfig > b/drivers/staging/iio/impedance-analyzer/Kconfig > index dd97b6bb3fd0..d0af5aa55dc0 100644 > --- a/drivers/staging/iio/impedance-analyzer/Kconfig > +++ b/drivers/staging/iio/impedance-analyzer/Kconfig > @@ -7,7 +7,7 @@ config AD5933 > tristate "Analog Devices AD5933, AD5934 driver" > depends on I2C > select IIO_BUFFER > - select IIO_KFIFO_BUF > + select IIO_TRIGGERED_BUFFER > help > Say yes here to build support for Analog Devices Impedance Converter, > Network Analyzer, AD5933/4, provides direct access via sysfs. > diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c > b/drivers/staging/iio/impedance-analyzer/ad5933.c > index f9bcb8310e21..edb8b540bbf1 100644 > --- a/drivers/staging/iio/impedance-analyzer/ad5933.c > +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c > @@ -20,7 +20,7 @@ > #include > #include > #include > -#include > +#include > > /* AD5933/AD5934 Registers */ > #define AD5933_REG_CONTROL_HB0x80/* R/W, 1 byte */ > @@ -615,22 +615,6 @@ static const struct iio_buffer_setup_ops > ad5933_ring_setup_ops = { > .postdisable = ad5933_ring_postdisable, > }; > > -static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) > -{ > - struct iio_buffer *buffer; > - > - buffer = iio_kfifo_allocate(); > - if (!buffer) > - return -ENOMEM; > - > - iio_device_attach_buffer(indio_dev, buffer); > - > - /* Ring buffer functions - here trigger setup related */ > - indio_dev->setup_ops = &ad5933_ring_setup_ops; > - > - return 0; > -} > - > static void ad5933_work(struct work_struct *work) > { > struct ad5933_state *st = container_of(work, > @@ -744,7 +728,8 @@ static int ad5933_probe(struct i2c_client *client, > indio_dev->channels = ad5933_channels; > indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); > > - ret = ad5933_register_ring_funcs_and_init(indio_dev); > + ret = iio_triggered_buffer_setup(indio_dev, NULL, NULL, > + &ad5933_ring_setup_ops); The absence of either of the interrupt related callbacks made me wonder what is going on here. The upshot is that this device isn't operating in a triggered buffer style at all so we really shouldn't be using that infrastructure - even if it's convenient. It'll allocate an interrupt with neither a top half nor a thread function. I'm not sure what the core will do about that but it seems unlikely to be happy about it! > if (ret) > goto error_disable_reg; > > @@ -759,7 +744,7 @@ static int ad5933_probe(struct i2c_client *client, > return 0; > > error_unreg_ring: > - iio_kfifo_free(indio_dev->buffer); > + iio_triggered_buffer_cleanup(indio_dev); > error_disable_reg: > regulator_disable(st->reg); > > @@ -772,7 +757,7 @@ static int ad5933_remove(struct i2c_client *client) > struct ad5933_state *st = iio_priv(indio_dev); > > iio_device_unregister(indio_dev); > - iio_kfifo_free(indio_dev->buffer); > + iio_triggered_buffer_cleanup(indio_dev); > regulator_disable(st->reg); > > return 0; ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: iio: ad7780: Add gain & filter gpio support
On Thu, 22 Nov 2018 11:01:00 + "Popa, Stefan Serban" wrote: > On Mi, 2018-11-21 at 16:04 -0200, Giuliano Belinassi wrote: > > Previously, the AD7780 driver only supported gpio for the 'powerdown' > > pin. This commit adds suppport for the 'gain' and 'filter' pin. > Hey, > > Comments inline. > > > > Signed-off-by: Giuliano Belinassi > > --- > > drivers/staging/iio/adc/ad7780.c | 61 -- > > include/linux/iio/adc/ad_sigma_delta.h | 5 +++ > > 2 files changed, 62 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/staging/iio/adc/ad7780.c > > b/drivers/staging/iio/adc/ad7780.c > > index c4a85789c2db..69794f06dbcd 100644 > > --- a/drivers/staging/iio/adc/ad7780.c > > +++ b/drivers/staging/iio/adc/ad7780.c > > @@ -39,6 +39,9 @@ > > #define AD7170_PATTERN (AD7780_PAT0 | AD7170_PAT2) > > #define AD7170_PATTERN_MASK(AD7780_PAT0 | AD7780_PAT1 | > > AD7170_PAT2) > > > > +#define AD7780_GAIN_GPIO 0 > > +#define AD7780_FILTER_GPIO 1 > > + > > struct ad7780_chip_info { > > struct iio_chan_specchannel; > > unsigned intpattern_mask; > > @@ -50,6 +53,8 @@ struct ad7780_state { > > const struct ad7780_chip_info *chip_info; > > struct regulator*reg; > > struct gpio_desc*powerdown_gpio; > > + struct gpio_desc*gain_gpio; > > + struct gpio_desc*filter_gpio; > > unsigned intgain; > > > > struct ad_sigma_delta sd; > > @@ -115,18 +120,51 @@ static int ad7780_read_raw(struct iio_dev > > *indio_dev, > > return -EINVAL; > > } > > > > +static int ad7780_write_raw(struct iio_dev *indio_dev, > > + struct iio_chan_spec const *chan, > > + int val, > > + int val2, > > + long m) > > +{ > > + struct ad7780_state *st = iio_priv(indio_dev); > > + > > + if (m != IIO_CHAN_INFO_RAW) > > + return -EINVAL; > > + > > + if (st->chip_info->is_ad778x) { > > + switch(val) { > > + case AD7780_GAIN_GPIO: > > I think that instead of setting the gain directly, we should use > the IIO_CHAN_INFO_SCALE attribute. At page 12 of the ad7780 datasheet there > is a formula from which the output code can be calculated: > Code = 2^(N − 1) > × [(AIN × Gain /VREF) + 1]. So, by setting the scale from user space, the > driver can calculate the correct gain by using the formula above. Also, it > would be useful to introduce scale available. > Furthermore, there is a new > ad7124 adc driver which does this exact thing. Take a look here: https://gi > thub.com/analogdevicesinc/linux/blob/master/drivers/iio/adc/ad7124.c#L337. > > > + gpiod_set_value(st->gain_gpio, val2); > > + break; > > + case AD7780_FILTER_GPIO: > > The attribute that should be used to configure the filter gpio is > IIO_CHAN_INFO_SAMP_FREQ. So, we should have 10 Hz and 16.7 Hz available > sampling frequencies. If from user space the 10 Hz sampling freq is > requested, then we set the FILTER pin high, while for 16.7 Hz the FILTER > pin will be low. Absolutely agreed with Stefan here. If it had been decoupled from sampling frequency (sometimes they are) then we have specific controls for filters as well. Here it directly effects the sampling frequency. Please in future avoid any driver specific control like you have here. I haven't really worked out what the interface is beyond some sort of bitmap passed through a write to a magic channel? If there isn't an existing interface in IIO for what you want to do please propose one rather than doing something that will only work with a particular userspace. One of the primary purposes of having a subsystem is to standardise interfaces. This definitely doesn't do that! Will be good to have the support along the lines Stefan suggested though! Thanks, Jonathan > > > + gpiod_set_value(st->filter_gpio, val2); > > + break; > > + default: > > + return -EINVAL; > > + } > > + } > > + > > + return 0; > > +} > > + > > static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, > > unsigned int raw_sample) > > { > > struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); > > const struct ad7780_chip_info *chip_info = st->chip_info; > > + int val; > > > > if ((raw_sample & AD7780_ERR) || > > ((raw_sample & chip_info->pattern_mask) != chip_info- > > >pattern)) > > return -EIO; > > > > if (chip_info->is_ad778x) { > > - if (raw_sample & AD7780_GAIN) > > + val = raw_sample & AD7780_GAIN; > > + > > + if (val != gpiod_get_value(st->gain_gpio)) > > + return -EIO; > > + > > + if (val) > > st->gain = 1; > > else > > st->gain = 12
[PATCH 00/26] Staging: fbtft: Switch to the gpio descriptor interface
This switches the fbtft driver to use GPIO descriptors rather than numerical gpios. Nishad Kamdar (26): Staging: fbtft: fbtft-core: Switch to the gpio descriptor interface Staging: fbtft: fbtft-bus: Switch to the gpio descriptor interface Staging: fbtft: fbtft-io: Switch to the gpio descriptor interface Staging: fbtft: flexfb: Switch to the gpio descriptor interface Staging: fbtft: fbtft-device: Switch to the gpio descriptor interface Staging: fbtft: fb_upd161704: Switch to the gpio descriptor interface Staging: fbtft: fb_sh1106: Switch to the gpio descriptor interface Staging: fbtft: fb_uc1611: Switch to the gpio descriptor interface Staging: fbtft: fb_s6d1211: Switch to the gpio descriptor interface Staging: fbtft: fb_ili9320: Switch to the gpio descriptor interface Staging: fbtft: fb_ili9340: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1325: Switch to the gpio descriptor interface Staging: fbtft: fb_ili9325: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1289: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1351: Switch to the gpio descriptor interface Staging: fbtft: fb_uc1701: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1306: Switch to the gpio descriptor interface Staging: fbtft: fb_bd663474: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1331: Switch to the gpio descriptor interface Staging: fbtft: fb_ili9163: Switch to the gpio descriptor interface Staging: fbtft: fb_agm1264k-fl: Switch to the gpio descriptor interface Staging: fbtft: fb_pcd8544: Switch to the gpio descriptor interface Staging: fbtft: fb_ssd1305: Switch to the gpio descriptor interface Staging: fbtft: fb_tls8204: Switch to the gpio descriptor interface Staging: fbtft: fb_watterott: Switch to the gpio descriptor interface Staging: fbtft: fb_ra8875: Switch to the gpio descriptor interface drivers/staging/fbtft/fb_agm1264k-fl.c | 52 ++-- drivers/staging/fbtft/fb_bd663474.c| 6 +- drivers/staging/fbtft/fb_ili9163.c | 6 +- drivers/staging/fbtft/fb_ili9320.c | 2 +- drivers/staging/fbtft/fb_ili9325.c | 6 +- drivers/staging/fbtft/fb_ili9340.c | 2 +- drivers/staging/fbtft/fb_pcd8544.c | 4 +- drivers/staging/fbtft/fb_ra8875.c | 4 +- drivers/staging/fbtft/fb_s6d1121.c | 6 +- drivers/staging/fbtft/fb_sh1106.c | 2 +- drivers/staging/fbtft/fb_ssd1289.c | 6 +- drivers/staging/fbtft/fb_ssd1305.c | 4 +- drivers/staging/fbtft/fb_ssd1306.c | 4 +- drivers/staging/fbtft/fb_ssd1325.c | 6 +- drivers/staging/fbtft/fb_ssd1331.c | 10 +- drivers/staging/fbtft/fb_ssd1351.c | 2 +- drivers/staging/fbtft/fb_tls8204.c | 6 +- drivers/staging/fbtft/fb_uc1611.c | 4 +- drivers/staging/fbtft/fb_uc1701.c | 6 +- drivers/staging/fbtft/fb_upd161704.c | 6 +- drivers/staging/fbtft/fb_watterott.c | 4 +- drivers/staging/fbtft/fbtft-bus.c | 6 +- drivers/staging/fbtft/fbtft-core.c | 170 ++-- drivers/staging/fbtft/fbtft-io.c | 26 +- drivers/staging/fbtft/fbtft.h | 21 +- drivers/staging/fbtft/fbtft_device.c | 344 + drivers/staging/fbtft/flexfb.c | 12 +- 27 files changed, 142 insertions(+), 585 deletions(-) -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 01/26] Staging: fbtft: fbtft-core: Switch to the gpio descriptor interface
This switches the fbtft-core to use GPIO descriptors rather than numerical gpios: Utilize the GPIO library's intrinsic handling of OF GPIOs and polarity. If the line is flagged active low, gpiolib will deal with this. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fbtft-core.c | 127 - drivers/staging/fbtft/fbtft.h | 22 ++--- 2 files changed, 61 insertions(+), 88 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index a2df02d97a8e..75ee16074126 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "fbtft.h" @@ -38,8 +37,8 @@ int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc) { int ret; - if (gpio_is_valid(par->gpio.dc)) - gpio_set_value(par->gpio.dc, dc); + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, dc); ret = par->fbtftops.write(par, buf, len); if (ret < 0) @@ -72,7 +71,7 @@ void fbtft_dbg_hex(const struct device *dev, int groupsize, EXPORT_SYMBOL(fbtft_dbg_hex); static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, - const struct fbtft_gpio *gpio) + struct fbtft_gpio *gpio) { int ret; unsigned int val; @@ -82,34 +81,34 @@ static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, if (strcasecmp(gpio->name, "reset") == 0) { par->gpio.reset = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "dc") == 0) { par->gpio.dc = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (strcasecmp(gpio->name, "cs") == 0) { par->gpio.cs = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "wr") == 0) { par->gpio.wr = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "rd") == 0) { par->gpio.rd = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "latch") == 0) { par->gpio.latch = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') { ret = kstrtouint(&gpio->name[2], 10, &val); if (ret == 0 && val < 16) { par->gpio.db[val] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } } else if (strcasecmp(gpio->name, "led") == 0) { par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (strcasecmp(gpio->name, "led_") == 0) { par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } return FBTFT_GPIO_NO_MATCH; @@ -118,7 +117,8 @@ static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, static int fbtft_request_gpios(struct fbtft_par *par) { struct fbtft_platform_data *pdata = par->pdata; - const struct fbtft_gpio *gpio; + struct device *dev = par->info->device; + struct fbtft_gpio *gpio; unsigned long flags; int ret; @@ -136,19 +136,19 @@ static int fbtft_request_gpios(struct fbtft_par *par) if (flags == FBTFT_GPIO_NO_MATCH) flags = fbtft_request_gpios_match(par, gpio); if (flags != FBTFT_GPIO_NO_MATCH) { - ret = devm_gpio_request_one(par->info->device, - gpio->gpio, flags, - par->info->device->driver->name); - if (ret < 0) { - dev_err(par->info->device, - "%s: gpio_request_one('%s'=%d) failed with %d\n", - __func__, gpio->name, - gpio->gpio, ret); + gpio->gpio = devm_gpiod_get(dev, + dev->driver->name, flags); + if (IS_ERR(gpio->gpio)) { + ret = PTR_ERR(gpio->gpio); + dev_err(dev, + "%
[PATCH 02/26] Staging: fbtft: fbtft-bus: Switch to the gpio descriptor interface
This switches the fbtft-bus to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fbtft-bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index 8ce1ff9b6c2a..2ea814d0dca5 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include +#include #include #include "fbtft.h" @@ -135,8 +135,8 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) remain = len / 2; vmem16 = (u16 *)(par->info->screen_buffer + offset); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); /* non buffered write */ if (!par->txbuf.buf) -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/26] Staging: fbtft: fbtft-io: Switch to the gpio descriptor interface
This switches the fbtft-io to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fbtft-io.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index b5051d3d46a6..38cdad6203ea 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include +#include #include #include "fbtft.h" @@ -142,30 +142,30 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u8 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 8; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 8; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u8 *)buf; @@ -192,30 +192,30 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u16 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 16; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 16; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u16 *)buf; -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/26] Staging: fbtft: flexfb: Switch to the gpio descriptor interface
This switches the flexfb.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/flexfb.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index 2af474469e7d..c5fa59105a43 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -521,7 +521,7 @@ static int flexfb_verify_gpios_dc(struct fbtft_par *par) { fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; @@ -537,22 +537,22 @@ static int flexfb_verify_gpios_db(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; } - if (par->gpio.wr < 0) { + if (!par->gpio.wr) { dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n"); return -EINVAL; } - if (latched && (par->gpio.latch < 0)) { + if (latched && !par->gpio.latch) { dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n"); return -EINVAL; } if (latched) num_db = buswidth / 2; for (i = 0; i < num_db; i++) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/26] Staging: fbtft: fbtft-device: Switch to the gpio descriptor interface
This switches the fbtft-device.c to use GPIO descriptors rather than numerical gpios: Remove gpios from platform device structure. Neither assign statically numbers to gpios in platform device nor allow gpios to be parsed as module parameters. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fbtft-core.c | 87 --- drivers/staging/fbtft/fbtft.h| 1 - drivers/staging/fbtft/fbtft_device.c | 344 +-- 3 files changed, 8 insertions(+), 424 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 75ee16074126..904ba7470abf 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -70,92 +70,6 @@ void fbtft_dbg_hex(const struct device *dev, int groupsize, } EXPORT_SYMBOL(fbtft_dbg_hex); -static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, - struct fbtft_gpio *gpio) -{ - int ret; - unsigned int val; - - fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n", - __func__, gpio->name); - - if (strcasecmp(gpio->name, "reset") == 0) { - par->gpio.reset = gpio->gpio; - return GPIOD_OUT_HIGH; - } else if (strcasecmp(gpio->name, "dc") == 0) { - par->gpio.dc = gpio->gpio; - return GPIOD_OUT_LOW; - } else if (strcasecmp(gpio->name, "cs") == 0) { - par->gpio.cs = gpio->gpio; - return GPIOD_OUT_HIGH; - } else if (strcasecmp(gpio->name, "wr") == 0) { - par->gpio.wr = gpio->gpio; - return GPIOD_OUT_HIGH; - } else if (strcasecmp(gpio->name, "rd") == 0) { - par->gpio.rd = gpio->gpio; - return GPIOD_OUT_HIGH; - } else if (strcasecmp(gpio->name, "latch") == 0) { - par->gpio.latch = gpio->gpio; - return GPIOD_OUT_LOW; - } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') { - ret = kstrtouint(&gpio->name[2], 10, &val); - if (ret == 0 && val < 16) { - par->gpio.db[val] = gpio->gpio; - return GPIOD_OUT_LOW; - } - } else if (strcasecmp(gpio->name, "led") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOD_OUT_LOW; - } else if (strcasecmp(gpio->name, "led_") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOD_OUT_HIGH; - } - - return FBTFT_GPIO_NO_MATCH; -} - -static int fbtft_request_gpios(struct fbtft_par *par) -{ - struct fbtft_platform_data *pdata = par->pdata; - struct device *dev = par->info->device; - struct fbtft_gpio *gpio; - unsigned long flags; - int ret; - - if (!(pdata && pdata->gpios)) - return 0; - - gpio = pdata->gpios; - while (gpio->name[0]) { - flags = FBTFT_GPIO_NO_MATCH; - /* if driver provides match function, try it first, -* if no match use our own -*/ - if (par->fbtftops.request_gpios_match) - flags = par->fbtftops.request_gpios_match(par, gpio); - if (flags == FBTFT_GPIO_NO_MATCH) - flags = fbtft_request_gpios_match(par, gpio); - if (flags != FBTFT_GPIO_NO_MATCH) { - gpio->gpio = devm_gpiod_get(dev, - dev->driver->name, flags); - if (IS_ERR(gpio->gpio)) { - ret = PTR_ERR(gpio->gpio); - dev_err(dev, - "%s: Failed to request %s GPIO:%d\n", - __func__, gpio->name, ret); - return ret; - - } - fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, - "%s: '%s' GPIO\n", - __func__, gpio->name); - } - gpio++; - } - - return 0; -} - #ifdef CONFIG_OF static int fbtft_request_one_gpio(struct fbtft_par *par, const char *name, int index, @@ -836,7 +750,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, par->fbtftops.reset = fbtft_reset; par->fbtftops.mkdirty = fbtft_mkdirty; par->fbtftops.update_display = fbtft_update_display; - par->fbtftops.request_gpios = fbtft_request_gpios; if (display->backlight) par->fbtftops.register_backlight = fbtft_register_backlight; diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index a9eed11c29b0..7fdd3b0851ef 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -134,7 +134,6 @@ struct fbtft_display { */ s
[PATCH 07/26] Staging: fbtft: fb_sh1106: Switch to the gpio descriptor interface
This switches the fb_sh1106.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_sh1106.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_sh1106.c b/drivers/staging/fbtft/fb_sh1106.c index 00096f8d249a..6f7249493ea3 100644 --- a/drivers/staging/fbtft/fb_sh1106.c +++ b/drivers/staging/fbtft/fb_sh1106.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 06/26] Staging: fbtft: fb_upd161704: Switch to the gpio descriptor interface
This switches the fb_upd161704.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_upd161704.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c index acc425fdf34e..564a38e34440 100644 --- a/drivers/staging/fbtft/fb_upd161704.c +++ b/drivers/staging/fbtft/fb_upd161704.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -26,8 +26,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 08/26] Staging: fbtft: fb_uc1611: Switch to the gpio descriptor interface
This switches the fb_uc1611.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_uc1611.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index dfaf8bc70f73..65681d0fe200 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -251,7 +251,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } break; } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, len / 2); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 09/26] Staging: fbtft: fb_s6d1211: Switch to the gpio descriptor interface
This switches the fb_s6d1211.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_s6d1121.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index aa716f33420a..b3d0701880fe 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -29,8 +29,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 10/26] Staging: fbtft: fb_ili9320: Switch to the gpio descriptor interface
This switches the fb_ili9320.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ili9320.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index 740c0acbecd8..ea6e001288ce 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/26] Staging: fbtft: fb_ili9340: Switch to the gpio descriptor interface
This switches the fb_ili9340.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ili9340.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c index 430f21e50f4d..415183c7054a 100644 --- a/drivers/staging/fbtft/fb_ili9340.c +++ b/drivers/staging/fbtft/fb_ili9340.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/26] Staging: fbtft: fb_ssd1325: Switch to the gpio descriptor interface
This switches the fb_ssd1325.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1325.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c index f974f7fc4d79..8a3140d41d8b 100644 --- a/drivers/staging/fbtft/fb_ssd1325.c +++ b/drivers/staging/fbtft/fb_ssd1325.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -35,7 +35,7 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - gpio_set_value(par->gpio.cs, 0); + gpiod_set_value(par->gpio.cs, 0); write_reg(par, 0xb3); write_reg(par, 0xf0); @@ -155,7 +155,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 13/26] Staging: fbtft: fb_ili9325: Switch to the gpio descriptor interface
This switches the fb_ili9325.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ili9325.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 2cf75f2e03e2..b090e7ab6fdd 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -85,8 +85,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ bt &= 0x07; vc &= 0x07; -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 14/26] Staging: fbtft: fb_ssd1289: Switch to the gpio descriptor interface
This switches the fb_ssd1289.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1289.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index c9b18b3ba4ab..bbf75f795234 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "fbtft.h" @@ -28,8 +28,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, 0x00, 0x0001); write_reg(par, 0x03, 0xA8A4); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/26] Staging: fbtft: fb_ssd1351: Switch to the gpio descriptor interface
This switches the fb_ssd1351.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1351.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index 3da091b4d297..a8980d9f7557 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 16/26] Staging: fbtft: fb_uc1701: Switch to the gpio descriptor interface
This switches the fb_uc1701.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_uc1701.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c index 0a3531d6eb39..e4ccc73868a7 100644 --- a/drivers/staging/fbtft/fb_uc1701.c +++ b/drivers/staging/fbtft/fb_uc1701.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -136,9 +136,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, LCD_PAGE_ADDRESS | (u8)y); write_reg(par, 0x00); write_reg(par, LCD_COL_ADDRESS); - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); } if (ret < 0) -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 17/26] Staging: fbtft: fb_ssd1306: Switch to the gpio descriptor interface
This switches the fb_ssd1306.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1306.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 50172ddd94ae..d7c5e2e0eee9 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -190,7 +190,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, xres * yres / 8); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 18/26] Staging: fbtft: fb_bd663474: Switch to the gpio descriptor interface
This switches the fb_bd663474.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_bd663474.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index a58c514f4721..b6c6d66e4eb1 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -24,8 +24,8 @@ static int init_display(struct fbtft_par *par) { - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ par->fbtftops.reset(par); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 19/26] Staging: fbtft: fb_ssd1331: Switch to the gpio descriptor interface
This switches the fb_ssd1331.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1331.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index 0b614c84822e..9f54fe28d511 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -80,8 +80,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) va_start(args, len); *buf = (u8)va_arg(args, unsigned int); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 0); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 0); ret = par->fbtftops.write(par, par->buf, sizeof(u8)); if (ret < 0) { va_end(args); @@ -103,8 +103,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) return; } } - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); va_end(args); } -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 20/26] Staging: fbtft: fb_ili9163: Switch to the gpio descriptor interface
This switches the fb_ili9163.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ili9163.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 86e140244aab..d609a2b67db9 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -77,8 +77,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, MIPI_DCS_SOFT_RESET); /* software reset */ mdelay(500); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 21/26] Staging: fbtft: fb_agm1264k-fl: Switch to the gpio descriptor interface
This switches the fb_agm1264k-fl.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_agm1264k-fl.c | 52 +- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index f6f30f5bf15a..8f27bd8da17d 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -79,14 +79,14 @@ static int init_display(struct fbtft_par *par) static void reset(struct fbtft_par *par) { - if (par->gpio.reset == -1) + if (!par->gpio.reset) return; dev_dbg(par->info->device, "%s()\n", __func__); - gpio_set_value(par->gpio.reset, 0); + gpiod_set_value(par->gpio.reset, 0); udelay(20); - gpio_set_value(par->gpio.reset, 1); + gpiod_set_value(par->gpio.reset, 1); mdelay(120); } @@ -98,30 +98,30 @@ static int verify_gpios(struct fbtft_par *par) dev_dbg(par->info->device, "%s()\n", __func__); - if (par->EPIN < 0) { + if (!par->EPIN) { dev_err(par->info->device, "Missing info about 'wr' (aka E) gpio. Aborting.\n"); return -EINVAL; } for (i = 0; i < 8; ++i) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db[%i]' gpio. Aborting.\n", i); return -EINVAL; } } - if (par->CS0 < 0) { + if (!par->CS0) { dev_err(par->info->device, "Missing info about 'cs0' gpio. Aborting.\n"); return -EINVAL; } - if (par->CS1 < 0) { + if (!par->CS1) { dev_err(par->info->device, "Missing info about 'cs1' gpio. Aborting.\n"); return -EINVAL; } - if (par->RW < 0) { + if (!par->RW) { dev_err(par->info->device, "Missing info about 'rw' gpio. Aborting.\n"); return -EINVAL; @@ -139,22 +139,22 @@ request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio) if (strcasecmp(gpio->name, "wr") == 0) { /* left ks0108 E pin */ par->EPIN = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (strcasecmp(gpio->name, "cs0") == 0) { /* left ks0108 controller pin */ par->CS0 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "cs1") == 0) { /* right ks0108 controller pin */ par->CS1 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } /* if write (rw = 0) e(1->0) perform write */ /* if read (rw = 1) e(0->1) set data on D0-7*/ else if (strcasecmp(gpio->name, "rw") == 0) { par->RW = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } return FBTFT_GPIO_NO_MATCH; @@ -194,15 +194,15 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) /* select chip */ if (*buf) { /* cs1 */ - gpio_set_value(par->CS0, 1); - gpio_set_value(par->CS1, 0); + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 0); } else { /* cs0 */ - gpio_set_value(par->CS0, 0); - gpio_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 1); } - gpio_set_value(par->RS, 0); /* RS->0 (command mode) */ + gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ len--; if (len) { @@ -364,7 +364,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x00, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS, 1); /* RS->1 (data mode) */ + gpiod_set_value(par->RS, 1); /* RS->1 (data mode) */ ret = par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, @@ -387,7 +387,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x01, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS,
[PATCH 22/26] Staging: fbtft: fb_pcd8544: Switch to the gpio descriptor interface
This switches the fb_pcd8544.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_pcd8544.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index 32172f8f79f0..ad49973ad594 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -119,7 +119,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, 6 * 84); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/2] staging: iio: ad7606: Move out of staging
On Tue, 20 Nov 2018 17:43:46 +0200 Stefan Popa wrote: > Move ad7606 ADC driver out of staging and into the mainline. > > Signed-off-by: Stefan Popa One idle thought, how much would the performance suffer if we moved the parallel path over to the new gpiod_get/set_raw_array_value and friends? If would relax some of the constraints on where this could be used. There are some ordering issues in probe that need fixing. There are also a few places where it feels 'racey' and might need more comments to say why data is definitely ready when we try to read it for example. So nearly there, but one more cleanup series I think! Thanks, Jonathan > --- > Changes in v2: > - Simplified the Kconfig menu. > - Added SPDX-License-Identifier. > - Ordered the includes alphabetically. > - Used a threaded interrupt. > - Replaced ad7606_poll_bh_to_ring() with ad7606_trigger_handler(). > - Used a trigger. > - Replaced wait_event_interruptible() with > wait_for_completion_timeout(). > - Replaced wake_up_interruptible() with complete(). > - Used devm_iio_triggered_buffer_setup(). > - Added buffer_ops. > - Used single line comments where needed. > - Removed the gap between docs and struct. > - Added ad7606_of_match[]. > > MAINTAINERS | 7 + > drivers/iio/adc/Kconfig | 28 ++ > drivers/iio/adc/Makefile | 3 + > drivers/iio/adc/ad7606.c | 608 > +++ > drivers/iio/adc/ad7606.h | 107 ++ > drivers/iio/adc/ad7606_par.c | 110 +++ > drivers/iio/adc/ad7606_spi.c | 88 + > drivers/staging/iio/adc/Kconfig | 34 -- > drivers/staging/iio/adc/Makefile | 3 - > drivers/staging/iio/adc/ad7606.c | 565 > drivers/staging/iio/adc/ad7606.h | 106 -- > drivers/staging/iio/adc/ad7606_par.c | 113 --- > drivers/staging/iio/adc/ad7606_spi.c | 79 - > 13 files changed, 951 insertions(+), 900 deletions(-) > create mode 100644 drivers/iio/adc/ad7606.c > create mode 100644 drivers/iio/adc/ad7606.h > create mode 100644 drivers/iio/adc/ad7606_par.c > create mode 100644 drivers/iio/adc/ad7606_spi.c > delete mode 100644 drivers/staging/iio/adc/ad7606.c > delete mode 100644 drivers/staging/iio/adc/ad7606.h > delete mode 100644 drivers/staging/iio/adc/ad7606_par.c > delete mode 100644 drivers/staging/iio/adc/ad7606_spi.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index f642044..843545d 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -839,6 +839,13 @@ S: Supported > F: drivers/iio/dac/ad5758.c > F: Documentation/devicetree/bindings/iio/dac/ad5758.txt > > +ANALOG DEVICES INC AD7606 DRIVER > +M: Stefan Popa > +L: linux-...@vger.kernel.org > +W: http://ez.analog.com/community/linux-device-drivers > +S: Supported > +F: drivers/iio/adc/ad7606.c > + > ANALOG DEVICES INC AD9389B DRIVER > M: Hans Verkuil > L: linux-me...@vger.kernel.org > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index a52fea8..c3f61c9 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -58,6 +58,34 @@ config AD7476 > To compile this driver as a module, choose M here: the > module will be called ad7476. > > +config AD7606 > + tristate > + depends on GPIOLIB || COMPILE_TEST > + depends on HAS_IOMEM > + select IIO_BUFFER > + select IIO_TRIGGERED_BUFFER > + > +config AD7606_IFACE_PARALLEL > + tristate "Analog Devices AD7606 ADC driver with parallel interface > support" > + select AD7606 > + help > + Say yes here to build parallel interface support for Analog Devices: > + ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters > (ADC). > + > + To compile this driver as a module, choose M here: the > + module will be called ad7606_parallel. > + > +config AD7606_IFACE_SPI > + tristate "Analog Devices AD7606 ADC driver with spi interface support" > + depends on SPI > + select AD7606 > + help > + Say yes here to build spi interface support for Analog Devices: > + ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters > (ADC). > + > + To compile this driver as a module, choose M here: the > + module will be called ad7606_spi. > + > config AD7766 > tristate "Analog Devices AD7766/AD7767 ADC driver" > depends on SPI_MASTER > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index a6e6a0b..b734f4f 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -8,6 +8,9 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o > obj-$(CONFIG_AD7266) += ad7266.o > obj-$(CONFIG_AD7291) += ad7291.o > obj-$(CONFIG_AD7298) += ad7298.o > +obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o > +obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o > +obj-$(CONFIG_AD760
[PATCH 23/26] Staging: fbtft: fb_ssd1305: Switch to the gpio descriptor interface
This switches the fb_ssd1305.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ssd1305.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1305.c b/drivers/staging/fbtft/fb_ssd1305.c index 3515888d94c9..020fe48fed0b 100644 --- a/drivers/staging/fbtft/fb_ssd1305.c +++ b/drivers/staging/fbtft/fb_ssd1305.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -168,7 +168,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, par->info->var.xres * par->info->var.yres / 8); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 24/26] Staging: fbtft: fb_tls8204: Switch to the gpio descriptor interface
This switches the fb_tls8204.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_tls8204.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index 277b6ed9c725..bec6dd0ffb01 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -94,7 +94,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) /* The display is 102x68 but the LCD is 84x48. * Set the write pointer at the start of each row. */ - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); write_reg(par, 0x80 | 0); write_reg(par, 0x40 | y); @@ -109,7 +109,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) *buf++ = ch; } /* Write the row */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); if (ret < 0) { dev_err(par->info->device, -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 25/26] Staging: fbtft: fb_watterott: Switch to the gpio descriptor interface
This switches the fb_watterott.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_watterott.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index e77178157f1b..0a5206d28da4 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "fbtft.h" @@ -213,7 +213,7 @@ static int set_var(struct fbtft_par *par) static int verify_gpios(struct fbtft_par *par) { - if (par->gpio.reset < 0) { + if (!par->gpio.reset) { dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n"); return -EINVAL; } -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 26/26] Staging: fbtft: fb_ra8875: Switch to the gpio descriptor interface
This switches the fb_ra8875.c to use GPIO descriptors rather than numerical gpios. Signed-off-by: Nishad Kamdar --- drivers/staging/fbtft/fb_ra8875.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 5d3b76ca74d8..70b37fc7fb66 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include "fbtft.h" #define DRVNAME "fb_ra8875" @@ -39,7 +39,7 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len) static int init_display(struct fbtft_par *par) { - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/5] Staging: iio: adt7316: Add of_device_id table
On Tue, 20 Nov 2018 22:22:30 +0530 Shreeya Patel wrote: > When the kernel starts up, it kicks off compiled-in drivers > that match “compatible” entries it finds in the device tree. > At a later stage (when /lib/modules is available), all kernel modules > that match “compatible” entries in the device tree are loaded. > > But if there is no dt table then there should be a fall back path > with which desired kernel modules can be loaded. Hence, add > of_device_id table in the i2c driver to be able to use when there > is no dt table. The patch is fine, but this description is confusing. of_device_id is a device tree table (confusing naming in the kernel, but of is open firmware, a standard from which device tree emerged). I've just dropped this second paragraph from the description to avoid confusion. Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > > Signed-off-by: Shreeya Patel > --- > > Changes in v2: > - Make the commit message appropriate and assign of_match_table > in the driver structure. > > drivers/staging/iio/addac/adt7316-i2c.c | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/drivers/staging/iio/addac/adt7316-i2c.c > b/drivers/staging/iio/addac/adt7316-i2c.c > index 473e5e34ec00..41bc4ca008bc 100644 > --- a/drivers/staging/iio/addac/adt7316-i2c.c > +++ b/drivers/staging/iio/addac/adt7316-i2c.c > @@ -126,9 +126,22 @@ static const struct i2c_device_id adt7316_i2c_id[] = { > > MODULE_DEVICE_TABLE(i2c, adt7316_i2c_id); > > +static const struct of_device_id adt7316_of_match[] = { > + { .compatible = "adi,adt7316" }, > + { .compatible = "adi,adt7317" }, > + { .compatible = "adi,adt7318" }, > + { .compatible = "adi,adt7516" }, > + { .compatible = "adi,adt7517" }, > + { .compatible = "adi,adt7519" }, > + { }, > +}; > + > +MODULE_DEVICE_TABLE(of, adt7316_of_match); > + > static struct i2c_driver adt7316_driver = { > .driver = { > .name = "adt7316", > + .of_match_table = adt7316_of_match, > .pm = ADT7316_PM_OPS, > }, > .probe = adt7316_i2c_probe, ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 2/5] Staging: iio: adt7316: Use device tree data to set ldac_pin
On Tue, 20 Nov 2018 22:24:36 +0530 Shreeya Patel wrote: > Make the driver use device tree instead of the platform data. > Hence, use devm_gpiod_get_optional function to get the data from > device tree for ldac-pin and accordingly make the needed changes > in the driver. > > Signed-off-by: Shreeya Patel Sorry, missed this previously. This is definitely a non standard gpio name, so should be prefixed in the binding and here with adi, I'll fix up, but please check I didn't mess it up! Applied with that change to the togreg branch of iio.git. Thanks, Jonathan > --- > drivers/staging/iio/addac/adt7316.c | 14 ++ > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/iio/addac/adt7316.c > b/drivers/staging/iio/addac/adt7316.c > index 3f22d1088713..deb2f7b40f60 100644 > --- a/drivers/staging/iio/addac/adt7316.c > +++ b/drivers/staging/iio/addac/adt7316.c > @@ -177,7 +177,7 @@ > > struct adt7316_chip_info { > struct adt7316_bus bus; > - u16 ldac_pin; > + struct gpio_desc*ldac_pin; > u16 int_mask; /* 0x2f */ > u8 config1; > u8 config2; > @@ -950,8 +950,8 @@ static ssize_t adt7316_store_update_DAC(struct device > *dev, > if (ret) > return -EIO; > } else { > - gpio_set_value(chip->ldac_pin, 0); > - gpio_set_value(chip->ldac_pin, 1); > + gpiod_set_value(chip->ldac_pin, 0); > + gpiod_set_value(chip->ldac_pin, 1); > } > > return len; > @@ -2120,7 +2120,13 @@ int adt7316_probe(struct device *dev, struct > adt7316_bus *bus, > else > return -ENODEV; > > - chip->ldac_pin = adt7316_platform_data[1]; > + chip->ldac_pin = devm_gpiod_get_optional(dev, "ldac", GPIOD_OUT_LOW); > + if (IS_ERR(chip->ldac_pin)) { > + ret = PTR_ERR(chip->ldac_pin); > + dev_err(dev, "Failed to request ldac GPIO: %d\n", ret); > + return ret; > + } > + > if (chip->ldac_pin) { > chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA; > if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 3/5] Staging: iio: adt7316: Switch irq_flags to a local variable
On Tue, 20 Nov 2018 22:26:58 +0530 Shreeya Patel wrote: > There is no need to store irq_flags into the structure as it > is always set to the same thing. Hence switch irq_flags to a > local variable. > > Signed-off-by: Shreeya Patel Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > drivers/staging/iio/addac/adt7316-i2c.c | 1 - > drivers/staging/iio/addac/adt7316-spi.c | 1 - > drivers/staging/iio/addac/adt7316.c | 8 > drivers/staging/iio/addac/adt7316.h | 1 - > 4 files changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/iio/addac/adt7316-i2c.c > b/drivers/staging/iio/addac/adt7316-i2c.c > index 41bc4ca008bc..ac91163656b5 100644 > --- a/drivers/staging/iio/addac/adt7316-i2c.c > +++ b/drivers/staging/iio/addac/adt7316-i2c.c > @@ -104,7 +104,6 @@ static int adt7316_i2c_probe(struct i2c_client *client, > struct adt7316_bus bus = { > .client = client, > .irq = client->irq, > - .irq_flags = IRQF_TRIGGER_LOW, > .read = adt7316_i2c_read, > .write = adt7316_i2c_write, > .multi_read = adt7316_i2c_multi_read, > diff --git a/drivers/staging/iio/addac/adt7316-spi.c > b/drivers/staging/iio/addac/adt7316-spi.c > index 5cd22743e140..e75827e326a6 100644 > --- a/drivers/staging/iio/addac/adt7316-spi.c > +++ b/drivers/staging/iio/addac/adt7316-spi.c > @@ -94,7 +94,6 @@ static int adt7316_spi_probe(struct spi_device *spi_dev) > struct adt7316_bus bus = { > .client = spi_dev, > .irq = spi_dev->irq, > - .irq_flags = IRQF_TRIGGER_LOW, > .read = adt7316_spi_read, > .write = adt7316_spi_write, > .multi_read = adt7316_spi_multi_read, > diff --git a/drivers/staging/iio/addac/adt7316.c > b/drivers/staging/iio/addac/adt7316.c > index deb2f7b40f60..dfae22619287 100644 > --- a/drivers/staging/iio/addac/adt7316.c > +++ b/drivers/staging/iio/addac/adt7316.c > @@ -2102,6 +2102,7 @@ int adt7316_probe(struct device *dev, struct > adt7316_bus *bus, > struct adt7316_chip_info *chip; > struct iio_dev *indio_dev; > unsigned short *adt7316_platform_data = dev->platform_data; > + int irq_flags = IRQF_TRIGGER_LOW; > int ret = 0; > > indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); > @@ -2146,19 +2147,18 @@ int adt7316_probe(struct device *dev, struct > adt7316_bus *bus, > > if (chip->bus.irq > 0) { > if (adt7316_platform_data[0]) > - chip->bus.irq_flags = adt7316_platform_data[0]; > + irq_flags = adt7316_platform_data[0]; > > ret = devm_request_threaded_irq(dev, chip->bus.irq, > NULL, > adt7316_event_handler, > - chip->bus.irq_flags | > - IRQF_ONESHOT, > + irq_flags | IRQF_ONESHOT, > indio_dev->name, > indio_dev); > if (ret) > return ret; > > - if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH) > + if (irq_flags & IRQF_TRIGGER_HIGH) > chip->config1 |= ADT7316_INT_POLARITY; > } > > diff --git a/drivers/staging/iio/addac/adt7316.h > b/drivers/staging/iio/addac/adt7316.h > index ec40fbb698a6..fd7c5c92b599 100644 > --- a/drivers/staging/iio/addac/adt7316.h > +++ b/drivers/staging/iio/addac/adt7316.h > @@ -17,7 +17,6 @@ > struct adt7316_bus { > void *client; > int irq; > - int irq_flags; > int (*read)(void *client, u8 reg, u8 *data); > int (*write)(void *client, u8 reg, u8 val); > int (*multi_read)(void *client, u8 first_reg, u8 count, u8 *data); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 4/5] Staging: iio: adt7316: Change the name from irq_flags to irq_type
On Tue, 20 Nov 2018 22:28:36 +0530 Shreeya Patel wrote: > Most of the drivers in IIO uses irq_type as the name for > storing the interrupt type and hence change the name from > irq_flags to irq_type for maintaining the consistency. > > Signed-off-by: Shreeya Patel Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with. Thanks, Jonathan > --- > drivers/staging/iio/addac/adt7316.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/iio/addac/adt7316.c > b/drivers/staging/iio/addac/adt7316.c > index dfae22619287..9c72538baf9e 100644 > --- a/drivers/staging/iio/addac/adt7316.c > +++ b/drivers/staging/iio/addac/adt7316.c > @@ -2102,7 +2102,7 @@ int adt7316_probe(struct device *dev, struct > adt7316_bus *bus, > struct adt7316_chip_info *chip; > struct iio_dev *indio_dev; > unsigned short *adt7316_platform_data = dev->platform_data; > - int irq_flags = IRQF_TRIGGER_LOW; > + int irq_type = IRQF_TRIGGER_LOW; > int ret = 0; > > indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); > @@ -2147,18 +2147,18 @@ int adt7316_probe(struct device *dev, struct > adt7316_bus *bus, > > if (chip->bus.irq > 0) { > if (adt7316_platform_data[0]) > - irq_flags = adt7316_platform_data[0]; > + irq_type = adt7316_platform_data[0]; > > ret = devm_request_threaded_irq(dev, chip->bus.irq, > NULL, > adt7316_event_handler, > - irq_flags | IRQF_ONESHOT, > + irq_type | IRQF_ONESHOT, > indio_dev->name, > indio_dev); > if (ret) > return ret; > > - if (irq_flags & IRQF_TRIGGER_HIGH) > + if (irq_type & IRQF_TRIGGER_HIGH) > chip->config1 |= ADT7316_INT_POLARITY; > } > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 5/5] Staging: iio: adt7316: Use device tree data to assign irq_type
On Wed, 21 Nov 2018 15:02:52 +0530 Shreeya Patel wrote: > On Wed, 2018-11-21 at 08:21 +, Ardelean, Alexandru wrote: > > On Tue, 2018-11-20 at 22:30 +0530, Shreeya Patel wrote: > > > ADT7316 driver no more uses platform data and hence use device tree > > > data instead of platform data for assigning irq_type field. > > > Switch case figures out the type of irq and if it's the default > > > case > > > then assign the default value to the irq_type i.e. > > > irq_type = IRQF_TRIGGER_LOW > > > > > > > 1 comment inline > > > > > Signed-off-by: Shreeya Patel > > > --- > > > drivers/staging/iio/addac/adt7316.c | 21 + > > > 1 file changed, 17 insertions(+), 4 deletions(-) > > > > > > diff --git a/drivers/staging/iio/addac/adt7316.c > > > b/drivers/staging/iio/addac/adt7316.c > > > index 9c72538baf9e..c647875a64f5 100644 > > > --- a/drivers/staging/iio/addac/adt7316.c > > > +++ b/drivers/staging/iio/addac/adt7316.c > > > @@ -2101,8 +2101,7 @@ int adt7316_probe(struct device *dev, struct > > > adt7316_bus *bus, > > > { > > > struct adt7316_chip_info *chip; > > > struct iio_dev *indio_dev; > > > - unsigned short *adt7316_platform_data = dev- > > > >platform_data; > > > - int irq_type = IRQF_TRIGGER_LOW; > > > + int irq_type; > > > int ret = 0; > > > > > > indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); > > > @@ -2146,8 +2145,22 @@ int adt7316_probe(struct device *dev, struct > > > adt7316_bus *bus, > > > indio_dev->modes = INDIO_DIRECT_MODE; > > > > > > if (chip->bus.irq > 0) { > > > - if (adt7316_platform_data[0]) > > > - irq_type = adt7316_platform_data[0]; > > > + irq_type = > > > + irqd_get_trigger_type(irq_get_irq_data(chi > > > p- > > > > bus.irq)); > > > > > > + > > > + switch (irq_type) { > > > + case IRQF_TRIGGER_HIGH: > > > + case IRQF_TRIGGER_RISING: > > > + break; > > > + case IRQF_TRIGGER_LOW: > > > + case IRQF_TRIGGER_FALLING: > > > + break; > > > + default: > > > + dev_info(dev, "mode %d unsupported, using > > > IRQF_TRIGGER_LOW\n", > > > + irq_type); > > > + irq_type = IRQF_TRIGGER_LOW; > > > + break; > > > + } > > > > It would be an idea to move this part [together with > > devm_request_threaded_irq()] into a "adt7316_setup_irq()" function. > > To un- > > clutter the code in the adt7316_probe() function. > > > > Yes, seems like a good idea! > Even other drivers are doing the same as you told me to do...thanks :) > > I'll do the change after Jonathan picks up the other patches and will > wait for some other reviews to come up if there are any. Agreed. This suggested change is good, so I'll leave this patch for now on the basis it probably makes sense to do it as a short series focused on that one element. Thanks, Jonathan > > Thanks > > > > > > > ret = devm_request_threaded_irq(dev, chip- > > > >bus.irq, > > > NULL, ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 01/26] Staging: fbtft: fbtft-core: Switch to the gpio descriptor interface
Hi Nishad, Thank you for the patch! Yet something to improve: [auto build test ERROR on staging/staging-testing] [also build test ERROR on v4.20-rc3 next-20181123] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nishad-Kamdar/Staging-fbtft-Switch-to-the-gpio-descriptor-interface/20181125-232835 config: x86_64-randconfig-x001-201847 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): drivers/staging/fbtft/fbtft-core.c: In function 'fbtft_request_one_gpio': >> drivers/staging/fbtft/fbtft-core.c:167:21: error: storage size of 'of_flags' >> isn't known enum of_gpio_flags of_flags; ^~~~ drivers/staging/fbtft/fbtft-core.c:167:21: warning: unused variable 'of_flags' [-Wunused-variable] drivers/staging/fbtft/fbtft-core.c:166:12: warning: unused variable 'flags' [-Wunused-variable] int gpio, flags, ret = 0; ^ drivers/staging/fbtft/fbtft-core.c:166:6: warning: unused variable 'gpio' [-Wunused-variable] int gpio, flags, ret = 0; ^~~~ -- drivers/staging/fbtft/fb_agm1264k-fl.c: In function 'reset': >> drivers/staging/fbtft/fb_agm1264k-fl.c:82:22: warning: comparison between >> pointer and integer if (par->gpio.reset == -1) ^~ >> drivers/staging/fbtft/fb_agm1264k-fl.c:87:17: warning: passing argument 1 of >> 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->gpio.reset, 0); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c:89:17: warning: passing argument 1 of 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->gpio.reset, 1); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c: In function 'write_reg8_bus8': drivers/staging/fbtft/fb_agm1264k-fl.c:197:18: warning: passing argument 1 of 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->CS0, 1); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c:198:18: warning: passing argument 1 of 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->CS1, 0); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c:201:18: warning: passing argument 1 of 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->CS0, 0); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c:202:18: warning: passing argument 1 of 'gpio_set_value' makes integer from pointer without a cast [-Wint-conversion] gpio_set_value(par->CS1, 1); ^~~ In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:11:0: include/linux/gpio.h:69:20: note: expected 'unsigned int' but argument is of type 'struct gpio_desc *' static inline void gpio_set_value(unsigned int gpio, int value) ^~ drivers/staging/fbtft/fb_agm1264k-fl.c:205:17: warning: passing ar
Re: [PATCH] staging: android: ion: Add chunk heap initialization
On 11/11/18 11:29 AM, Alexey Skidanov wrote: Create chunk heap of specified size and base address by adding "ion_chunk_heap=size@start" kernel boot parameter. Signed-off-by: Alexey Skidanov --- drivers/staging/android/ion/ion_chunk_heap.c | 40 1 file changed, 40 insertions(+) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 159d72f..67573aa4 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -135,6 +135,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) } chunk_heap->base = heap_data->base; chunk_heap->size = heap_data->size; + chunk_heap->heap.name = heap_data->name; chunk_heap->allocated = 0; gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); @@ -151,3 +152,42 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) return ERR_PTR(ret); } +static u64 base; +static u64 size; + +static int __init setup_heap(char *param) +{ + char *p, *pp; + + size = memparse(param, &p); + if (param == p) + return -EINVAL; + + if (*p == '@') + base = memparse(p + 1, &pp); + else + return -EINVAL; + + if (p == pp) + return -EINVAL; + + return 0; +} + +__setup("ion_chunk_heap=", setup_heap); + +static int ion_add_chunk_heap(void) +{ + struct ion_heap *heap; + struct ion_platform_heap plat_heap = {.base = base, + .size = size, + .name = "chunk_heap", + .priv = (void *)PAGE_SIZE}; + heap = ion_chunk_heap_create(&plat_heap); + if (heap) + ion_device_add_heap(heap); + + return 0; +} +device_initcall(ion_add_chunk_heap); + This solves a problem but not enough of the problem. We need to be able to support more than one chunk/carveout heap. This also assumes that the memory has already been reserved/placed and that you know the base and size to pass on the command line. Part of the issue with the carveout heaps is that we need a way to tell the kernel to reserve the memory early enough and then get that information to Ion. Hard coding memory locations tends to be buggy from my past experience with Ion. If you'd like to see about coming up with a complete solution, feel free to resubmit but I'm still strongly considering removing these heaps. Thanks, Laura ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: android: ion: Add chunk heap initialization
On 11/25/18 10:51 PM, Laura Abbott wrote: > On 11/11/18 11:29 AM, Alexey Skidanov wrote: >> Create chunk heap of specified size and base address by adding >> "ion_chunk_heap=size@start" kernel boot parameter. >> >> Signed-off-by: Alexey Skidanov >> --- >> drivers/staging/android/ion/ion_chunk_heap.c | 40 >> >> 1 file changed, 40 insertions(+) >> >> diff --git a/drivers/staging/android/ion/ion_chunk_heap.c >> b/drivers/staging/android/ion/ion_chunk_heap.c >> index 159d72f..67573aa4 100644 >> --- a/drivers/staging/android/ion/ion_chunk_heap.c >> +++ b/drivers/staging/android/ion/ion_chunk_heap.c >> @@ -135,6 +135,7 @@ struct ion_heap *ion_chunk_heap_create(struct >> ion_platform_heap *heap_data) >> } >> chunk_heap->base = heap_data->base; >> chunk_heap->size = heap_data->size; >> + chunk_heap->heap.name = heap_data->name; >> chunk_heap->allocated = 0; >> gen_pool_add(chunk_heap->pool, chunk_heap->base, >> heap_data->size, -1); >> @@ -151,3 +152,42 @@ struct ion_heap *ion_chunk_heap_create(struct >> ion_platform_heap *heap_data) >> return ERR_PTR(ret); >> } >> +static u64 base; >> +static u64 size; >> + >> +static int __init setup_heap(char *param) >> +{ >> + char *p, *pp; >> + >> + size = memparse(param, &p); >> + if (param == p) >> + return -EINVAL; >> + >> + if (*p == '@') >> + base = memparse(p + 1, &pp); >> + else >> + return -EINVAL; >> + >> + if (p == pp) >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> +__setup("ion_chunk_heap=", setup_heap); >> + >> +static int ion_add_chunk_heap(void) >> +{ >> + struct ion_heap *heap; >> + struct ion_platform_heap plat_heap = {.base = base, >> + .size = size, >> + .name = "chunk_heap", >> + .priv = (void *)PAGE_SIZE}; >> + heap = ion_chunk_heap_create(&plat_heap); >> + if (heap) >> + ion_device_add_heap(heap); >> + >> + return 0; >> +} >> +device_initcall(ion_add_chunk_heap); >> + >> > > This solves a problem but not enough of the problem. > > We need to be able to support more than one chunk/carveout > heap. This is easy to support. This also assumes that the memory has already been > reserved/placed and that you know the base and size to > pass on the command line. Part of the issue with the carveout > heaps is that we need a way to tell the kernel to reserve > the memory early enough and then get that information to > Ion. Hard coding memory locations tends to be buggy from > my past experience with Ion. memmap= kernel option marks the memory region(s) as reserved (Zone Allocator doesn't use this memory region(s)). So the heap(s) may manage this memory region(s). > > If you'd like to see about coming up with a complete solution, > feel free to resubmit but I'm still strongly considering > removing these heaps. > I will add the multiple heaps support and resubmit the patch > Thanks, > Laura Thanks, Alexey ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: android: ion: Add chunk heap initialization
On 11/25/18 1:22 PM, Alexey Skidanov wrote: On 11/25/18 10:51 PM, Laura Abbott wrote: On 11/11/18 11:29 AM, Alexey Skidanov wrote: Create chunk heap of specified size and base address by adding "ion_chunk_heap=size@start" kernel boot parameter. Signed-off-by: Alexey Skidanov --- drivers/staging/android/ion/ion_chunk_heap.c | 40 1 file changed, 40 insertions(+) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 159d72f..67573aa4 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -135,6 +135,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) } chunk_heap->base = heap_data->base; chunk_heap->size = heap_data->size; + chunk_heap->heap.name = heap_data->name; chunk_heap->allocated = 0; gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); @@ -151,3 +152,42 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) return ERR_PTR(ret); } +static u64 base; +static u64 size; + +static int __init setup_heap(char *param) +{ + char *p, *pp; + + size = memparse(param, &p); + if (param == p) + return -EINVAL; + + if (*p == '@') + base = memparse(p + 1, &pp); + else + return -EINVAL; + + if (p == pp) + return -EINVAL; + + return 0; +} + +__setup("ion_chunk_heap=", setup_heap); + +static int ion_add_chunk_heap(void) +{ + struct ion_heap *heap; + struct ion_platform_heap plat_heap = {.base = base, + .size = size, + .name = "chunk_heap", + .priv = (void *)PAGE_SIZE}; + heap = ion_chunk_heap_create(&plat_heap); + if (heap) + ion_device_add_heap(heap); + + return 0; +} +device_initcall(ion_add_chunk_heap); + This solves a problem but not enough of the problem. We need to be able to support more than one chunk/carveout heap. This is easy to support. This also assumes that the memory has already been reserved/placed and that you know the base and size to pass on the command line. Part of the issue with the carveout heaps is that we need a way to tell the kernel to reserve the memory early enough and then get that information to Ion. Hard coding memory locations tends to be buggy from my past experience with Ion. memmap= kernel option marks the memory region(s) as reserved (Zone Allocator doesn't use this memory region(s)). So the heap(s) may manage this memory region(s). memmap= is x86 only. I really don't like using the command line for specifying the base/size as it seems likely to conflict with platforms that rely on devicetree for reserving memory regions. Thanks, Laura If you'd like to see about coming up with a complete solution, feel free to resubmit but I'm still strongly considering removing these heaps. I will add the multiple heaps support and resubmit the patch Thanks, Laura Thanks, Alexey ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: android: ion: Add chunk heap initialization
On 11/25/18 11:40 PM, Laura Abbott wrote: > On 11/25/18 1:22 PM, Alexey Skidanov wrote: >> >> >> On 11/25/18 10:51 PM, Laura Abbott wrote: >>> On 11/11/18 11:29 AM, Alexey Skidanov wrote: Create chunk heap of specified size and base address by adding "ion_chunk_heap=size@start" kernel boot parameter. Signed-off-by: Alexey Skidanov --- drivers/staging/android/ion/ion_chunk_heap.c | 40 1 file changed, 40 insertions(+) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 159d72f..67573aa4 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -135,6 +135,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) } chunk_heap->base = heap_data->base; chunk_heap->size = heap_data->size; + chunk_heap->heap.name = heap_data->name; chunk_heap->allocated = 0; gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); @@ -151,3 +152,42 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) return ERR_PTR(ret); } +static u64 base; +static u64 size; + +static int __init setup_heap(char *param) +{ + char *p, *pp; + + size = memparse(param, &p); + if (param == p) + return -EINVAL; + + if (*p == '@') + base = memparse(p + 1, &pp); + else + return -EINVAL; + + if (p == pp) + return -EINVAL; + + return 0; +} + +__setup("ion_chunk_heap=", setup_heap); + +static int ion_add_chunk_heap(void) +{ + struct ion_heap *heap; + struct ion_platform_heap plat_heap = {.base = base, + .size = size, + .name = "chunk_heap", + .priv = (void *)PAGE_SIZE}; + heap = ion_chunk_heap_create(&plat_heap); + if (heap) + ion_device_add_heap(heap); + + return 0; +} +device_initcall(ion_add_chunk_heap); + >>> >>> This solves a problem but not enough of the problem. >>> >>> We need to be able to support more than one chunk/carveout >>> heap. >> This is easy to support. >> This also assumes that the memory has already been >>> reserved/placed and that you know the base and size to >>> pass on the command line. Part of the issue with the carveout >>> heaps is that we need a way to tell the kernel to reserve >>> the memory early enough and then get that information to >>> Ion. Hard coding memory locations tends to be buggy from >>> my past experience with Ion. >> memmap= kernel option marks the memory region(s) as reserved (Zone >> Allocator doesn't use this memory region(s)). So the heap(s) may manage >> this memory region(s). > > memmap= is x86 only. I really don't like using the command line for > specifying the base/size as it seems likely to conflict with platforms > that rely on devicetree for reserving memory regions. > > Thanks, > Laura > I see ... So probably the better way is the one similar to this https://elixir.bootlin.com/linux/latest/source/kernel/dma/contiguous.c#L245 ? Thanks, Alexey >>> >>> If you'd like to see about coming up with a complete solution, >>> feel free to resubmit but I'm still strongly considering >>> removing these heaps. >>> >> I will add the multiple heaps support and resubmit the patch >>> Thanks, >>> Laura >> Thanks, >> Alexey >> > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Fix a race in sub-channel creation that can cause panic
From: Dexuan Cui We can concurrently try to open the same sub-channel from 2 paths: path #1: vmbus_onoffer() -> vmbus_process_offer() -> handle_sc_creation(). path #2: storvsc_probe() -> storvsc_connect_to_vsp() -> -> storvsc_channel_init() -> handle_multichannel_storage() -> -> vmbus_are_subchannels_present() -> handle_sc_creation(). They conflict with each other, but it was not an issue before the recent commit ae6935ed7d42 ("vmbus: split ring buffer allocation from open"), because at the beginning of vmbus_open() we checked newchannel->state so only one path could succeed, and the other would return with -EINVAL. After ae6935ed7d42, the failing path frees the channel's ringbuffer by vmbus_free_ring(), and this causes a panic later. Commit ae6935ed7d42 itself is good, and it just reveals the longstanding race. We can resolve the issue by removing path #2, i.e. removing the second vmbus_are_subchannels_present() in handle_multichannel_storage(). BTW, the comment "Check to see if sub-channels have already been created" in handle_multichannel_storage() is incorrect: when we unload the driver, we first close the sub-channel(s) and then close the primary channel, next the host sends rescind-offer message(s) so primary->sc_list will become empty. This means the first vmbus_are_subchannels_present() in handle_multichannel_storage() is never useful. Fixes: ae6935ed7d42 ("vmbus: split ring buffer allocation from open") Cc: sta...@vger.kernel.org Cc: Long Li Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/scsi/storvsc_drv.c | 61 +++--- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index f03dc03a42c3..8f88348ebe42 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -446,7 +446,6 @@ struct storvsc_device { bool destroy; bool drain_notify; - bool open_sub_channel; atomic_t num_outstanding_req; struct Scsi_Host *host; @@ -636,33 +635,38 @@ static inline struct storvsc_device *get_in_stor_device( static void handle_sc_creation(struct vmbus_channel *new_sc) { struct hv_device *device = new_sc->primary_channel->device_obj; + struct device *dev = &device->device; struct storvsc_device *stor_device; struct vmstorage_channel_properties props; + int ret; stor_device = get_out_stor_device(device); if (!stor_device) return; - if (stor_device->open_sub_channel == false) - return; - memset(&props, 0, sizeof(struct vmstorage_channel_properties)); - vmbus_open(new_sc, - storvsc_ringbuffer_size, - storvsc_ringbuffer_size, - (void *)&props, - sizeof(struct vmstorage_channel_properties), - storvsc_on_channel_callback, new_sc); + ret = vmbus_open(new_sc, +storvsc_ringbuffer_size, +storvsc_ringbuffer_size, +(void *)&props, +sizeof(struct vmstorage_channel_properties), +storvsc_on_channel_callback, new_sc); - if (new_sc->state == CHANNEL_OPENED_STATE) { - stor_device->stor_chns[new_sc->target_cpu] = new_sc; - cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus); + /* In case vmbus_open() fails, we don't use the sub-channel. */ + if (ret != 0) { + dev_err(dev, "Failed to open sub-channel: err=%d\n", ret); + return; } + + /* Add the sub-channel to the array of available channels. */ + stor_device->stor_chns[new_sc->target_cpu] = new_sc; + cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus); } static void handle_multichannel_storage(struct hv_device *device, int max_chns) { + struct device *dev = &device->device; struct storvsc_device *stor_device; int num_cpus = num_online_cpus(); int num_sc; @@ -679,21 +683,11 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) request = &stor_device->init_request; vstor_packet = &request->vstor_packet; - stor_device->open_sub_channel = true; /* * Establish a handler for dealing with subchannels. */ vmbus_set_sc_create_callback(device->channel, handle_sc_creation); - /* -* Check to see if sub-channels have already been created. This -* can happen when this driver is re-loaded after unloading. -*/ - - if (vmbus_are_subchannels_present(device->channel)) - return; - - stor_device->open_sub_channel = false; /* * Request the host to create sub-channels. */ @@ -710,23 +
[PATCH] Drivers: hv: vmbus: Remove the useless API vmbus_get_outgoing_channel()
From: Dexuan Cui Commit d86adf482b84 ("scsi: storvsc: Enable multi-queue support") removed the usage of the API in Jan 2017, and the API is not used since then. netvsc and storvsc have their own algorithms to determine the outgoing channel, so this API is useless. And the API is potentially unsafe, because it reads primary->num_sc without any lock held. This can be risky considering the RESCIND-OFFER message. Let's remove the API. Cc: Long Li Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel.c | 1 - drivers/hv/channel_mgmt.c | 45 --- include/linux/hyperv.h| 17 --- 3 files changed, 63 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index de8193f3b838..f96a77b18bb9 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -703,7 +703,6 @@ int vmbus_disconnect_ring(struct vmbus_channel *channel) /* Snapshot the list of subchannels */ spin_lock_irqsave(&channel->lock, flags); list_splice_init(&channel->sc_list, &list); - channel->num_sc = 0; spin_unlock_irqrestore(&channel->lock, flags); list_for_each_entry_safe(cur_channel, tmp, &list, sc_list) { diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 6277597d3d58..82e673671087 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -405,7 +405,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel) primary_channel = channel->primary_channel; spin_lock_irqsave(&primary_channel->lock, flags); list_del(&channel->sc_list); - primary_channel->num_sc--; spin_unlock_irqrestore(&primary_channel->lock, flags); } @@ -483,7 +482,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) newchannel->primary_channel = channel; spin_lock_irqsave(&channel->lock, flags); list_add_tail(&newchannel->sc_list, &channel->sc_list); - channel->num_sc++; spin_unlock_irqrestore(&channel->lock, flags); } else { goto err_free_chan; @@ -1239,49 +1237,6 @@ int vmbus_request_offers(void) return ret; } -/* - * Retrieve the (sub) channel on which to send an outgoing request. - * When a primary channel has multiple sub-channels, we try to - * distribute the load equally amongst all available channels. - */ -struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) -{ - struct list_head *cur, *tmp; - int cur_cpu; - struct vmbus_channel *cur_channel; - struct vmbus_channel *outgoing_channel = primary; - int next_channel; - int i = 1; - - if (list_empty(&primary->sc_list)) - return outgoing_channel; - - next_channel = primary->next_oc++; - - if (next_channel > (primary->num_sc)) { - primary->next_oc = 0; - return outgoing_channel; - } - - cur_cpu = hv_cpu_number_to_vp_number(smp_processor_id()); - list_for_each_safe(cur, tmp, &primary->sc_list) { - cur_channel = list_entry(cur, struct vmbus_channel, sc_list); - if (cur_channel->state != CHANNEL_OPENED_STATE) - continue; - - if (cur_channel->target_vp == cur_cpu) - return cur_channel; - - if (i == next_channel) - return cur_channel; - - i++; - } - - return outgoing_channel; -} -EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel); - static void invoke_sc_cb(struct vmbus_channel *primary_channel) { struct list_head *cur, *tmp; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b3e24368930a..07a367f5e22f 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -830,15 +830,6 @@ struct vmbus_channel { * All Sub-channels of a primary channel are linked here. */ struct list_head sc_list; - /* -* Current number of sub-channels. -*/ - int num_sc; - /* -* Number of a sub-channel (position within sc_list) which is supposed -* to be used as the next outgoing channel. -*/ - int next_oc; /* * The primary channel this sub-channel belongs to. * This will be NULL for the primary channel. @@ -965,14 +956,6 @@ void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel, void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel, void (*chn_rescind_cb)(struct vmbus_channel *)); -/* - * Retrieve the (sub) channel on which to send an outgoing request. - * When a primary channel has multiple sub-channels, we choose a - * channel whose VCPU binding is clos
[PATCH 0/2] Drivers: hv: vmbus: Miscellaneous fixes
From: "K. Y. Srinivasan" Miscellaneous fixes. Dexuan Cui (2): Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl() Drivers: hv: vmbus: offload the handling of channels to two workqueues drivers/hv/channel.c | 8 ++ drivers/hv/channel_mgmt.c | 188 +- drivers/hv/connection.c | 24 - drivers/hv/hyperv_vmbus.h | 7 ++ include/linux/hyperv.h| 7 ++ 5 files changed, 169 insertions(+), 65 deletions(-) -- 2.19.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] Drivers: hv: vmbus: offload the handling of channels to two workqueues
From: Dexuan Cui vmbus_process_offer() mustn't call channel->sc_creation_callback() directly for sub-channels, because sc_creation_callback() -> vmbus_open() may never get the host's response to the OPEN_CHANNEL message (the host may rescind a channel at any time, e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind() may not wake up the vmbus_open() as it's blocked due to a non-zero vmbus_connection.offer_in_progress, and finally we have a deadlock. The above is also true for primary channels, if the related device drivers use sync probing mode by default. And, usually the handling of primary channels and sub-channels can depend on each other, so we should offload them to different workqueues to avoid possible deadlock, e.g. in sync-probing mode, NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() -> rtnl_lock(), and causes deadlock: the former gets the rtnl_lock and waits for all the sub-channels to appear, but the latter can't get the rtnl_lock and this blocks the handling of sub-channels. The patch can fix the multiple-NIC deadlock described above for v3.x kernels (e.g. RHEL 7.x) which don't support async-probing of devices, and v4.4, v4.9, v4.14 and v4.18 which support async-probing but don't enable async-probing for Hyper-V drivers (yet). The patch can also fix the hang issue in sub-channel's handling described above for all versions of kernels, including v4.19 and v4.20-rc3. So the patch should be applied to all the existing kernels. Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug") Cc: sta...@vger.kernel.org Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel_mgmt.c | 188 +- drivers/hv/connection.c | 24 - drivers/hv/hyperv_vmbus.h | 7 ++ include/linux/hyperv.h| 7 ++ 4 files changed, 161 insertions(+), 65 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 82e673671087..d01689079e9b 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -434,60 +434,16 @@ void vmbus_free_channels(void) } } -/* - * vmbus_process_offer - Process the offer by creating a channel/device - * associated with this offer - */ -static void vmbus_process_offer(struct vmbus_channel *newchannel) +/* Note: the function can run concurrently for primary/sub channels. */ +static void vmbus_add_channel_work(struct work_struct *work) { - struct vmbus_channel *channel; - bool fnew = true; + struct vmbus_channel *newchannel = + container_of(work, struct vmbus_channel, add_channel_work); + struct vmbus_channel *primary_channel = newchannel->primary_channel; unsigned long flags; u16 dev_type; int ret; - /* Make sure this is a new offer */ - mutex_lock(&vmbus_connection.channel_mutex); - - /* -* Now that we have acquired the channel_mutex, -* we can release the potentially racing rescind thread. -*/ - atomic_dec(&vmbus_connection.offer_in_progress); - - list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { - if (!uuid_le_cmp(channel->offermsg.offer.if_type, - newchannel->offermsg.offer.if_type) && - !uuid_le_cmp(channel->offermsg.offer.if_instance, - newchannel->offermsg.offer.if_instance)) { - fnew = false; - break; - } - } - - if (fnew) - list_add_tail(&newchannel->listentry, - &vmbus_connection.chn_list); - - mutex_unlock(&vmbus_connection.channel_mutex); - - if (!fnew) { - /* -* Check to see if this is a sub-channel. -*/ - if (newchannel->offermsg.offer.sub_channel_index != 0) { - /* -* Process the sub-channel. -*/ - newchannel->primary_channel = channel; - spin_lock_irqsave(&channel->lock, flags); - list_add_tail(&newchannel->sc_list, &channel->sc_list); - spin_unlock_irqrestore(&channel->lock, flags); - } else { - goto err_free_chan; - } - } - dev_type = hv_get_dev_type(newchannel); init_vp_index(newchannel, dev_type); @@ -505,27 +461,26 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) /* * This state is used to indicate a successful open * so that when we do close the channel normally, we -* can cleanup properly +* can cleanup properly. */ newchannel->state = CHANNEL_OPEN_STATE; - if (!fnew) { - struct hv_device *dev - = newchann
[PATCH 1/2] Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl()
From: Dexuan Cui This is a longstanding issue: if the vmbus upper-layer drivers try to consume too many GPADLs, the host may return with an error 0xC044 (STATUS_QUOTA_EXCEEDED), but currently we forget to check the creation_status, and hence we can pass an invalid GPADL handle into the OPEN_CHANNEL message, and get an error code 0xc225 in open_info->response.open_result.status, and finally we hang in vmbus_open() -> "goto error_free_info" -> vmbus_teardown_gpadl(). With this patch, we can exit gracefully on STATUS_QUOTA_EXCEEDED. Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Cc: sta...@vger.kernel.org Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index f96a77b18bb9..ce0ba2062723 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -516,6 +516,14 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, } wait_for_completion(&msginfo->waitevent); + if (msginfo->response.gpadl_created.creation_status != 0) { + pr_err("Failed to establish GPADL: err = 0x%x\n", + msginfo->response.gpadl_created.creation_status); + + ret = -EDQUOT; + goto cleanup; + } + if (channel->rescind) { ret = -ENODEV; goto cleanup; -- 2.19.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] Drivers: hv: vmbus: offload the handling of channels to two workqueues
On Mon, Nov 26, 2018 at 02:29:57AM +, k...@linuxonhyperv.com wrote: From: Dexuan Cui vmbus_process_offer() mustn't call channel->sc_creation_callback() directly for sub-channels, because sc_creation_callback() -> vmbus_open() may never get the host's response to the OPEN_CHANNEL message (the host may rescind a channel at any time, e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind() may not wake up the vmbus_open() as it's blocked due to a non-zero vmbus_connection.offer_in_progress, and finally we have a deadlock. The above is also true for primary channels, if the related device drivers use sync probing mode by default. And, usually the handling of primary channels and sub-channels can depend on each other, so we should offload them to different workqueues to avoid possible deadlock, e.g. in sync-probing mode, NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() -> rtnl_lock(), and causes deadlock: the former gets the rtnl_lock and waits for all the sub-channels to appear, but the latter can't get the rtnl_lock and this blocks the handling of sub-channels. The patch can fix the multiple-NIC deadlock described above for v3.x kernels (e.g. RHEL 7.x) which don't support async-probing of devices, and v4.4, v4.9, v4.14 and v4.18 which support async-probing but don't enable async-probing for Hyper-V drivers (yet). The patch can also fix the hang issue in sub-channel's handling described above for all versions of kernels, including v4.19 and v4.20-rc3. So the patch should be applied to all the existing kernels. Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug") Cc: sta...@vger.kernel.org Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan This patch doesn't apply on next/linus/char-misc; there seems to be a missing patch that touches vmbus_process_offer() which isn't a part of this series. -- Thanks, Sasha ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] scsi: storvsc: Fix a race in sub-channel creation that can cause panic
On Mon, Nov 26, 2018 at 12:26:17AM +, k...@linuxonhyperv.com wrote: From: Dexuan Cui We can concurrently try to open the same sub-channel from 2 paths: path #1: vmbus_onoffer() -> vmbus_process_offer() -> handle_sc_creation(). path #2: storvsc_probe() -> storvsc_connect_to_vsp() -> -> storvsc_channel_init() -> handle_multichannel_storage() -> -> vmbus_are_subchannels_present() -> handle_sc_creation(). They conflict with each other, but it was not an issue before the recent commit ae6935ed7d42 ("vmbus: split ring buffer allocation from open"), because at the beginning of vmbus_open() we checked newchannel->state so only one path could succeed, and the other would return with -EINVAL. After ae6935ed7d42, the failing path frees the channel's ringbuffer by vmbus_free_ring(), and this causes a panic later. Commit ae6935ed7d42 itself is good, and it just reveals the longstanding race. We can resolve the issue by removing path #2, i.e. removing the second vmbus_are_subchannels_present() in handle_multichannel_storage(). BTW, the comment "Check to see if sub-channels have already been created" in handle_multichannel_storage() is incorrect: when we unload the driver, we first close the sub-channel(s) and then close the primary channel, next the host sends rescind-offer message(s) so primary->sc_list will become empty. This means the first vmbus_are_subchannels_present() in handle_multichannel_storage() is never useful. Fixes: ae6935ed7d42 ("vmbus: split ring buffer allocation from open") Cc: sta...@vger.kernel.org Cc: Long Li Cc: Stephen Hemminger Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Just a heads-up: ae6935ed7d42 ("vmbus: split ring buffer allocation from open") was merged in the 4.20 merge window, so this fix won't actually apply to any of the current stable trees. However, it's good to have tags (fixes + cc: stable) here since this fix might end up (for whatever reason) getting merged only for 4.21, which will then make these tags relevant. -- Thanks, Sasha ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 7/7] staging:iio:ad2s90: Move out of staging
On Fri, 2018-11-23 at 22:23 -0200, Matheus Tavares wrote: > Move ad2s90 resolver driver out of staging to the main tree. > Acked-by: Alexandru Ardelean > Signed-off-by: Matheus Tavares > Signed-off-by: Victor Colombo > --- > Changes in v3: > - none > > Changes in v2: > - Disabled git move detection, to see the whole code, as Jonathan > suggested > > drivers/iio/resolver/Kconfig | 10 ++ > drivers/iio/resolver/Makefile | 1 + > drivers/iio/resolver/ad2s90.c | 131 ++ > drivers/staging/iio/resolver/Kconfig | 10 -- > drivers/staging/iio/resolver/Makefile | 1 - > drivers/staging/iio/resolver/ad2s90.c | 131 -- > 6 files changed, 142 insertions(+), 142 deletions(-) > create mode 100644 drivers/iio/resolver/ad2s90.c > delete mode 100644 drivers/staging/iio/resolver/ad2s90.c > > diff --git a/drivers/iio/resolver/Kconfig b/drivers/iio/resolver/Kconfig > index 2ced9f22aa70..786801be54f6 100644 > --- a/drivers/iio/resolver/Kconfig > +++ b/drivers/iio/resolver/Kconfig > @@ -3,6 +3,16 @@ > # > menu "Resolver to digital converters" > > +config AD2S90 > + tristate "Analog Devices ad2s90 driver" > + depends on SPI > + help > + Say yes here to build support for Analog Devices spi resolver > + to digital converters, ad2s90, provides direct access via sysfs. > + > + To compile this driver as a module, choose M here: the > + module will be called ad2s90. > + > config AD2S1200 > tristate "Analog Devices ad2s1200/ad2s1205 driver" > depends on SPI > diff --git a/drivers/iio/resolver/Makefile > b/drivers/iio/resolver/Makefile > index 4e1dccae07e7..398d82d50028 100644 > --- a/drivers/iio/resolver/Makefile > +++ b/drivers/iio/resolver/Makefile > @@ -2,4 +2,5 @@ > # Makefile for Resolver/Synchro drivers > # > > +obj-$(CONFIG_AD2S90) += ad2s90.o > obj-$(CONFIG_AD2S1200) += ad2s1200.o > diff --git a/drivers/iio/resolver/ad2s90.c > b/drivers/iio/resolver/ad2s90.c > new file mode 100644 > index ..a41f5cb10da5 > --- /dev/null > +++ b/drivers/iio/resolver/ad2s90.c > @@ -0,0 +1,131 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ad2s90.c simple support for the ADI Resolver to Digital Converters: > AD2S90 > + * > + * Copyright (c) 2010-2010 Analog Devices Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* > + * Although chip's max frequency is 2Mhz, it needs 600ns between CS and > the > + * first falling edge of SCLK, so frequency should be at most 1 / (2 * > 6e-7) > + */ > +#define AD2S90_MAX_SPI_FREQ_HZ 83 > + > +struct ad2s90_state { > + struct mutex lock; /* lock to protect rx buffer */ > + struct spi_device *sdev; > + u8 rx[2] cacheline_aligned; > +}; > + > +static int ad2s90_read_raw(struct iio_dev *indio_dev, > +struct iio_chan_spec const *chan, > +int *val, > +int *val2, > +long m) > +{ > + int ret; > + struct ad2s90_state *st = iio_priv(indio_dev); > + > + if (chan->type != IIO_ANGL) > + return -EINVAL; > + > + switch (m) { > + case IIO_CHAN_INFO_SCALE: > + /* 2 * Pi / 2^12 */ > + *val = 6283; /* mV */ > + *val2 = 12; > + return IIO_VAL_FRACTIONAL_LOG2; > + case IIO_CHAN_INFO_RAW: > + mutex_lock(&st->lock); > + ret = spi_read(st->sdev, st->rx, 2); > + if (ret < 0) { > + mutex_unlock(&st->lock); > + return ret; > + } > + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> > 4); > + > + mutex_unlock(&st->lock); > + > + return IIO_VAL_INT; > + default: > + break; > + } > + > + return -EINVAL; > +} > + > +static const struct iio_info ad2s90_info = { > + .read_raw = ad2s90_read_raw, > +}; > + > +static const struct iio_chan_spec ad2s90_chan = { > + .type = IIO_ANGL, > + .indexed = 1, > + .channel = 0, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | > BIT(IIO_CHAN_INFO_SCALE), > +}; > + > +static int ad2s90_probe(struct spi_device *spi) > +{ > + struct iio_dev *indio_dev; > + struct ad2s90_state *st; > + > + if (spi->max_speed_hz > AD2S90_MAX_SPI_FREQ_HZ) { > + dev_err(&spi->dev, "SPI CLK, %d Hz exceeds %d Hz\n", > + spi->max_speed_hz, AD2S90_MAX_SPI_FREQ_HZ); > + return -EINVAL; > + } > + > + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + st = iio_priv(indio_dev); > + spi_set_drvdata(spi, indio_dev); > + > + mutex_init(&st->lock); > + st->sdev = spi; > + indio_dev->dev.parent = &spi->dev; > + indio_dev->info = &ad2s90_info; > + indio_dev->modes