From: Greg Kroah-Hartman Date: Wed, 17 Jul 2013 05:41:38 +0000 (-0700) Subject: Merge tag 'iio-fixes-for-3.11a' of git://git.kernel.org/pub/scm/linux/kernel/git... X-Git-Tag: v3.11-rc2~3^2 X-Git-Url: http://git.cascardo.info/?p=cascardo%2Flinux.git;a=commitdiff_plain;h=78077256bc08348d587e318957ceb41fe4d4afae;hp=-c Merge tag 'iio-fixes-for-3.11a' of git://git./linux/kernel/git/jic23/iio into staging-linus Jonathan writes: The first round of IIO fixes for the 3.11 cycle. This set is larger than I would like, partly due to my lack of review time in the weeks before the merge window and partly because a couple of large drivers and the subsystem as a whole seem to be getting a lot more exposure and testing recently. 1) A long term bug in trigger handling gave a double free of the device. 2) Wrong return value handling means offsets are ignored in iio_convert_raw_to_processed_unlocked. 3) The iio_channel_has_info utility function was incorrectly updated during the recent info_mask split, this is now fixed. 4) mxs-lradc has a couple of little fixes. 5) A couple of missing .driver_module entries meant that drivers could be removed from underneath their users. 6) Error path fixes for ad7303 and lis3l02dq. 7) The scale value for presure in the lps331ap driver was out by a factor of 100. --- 78077256bc08348d587e318957ceb41fe4d4afae diff --combined drivers/iio/adc/ti_am335x_adc.c index 4427e8e46a7f,985f58873d03..0ad208a69c29 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@@ -22,18 -22,13 +22,18 @@@ #include #include #include +#include +#include +#include +#include #include -#include struct tiadc_device { struct ti_tscadc_dev *mfd_tscadc; int channels; + u8 channel_line[8]; + u8 channel_step[8]; }; static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) @@@ -47,20 -42,10 +47,20 @@@ static void tiadc_writel(struct tiadc_d writel(val, adc->mfd_tscadc->tscadc_base + reg); } +static u32 get_adc_step_mask(struct tiadc_device *adc_dev) +{ + u32 step_en; + + step_en = ((1 << adc_dev->channels) - 1); + step_en <<= TOTAL_STEPS - adc_dev->channels + 1; + return step_en; +} + static void tiadc_step_config(struct tiadc_device *adc_dev) { unsigned int stepconfig; - int i, channels = 0, steps; + int i, steps; + u32 step_en; /* * There are 16 configurable steps and 8 analog input @@@ -73,63 -58,43 +73,63 @@@ */ steps = TOTAL_STEPS - adc_dev->channels; - channels = TOTAL_CHANNELS - adc_dev->channels; - stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; - for (i = (steps + 1); i <= TOTAL_STEPS; i++) { - tiadc_writel(adc_dev, REG_STEPCONFIG(i), - stepconfig | STEPCONFIG_INP(channels)); - tiadc_writel(adc_dev, REG_STEPDELAY(i), + for (i = 0; i < adc_dev->channels; i++) { + int chan; + + chan = adc_dev->channel_line[i]; + tiadc_writel(adc_dev, REG_STEPCONFIG(steps), + stepconfig | STEPCONFIG_INP(chan)); + tiadc_writel(adc_dev, REG_STEPDELAY(steps), STEPCONFIG_OPENDLY); - channels++; + adc_dev->channel_step[i] = steps; + steps++; } - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); + step_en = get_adc_step_mask(adc_dev); + am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); } +static const char * const chan_name_ain[] = { + "AIN0", + "AIN1", + "AIN2", + "AIN3", + "AIN4", + "AIN5", + "AIN6", + "AIN7", +}; + static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) { + struct tiadc_device *adc_dev = iio_priv(indio_dev); struct iio_chan_spec *chan_array; + struct iio_chan_spec *chan; int i; indio_dev->num_channels = channels; - chan_array = kcalloc(indio_dev->num_channels, + chan_array = kcalloc(channels, sizeof(struct iio_chan_spec), GFP_KERNEL); - if (chan_array == NULL) return -ENOMEM; - for (i = 0; i < (indio_dev->num_channels); i++) { - struct iio_chan_spec *chan = chan_array + i; + chan = chan_array; + for (i = 0; i < channels; i++, chan++) { + chan->type = IIO_VOLTAGE; chan->indexed = 1; - chan->channel = i; + chan->channel = adc_dev->channel_line[i]; chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->datasheet_name = chan_name_ain[chan->channel]; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 12; + chan->scan_type.storagebits = 32; } indio_dev->channels = chan_array; - return indio_dev->num_channels; + return 0; } static void tiadc_channels_remove(struct iio_dev *indio_dev) @@@ -143,9 -108,7 +143,9 @@@ static int tiadc_read_raw(struct iio_de { struct tiadc_device *adc_dev = iio_priv(indio_dev); int i; - unsigned int fifo1count, readx1; + unsigned int fifo1count, read; + u32 step = UINT_MAX; + bool found = false; /* * When the sub-system is first enabled, @@@ -158,46 -121,33 +158,47 @@@ * Hence we need to flush out this data. */ + for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) { + if (chan->channel == adc_dev->channel_line[i]) { + step = adc_dev->channel_step[i]; + break; + } + } + if (WARN_ON_ONCE(step == UINT_MAX)) + return -EINVAL; + fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); for (i = 0; i < fifo1count; i++) { - readx1 = tiadc_readl(adc_dev, REG_FIFO1); - if (i == chan->channel) - *val = readx1 & 0xfff; + read = tiadc_readl(adc_dev, REG_FIFO1); + if (read >> 16 == step) { + *val = read & 0xfff; + found = true; + } } - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); - + am335x_tsc_se_update(adc_dev->mfd_tscadc); + if (found == false) + return -EBUSY; return IIO_VAL_INT; } static const struct iio_info tiadc_info = { .read_raw = &tiadc_read_raw, + .driver_module = THIS_MODULE, }; static int tiadc_probe(struct platform_device *pdev) { struct iio_dev *indio_dev; struct tiadc_device *adc_dev; - struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; - struct mfd_tscadc_board *pdata; + struct device_node *node = pdev->dev.of_node; + struct property *prop; + const __be32 *cur; int err; + u32 val; + int channels = 0; - pdata = tscadc_dev->dev->platform_data; - if (!pdata || !pdata->adc_init) { - dev_err(&pdev->dev, "Could not find platform data\n"); + if (!node) { + dev_err(&pdev->dev, "Could not find valid DT data.\n"); return -EINVAL; } @@@ -209,13 -159,8 +210,13 @@@ } adc_dev = iio_priv(indio_dev); - adc_dev->mfd_tscadc = tscadc_dev; - adc_dev->channels = pdata->adc_init->adc_channels; + adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev); + + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { + adc_dev->channel_line[channels] = val; + channels++; + } + adc_dev->channels = channels; indio_dev->dev.parent = &pdev->dev; indio_dev->name = dev_name(&pdev->dev); @@@ -247,15 -192,10 +248,15 @@@ err_ret static int tiadc_remove(struct platform_device *pdev) { struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct tiadc_device *adc_dev = iio_priv(indio_dev); + u32 step_en; iio_device_unregister(indio_dev); tiadc_channels_remove(indio_dev); + step_en = get_adc_step_mask(adc_dev); + am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en); + iio_device_free(indio_dev); return 0; @@@ -266,10 -206,9 +267,10 @@@ static int tiadc_suspend(struct device { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct tiadc_device *adc_dev = iio_priv(indio_dev); - struct ti_tscadc_dev *tscadc_dev = dev->platform_data; + struct ti_tscadc_dev *tscadc_dev; unsigned int idle; + tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); if (!device_may_wakeup(tscadc_dev->dev)) { idle = tiadc_readl(adc_dev, REG_CTRL); idle &= ~(CNTRLREG_TSCSSENB); @@@ -305,22 -244,16 +306,22 @@@ static const struct dev_pm_ops tiadc_pm #define TIADC_PM_OPS NULL #endif +static const struct of_device_id ti_adc_dt_ids[] = { + { .compatible = "ti,am3359-adc", }, + { } +}; +MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); + static struct platform_driver tiadc_driver = { .driver = { - .name = "tiadc", + .name = "TI-am335x-adc", .owner = THIS_MODULE, .pm = TIADC_PM_OPS, + .of_match_table = of_match_ptr(ti_adc_dt_ids), }, .probe = tiadc_probe, .remove = tiadc_remove, }; - module_platform_driver(tiadc_driver); MODULE_DESCRIPTION("TI ADC controller driver");