From 467a44b0372d8268ce5bd90e58bde7db51c1d476 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: iio: adc: at91_adc: Repair broken platform_data support Trying to use the at91_adc driver while not using device tree is ending up in a kernel crash: Unable to handle kernel NULL pointer dereference at virtual address 00000004 [...] [] (at91_adc_probe) from [] (platform_drv_probe+0x18/0x48) [] (platform_drv_probe) from [] (driver_probe_device+0x100/0x218) [] (driver_probe_device) from [] (__driver_attach+0x8c/0x90) [] (__driver_attach) from [] (bus_for_each_dev+0x58/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xd4/0x1d4) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (do_one_initcall+0xe8/0x14c) [] (do_one_initcall) from [] (kernel_init_freeable+0xec/0x1b4) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xe4) [] (kernel_init) from [] (ret_from_fork+0x14/0x24) This is because the at91_adc_caps structure is mandatory but is not filled when using platform_data. Correct that by using an id_table. It ensues that the driver will not match "at91_adc" anymore but it was crashing anyway. Fixes: c46016665fff (iio: at91: ADC start-up time calculation changed since at91sam9x5) Cc: stable@vger.kernel.org # v3.13+ Signed-off-by: Alexandre Belloni Tested-by: Josh Wu Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 5b1aa027c034..bbba014c9939 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -765,14 +765,17 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, if (!pdata) return -EINVAL; + st->caps = (struct at91_adc_caps *) + platform_get_device_id(pdev)->driver_data; + st->use_external = pdata->use_external_triggers; st->vref_mv = pdata->vref; st->channels_mask = pdata->channels_used; - st->num_channels = pdata->num_channels; + st->num_channels = st->caps->num_channels; st->startup_time = pdata->startup_time; st->trigger_number = pdata->trigger_number; st->trigger_list = pdata->trigger_list; - st->registers = pdata->registers; + st->registers = &st->caps->registers; return 0; } @@ -1101,7 +1104,6 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static struct at91_adc_caps at91sam9260_caps = { .calc_startup_ticks = calc_startup_ticks_9260, .num_channels = 4, @@ -1154,11 +1156,27 @@ static const struct of_device_id at91_adc_dt_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); -#endif + +static const struct platform_device_id at91_adc_ids[] = { + { + .name = "at91sam9260-adc", + .driver_data = (unsigned long)&at91sam9260_caps, + }, { + .name = "at91sam9g45-adc", + .driver_data = (unsigned long)&at91sam9g45_caps, + }, { + .name = "at91sam9x5-adc", + .driver_data = (unsigned long)&at91sam9x5_caps, + }, { + /* terminator */ + } +}; +MODULE_DEVICE_TABLE(platform, at91_adc_ids); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, .remove = at91_adc_remove, + .id_table = at91_adc_ids, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(at91_adc_dt_ids), -- cgit v1.2.3 From 41c897f8789d0d1039ed873ddcd0caabd5756e0f Mon Sep 17 00:00:00 2001 From: Beomho Seo Date: Wed, 3 Dec 2014 00:57:00 +0000 Subject: iio: cm32181: Fix read integration time function In read integration time function, assign 0 to val. Because, prevent return inaccurate value when call read integration time. Cc: Stable@vger.kernel.org Cc: Kevin Tsai Signed-off-by: Beomho Seo Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm32181.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 47a6dbac2d0c..d976e6ce60db 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -221,6 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, *val = cm32181->calibscale; return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: + *val = 0; ret = cm32181_read_als_it(cm32181, val2); return ret; } -- cgit v1.2.3 From 142df13b7598d88de5b163464e74d2101912f479 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: ARM: at91: at91sam9g45: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index cb36fa872d30..88554024eb2d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1203,7 +1203,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9g45-adc", .id = -1, .dev = { .platform_data = &adc_data, -- cgit v1.2.3 From 301841a634976c1cef4490cae577ffd0f26d0149 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: ARM: at91: at91sam9260: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index eda8d1679d40..0a0315920963 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -1292,7 +1292,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9260-adc", .id = -1, .dev = { .platform_data = &adc_data, -- cgit v1.2.3 From 8f32b6ba56ef8c8434635b9f08ff6a23510960a5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 3 Mar 2014 18:07:00 +0000 Subject: iio: adc: at91_adc: correct default shtim value When sample_hold_time is zero (this is the case when DT is not used or if atmel,adc-sample-hold-time is omitted), then the calculated shtim is large. Make that 0, which is the default for that register and the ADC will then use a sane value of 2/ADCCLK or 1/ADCCLK depending on the version. Signed-off-by: Alexandre Belloni Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index bbba014c9939..89777ed9abd8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1007,8 +1007,11 @@ static int at91_adc_probe(struct platform_device *pdev) * the best converted final value between two channels selection * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock */ - shtim = round_up((st->sample_hold_time * adc_clk_khz / - 1000) - 1, 1); + if (st->sample_hold_time > 0) + shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000) + - 1, 1); + else + shtim = 0; reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; -- cgit v1.2.3 From 6b9da2e77249bd62bb0902319cfa22398f32c538 Mon Sep 17 00:00:00 2001 From: Jimmy Li Date: Sat, 22 Mar 2014 05:58:00 +0000 Subject: staging:iio:ad2s1200 fix a missing break Signed-off-by: Jimmy Li Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 36eedd8a0ea9..e2b482045158 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -70,6 +70,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); vel = (vel << 4) >> 4; *val = vel; + break; default: mutex_unlock(&st->lock); return -EINVAL; -- cgit v1.2.3 From 2076a20fc1a06f7b0333c62a2bb4eeeac7ed1bcb Mon Sep 17 00:00:00 2001 From: Alec Berg Date: Wed, 19 Mar 2014 18:50:00 +0000 Subject: iio: querying buffer scan_mask should return 0/1 Ensure that querying the IIO buffer scan_mask returns a value of 0 or 1. Currently querying the scan mask has the value returned by test_bit(), which returns either true or false. For some architectures test_bit() may return -1 for true, which will appear to return an error when returning from iio_scan_mask_query(). Additionally, it's important for the sysfs interface to consistently return the same thing when querying the scan_mask. Signed-off-by: Alec Berg Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c67d83bdc8f0..fe25042f056a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -165,7 +165,8 @@ static ssize_t iio_scan_el_show(struct device *dev, int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); - ret = test_bit(to_iio_dev_attr(attr)->address, + /* Ensure ret is 0 or 1. */ + ret = !!test_bit(to_iio_dev_attr(attr)->address, indio_dev->buffer->scan_mask); return sprintf(buf, "%d\n", ret); @@ -866,7 +867,8 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, if (!buffer->scan_mask) return 0; - return test_bit(bit, buffer->scan_mask); + /* Ensure return value is 0 or 1. */ + return !!test_bit(bit, buffer->scan_mask); }; EXPORT_SYMBOL_GPL(iio_scan_mask_query); -- cgit v1.2.3 From d0a588a57c2b0748df8307a0865a1bbbf1624c53 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 18 Mar 2014 08:13:00 +0000 Subject: iio: cm36651: Fix i2c client leak and possible NULL pointer dereference During probe the driver allocates dummy I2C devices (i2c_new_dummy()) but they aren't unregistered during driver remove or probe failure. Additionally driver does not check the return value of i2c_new_dummy(). In case of error (i2c_new_device(): memory allocation failure or I2C address cannot be used) this function returns NULL which is later dereferenced by i2c_smbus_{read,write}_data() functions. Fix issues by properly checking for i2c_new_dummy() return value and unregistering I2C devices on driver remove or probe failure. Signed-off-by: Krzysztof Kozlowski Acked-by: Beomho Seo Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm36651.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index a45e07492db3..39fc67e82138 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -652,7 +652,19 @@ static int cm36651_probe(struct i2c_client *client, cm36651->client = client; cm36651->ps_client = i2c_new_dummy(client->adapter, CM36651_I2C_ADDR_PS); + if (!cm36651->ps_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_disable_reg; + } + cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA); + if (!cm36651->ara_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_i2c_unregister_ps; + } + mutex_init(&cm36651->lock); indio_dev->dev.parent = &client->dev; indio_dev->channels = cm36651_channels; @@ -664,7 +676,7 @@ static int cm36651_probe(struct i2c_client *client, ret = cm36651_setup_reg(cm36651); if (ret) { dev_err(&client->dev, "%s: register setup failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler, @@ -672,7 +684,7 @@ static int cm36651_probe(struct i2c_client *client, "cm36651", indio_dev); if (ret) { dev_err(&client->dev, "%s: request irq failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = iio_device_register(indio_dev); @@ -685,6 +697,10 @@ static int cm36651_probe(struct i2c_client *client, error_free_irq: free_irq(client->irq, indio_dev); +error_i2c_unregister_ara: + i2c_unregister_device(cm36651->ara_client); +error_i2c_unregister_ps: + i2c_unregister_device(cm36651->ps_client); error_disable_reg: regulator_disable(cm36651->vled_reg); return ret; @@ -698,6 +714,8 @@ static int cm36651_remove(struct i2c_client *client) iio_device_unregister(indio_dev); regulator_disable(cm36651->vled_reg); free_irq(client->irq, indio_dev); + i2c_unregister_device(cm36651->ps_client); + i2c_unregister_device(cm36651->ara_client); return 0; } -- cgit v1.2.3 From e036f71e8ce310dc58b1351c3eb967b892f4641c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 17 Mar 2014 16:43:00 +0000 Subject: iio: adc: mxs-lradc: fix warning when buidling on avr32 This fixes: drivers/staging/iio/adc/mxs-lradc.c: In function 'mxs_lradc_probe': drivers/staging/iio/adc/mxs-lradc.c:1558: warning: comparison of distinct pointer types lacks a cast drivers/staging/iio/adc/mxs-lradc.c:1558: warning: right shift count >= width of type drivers/staging/iio/adc/mxs-lradc.c:1558: warning: passing argument 1 of '__div64_32' from incompatible pointer type When building on avr32. Reported-by: Fengguang Wu Signed-off-by: Alexandre Belloni Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 514844efac75..53b3f963a7e3 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1527,7 +1527,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) struct resource *iores; int ret = 0, touch_ret; int i, s; - unsigned int scale_uv; + uint64_t scale_uv; /* Allocate the IIO device. */ iio = devm_iio_device_alloc(dev, sizeof(*lradc)); -- cgit v1.2.3 From 2704f807f9498054b8153002bafa3e818079e9a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 28 Mar 2014 09:20:58 -0700 Subject: staging: comedi: usbdux: bug fix for accessing 'ao_chanlist' in private data In usbdux_ao_cmd(), the channels for the command are transfered from the cmd->chanlist and stored in the private data 'ao_chanlist'. The channel numbers are bit-shifted when stored so that they become the "command" that is transfered to the device. The channel to command conversion results in the 'ao_chanlist' having these values for the channels: channel 0 -> ao_chanlist = 0x00 channel 1 -> ao_chanlist = 0x40 channel 2 -> ao_chanlist = 0x80 channel 3 -> ao_chanlist = 0xc0 The problem is, the usbduxsub_ao_isoc_irq() function uses the 'chan' value from 'ao_chanlist' to access the 'ao_readback' array in the private data. So instead of accessing the array as 0, 1, 2, 3, it accesses it as 0x00, 0x40, 0x80, 0xc0. Fix this by storing the raw channel number in 'ao_chanlist' and doing the bit-shift when creating the command. Fixes: a998a3db530bff80 "staging: comedi: usbdux: cleanup the private data 'outBuffer'" Cc: stable # 3.12 Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Acked-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 71db683098d6..b59af0303581 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -493,7 +493,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) /* pointer to the DA */ *datap++ = val & 0xff; *datap++ = (val >> 8) & 0xff; - *datap++ = chan; + *datap++ = chan << 6; devpriv->ao_readback[chan] = val; s->async->events |= COMEDI_CB_BLOCK; @@ -1040,11 +1040,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; - for (i = 0; i < cmd->chanlist_len; ++i) { - unsigned int chan = CR_CHAN(cmd->chanlist[i]); - - devpriv->ao_chanlist[i] = chan << 6; - } + for (i = 0; i < cmd->chanlist_len; ++i) + devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]); /* we count in steps of 1ms (125us) */ /* 125us mode not used yet */ -- cgit v1.2.3