On Wed, 15 Nov 2017 14:56:47 +0200 Eugen Hristev <eugen.hristev@xxxxxxxxxxxxx> wrote: > Added support for DMA transfers. The implementation uses the user watermark > to decide whether DMA will be used or not. For watermark 1, DMA will not be > used. If watermark is bigger, DMA will be used. > Sysfs attributes are created to indicate whether the DMA is used, > with hwfifo_enabled, and the current DMA watermark is readable > in hwfifo_watermark. Minimum and maximum values are in hwfifo_watermark_min > and hwfifo_watermark_max. > > Signed-off-by: Eugen Hristev <eugen.hristev@xxxxxxxxxxxxx> A tiny nitpick inline but otherwise looks fine to me. Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > Changes in v3: > - Remove misleaded dev_info message when DMA was not enabled at probe > - Rebased patch on top of the > [PATCH] iio: adc: at91-sama5d2_adc: fix probe error on missing trigger property > Which is already upstreamed in 4.14 > - Fixed the bug introduced in v2, with buffer size > - added extra check when enabling DMA, to have hw trigger present. > This is because now, we can have the driver with software trigger only (if no > hw trigger in device tree, start as software only) > > Changes in v2: > - No longer add last timestamp to all samples. Now, compute an interval > between samples w.r.t. start and end time of the transfer and number > of samples. Then distribute them each in the time interval. > - Add warning for conversion overrun. This helps user identify cases > when the watermark needs adjustment : the software is too slow in reading > data from the ADC. > - Protection around watermark is not needed, changing of the watermark > cannot be done while the buffer is enabled. When buffer is disabled, all > DMA resources are freed anyway. > - Added validation on trigger to be used by own device > - Best sample rate I could obtain using the low frequency clock was about > 4k samples/second, with a watermark of 100. To get up to 50k samples/second > the ADC frequency must be increased to max. > - Fixed computation of DMA buffer size > - Addressed other comments from mailing list review. Feedback is appreciated > > drivers/iio/adc/Kconfig | 1 + > drivers/iio/adc/at91-sama5d2_adc.c | 453 +++++++++++++++++++++++++++++++++++-- > 2 files changed, 434 insertions(+), 20 deletions(-) > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 1d13bf0..1a3a8e3 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC > tristate "Atmel AT91 SAMA5D2 ADC" > depends on ARCH_AT91 || COMPILE_TEST > depends on HAS_IOMEM > + depends on HAS_DMA > select IIO_TRIGGERED_BUFFER > help > Say yes here to build support for Atmel SAMA5D2 ADC which is > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c > index a70ef7f..11d34a8 100644 > --- a/drivers/iio/adc/at91-sama5d2_adc.c > +++ b/drivers/iio/adc/at91-sama5d2_adc.c > @@ -16,6 +16,8 @@ > > #include <linux/bitops.h> > #include <linux/clk.h> > +#include <linux/dma-mapping.h> > +#include <linux/dmaengine.h> > #include <linux/interrupt.h> > #include <linux/io.h> > #include <linux/module.h> > @@ -100,6 +102,8 @@ > #define AT91_SAMA5D2_LCDR 0x20 > /* Interrupt Enable Register */ > #define AT91_SAMA5D2_IER 0x24 > +/* Interrupt Enable Register - general overrun error */ > +#define AT91_SAMA5D2_IER_GOVRE BIT(25) > /* Interrupt Disable Register */ > #define AT91_SAMA5D2_IDR 0x28 > /* Interrupt Mask Register */ > @@ -167,13 +171,19 @@ > > /* > * Maximum number of bytes to hold conversion from all channels > - * plus the timestamp > + * without the timestamp. > */ > -#define AT91_BUFFER_MAX_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \ > - AT91_SAMA5D2_DIFF_CHAN_CNT) * 2 + 8) > +#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \ > + AT91_SAMA5D2_DIFF_CHAN_CNT) * 2) > + > +/* This total must also include the timestamp */ > +#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8) > > #define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2) > > +#define AT91_HWFIFO_MAX_SIZE_STR "128" > +#define AT91_HWFIFO_MAX_SIZE 128 > + > #define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ > { \ > .type = IIO_VOLTAGE, \ > @@ -228,6 +238,28 @@ struct at91_adc_trigger { > bool hw_trig; > }; > > +/** > + * at91_adc_dma - at91-sama5d2 dma information struct > + * @dma_chan: the dma channel acquired > + * @rx_buf: dma coherent allocated area > + * @rx_dma_buf: dma handler for the buffer > + * @phys_addr: physical address of the ADC base register > + * @buf_idx: index inside the dma buffer where reading was last done > + * @rx_buf_sz: size of buffer used by DMA operation > + * @watermark: number of conversions to copy before DMA triggers irq > + * @dma_ts: hold the start timestamp of dma operation > + */ > +struct at91_adc_dma { > + struct dma_chan *dma_chan; > + u8 *rx_buf; > + dma_addr_t rx_dma_buf; > + phys_addr_t phys_addr; > + int buf_idx; > + int rx_buf_sz; > + int watermark; > + s64 dma_ts; > +}; > + > struct at91_adc_state { > void __iomem *base; > int irq; > @@ -242,6 +274,7 @@ struct at91_adc_state { > u32 conversion_value; > struct at91_adc_soc_info soc_info; > wait_queue_head_t wq_data_available; > + struct at91_adc_dma dma_st; > u16 buffer[AT91_BUFFER_MAX_HWORDS]; > /* > * lock to prevent concurrent 'single conversion' requests through > @@ -322,11 +355,17 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) > if (state) { > at91_adc_writel(st, AT91_SAMA5D2_CHER, > BIT(chan->channel)); > - at91_adc_writel(st, AT91_SAMA5D2_IER, > - BIT(chan->channel)); > + /* enable irq only if not using DMA */ > + if (!st->dma_st.dma_chan) { > + at91_adc_writel(st, AT91_SAMA5D2_IER, > + BIT(chan->channel)); > + } > } else { > - at91_adc_writel(st, AT91_SAMA5D2_IDR, > - BIT(chan->channel)); > + /* disable irq only if not using DMA */ > + if (!st->dma_st.dma_chan) { > + at91_adc_writel(st, AT91_SAMA5D2_IDR, > + BIT(chan->channel)); > + } > at91_adc_writel(st, AT91_SAMA5D2_CHDR, > BIT(chan->channel)); > } > @@ -340,6 +379,10 @@ static int at91_adc_reenable_trigger(struct iio_trigger *trig) > struct iio_dev *indio = iio_trigger_get_drvdata(trig); > struct at91_adc_state *st = iio_priv(indio); > > + /* if we are using DMA, we must not reenable irq after each trigger */ > + if (st->dma_st.dma_chan) > + return 0; > + > enable_irq(st->irq); > > /* Needed to ACK the DRDY interruption */ > @@ -351,6 +394,153 @@ static const struct iio_trigger_ops at91_adc_trigger_ops = { > .owner = THIS_MODULE, > .set_trigger_state = &at91_adc_configure_trigger, > .try_reenable = &at91_adc_reenable_trigger, > + .validate_device = iio_trigger_validate_own_device, > +}; > + > +static int at91_adc_dma_size_done(struct at91_adc_state *st) > +{ > + struct dma_tx_state state; > + enum dma_status status; > + int i, size; > + > + status = dmaengine_tx_status(st->dma_st.dma_chan, > + st->dma_st.dma_chan->cookie, > + &state); > + if (status != DMA_IN_PROGRESS) > + return 0; > + > + /* Transferred length is size in bytes from end of buffer */ > + i = st->dma_st.rx_buf_sz - state.residue; > + > + /* Return available bytes */ > + if (i >= st->dma_st.buf_idx) > + size = i - st->dma_st.buf_idx; > + else > + size = st->dma_st.rx_buf_sz + i - st->dma_st.buf_idx; > + return size; > +} > + > +static void at91_dma_buffer_done(void *data) > +{ > + struct iio_dev *indio_dev = data; > + > + iio_trigger_poll_chained(indio_dev->trig); > +} > + > +static int at91_adc_dma_start(struct iio_dev *indio_dev) > +{ > + struct at91_adc_state *st = iio_priv(indio_dev); > + struct dma_async_tx_descriptor *desc; > + dma_cookie_t cookie; > + int ret; > + u8 bit; > + > + if (!st->dma_st.dma_chan) > + return 0; > + > + /* we start a new DMA, so set buffer index to start */ > + st->dma_st.buf_idx = 0; > + > + /* > + * compute buffer size w.r.t. watermark and enabled channels. > + * scan_bytes is aligned so we need an exact size for DMA > + */ > + st->dma_st.rx_buf_sz = 0; > + > + for_each_set_bit(bit, indio_dev->active_scan_mask, > + indio_dev->num_channels) { > + struct iio_chan_spec const *chan = indio_dev->channels + bit; > + > + st->dma_st.rx_buf_sz += chan->scan_type.storagebits / 8; > + } > + st->dma_st.rx_buf_sz *= st->dma_st.watermark; > + > + /* Prepare a DMA cyclic transaction */ > + desc = dmaengine_prep_dma_cyclic(st->dma_st.dma_chan, > + st->dma_st.rx_dma_buf, > + st->dma_st.rx_buf_sz, > + st->dma_st.rx_buf_sz / 2, > + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); > + > + if (!desc) { > + dev_err(&indio_dev->dev, "cannot prepare DMA cyclic\n"); > + return -EBUSY; > + } > + > + desc->callback = at91_dma_buffer_done; > + desc->callback_param = indio_dev; > + > + cookie = dmaengine_submit(desc); > + ret = dma_submit_error(cookie); > + if (ret) { > + dev_err(&indio_dev->dev, "cannot submit DMA cyclic\n"); > + dmaengine_terminate_async(st->dma_st.dma_chan); > + return ret; > + } > + > + /* enable general overrun error signaling */ > + at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE); > + /* Issue pending DMA requests */ > + dma_async_issue_pending(st->dma_st.dma_chan); > + > + /* consider current time as DMA start time for timestamps */ > + st->dma_st.dma_ts = iio_get_time_ns(indio_dev); > + > + dev_dbg(&indio_dev->dev, "DMA cyclic started\n"); > + > + return 0; > +} > + > +static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) > +{ > + int ret; > + > + ret = at91_adc_dma_start(indio_dev); > + if (ret) { > + dev_err(&indio_dev->dev, "buffer postenable failed\n"); > + return ret; > + } > + > + return iio_triggered_buffer_postenable(indio_dev); > +} > + > +static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) > +{ > + struct at91_adc_state *st = iio_priv(indio_dev); > + int ret; > + u8 bit; > + > + ret = iio_triggered_buffer_predisable(indio_dev); > + if (ret < 0) > + dev_err(&indio_dev->dev, "buffer predisable failed\n"); > + > + if (!st->dma_st.dma_chan) > + return ret; > + > + /* if we are using DMA we must clear registers and end DMA */ > + dmaengine_terminate_sync(st->dma_st.dma_chan); > + > + /* > + * For each enabled channel we must read the last converted value > + * to clear EOC status and not get a possible interrupt later. > + * This value is being read by DMA from LCDR anyway > + */ > + for_each_set_bit(bit, indio_dev->active_scan_mask, > + indio_dev->num_channels) { > + struct iio_chan_spec const *chan = indio_dev->channels + bit; > + > + if (st->dma_st.dma_chan) > + at91_adc_readl(st, chan->address); > + } > + > + /* read overflow register to clear possible overflow status */ > + at91_adc_readl(st, AT91_SAMA5D2_OVER); > + return ret; > +} > + > +static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { > + .postenable = &at91_adc_buffer_postenable, > + .predisable = &at91_adc_buffer_predisable, > }; > > static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio, > @@ -389,24 +579,77 @@ static int at91_adc_trigger_init(struct iio_dev *indio) > return 0; > } > > -static irqreturn_t at91_adc_trigger_handler(int irq, void *p) > +static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev, > + struct iio_poll_func *pf) > { > - struct iio_poll_func *pf = p; > - struct iio_dev *indio = pf->indio_dev; > - struct at91_adc_state *st = iio_priv(indio); > + struct at91_adc_state *st = iio_priv(indio_dev); > int i = 0; > u8 bit; > > - for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { > - struct iio_chan_spec const *chan = indio->channels + bit; > + for_each_set_bit(bit, indio_dev->active_scan_mask, > + indio_dev->num_channels) { > + struct iio_chan_spec const *chan = indio_dev->channels + bit; > > st->buffer[i] = at91_adc_readl(st, chan->address); > i++; > } > + iio_push_to_buffers_with_timestamp(indio_dev, st->buffer, > + pf->timestamp); > +} > + > +static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev) > +{ > + struct at91_adc_state *st = iio_priv(indio_dev); > + int transferred_len = at91_adc_dma_size_done(st); > + s64 ns = iio_get_time_ns(indio_dev); > + s64 interval; > + int sample_index = 0, sample_count, sample_size; > + > + u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR); > + /* if we reached this point, we cannot sample faster */ > + if (status & AT91_SAMA5D2_IER_GOVRE) > + pr_info_ratelimited("%s: conversion overrun detected\n", > + indio_dev->name); > + > + sample_size = div_s64(st->dma_st.rx_buf_sz, st->dma_st.watermark); > + > + sample_count = div_s64(transferred_len, sample_size); > + > + /* > + * interval between samples is total time since last transfer handling > + * divided by the number of samples (total size divided by sample size) > + */ > + interval = div_s64((ns - st->dma_st.dma_ts), sample_count); > + > + while (transferred_len >= sample_size) { > + iio_push_to_buffers_with_timestamp(indio_dev, > + (st->dma_st.rx_buf + st->dma_st.buf_idx), > + (st->dma_st.dma_ts + interval * sample_index)); > + /* adjust remaining length */ > + transferred_len -= sample_size; > + /* adjust buffer index */ > + st->dma_st.buf_idx += sample_size; > + /* in case of reaching end of buffer, reset index */ > + if (st->dma_st.buf_idx >= st->dma_st.rx_buf_sz) > + st->dma_st.buf_idx = 0; > + sample_index++; > + } > + /* adjust saved time for next transfer handling */ > + st->dma_st.dma_ts = iio_get_time_ns(indio_dev); > +} > + > +static irqreturn_t at91_adc_trigger_handler(int irq, void *p) > +{ > + struct iio_poll_func *pf = p; > + struct iio_dev *indio_dev = pf->indio_dev; > + struct at91_adc_state *st = iio_priv(indio_dev); > > - iio_push_to_buffers_with_timestamp(indio, st->buffer, pf->timestamp); > + if (st->dma_st.dma_chan) > + at91_adc_trigger_handler_dma(indio_dev); > + else > + at91_adc_trigger_handler_nodma(indio_dev, pf); > > - iio_trigger_notify_done(indio->trig); > + iio_trigger_notify_done(indio_dev->trig); > > return IRQ_HANDLED; > } > @@ -415,7 +658,7 @@ static int at91_adc_buffer_init(struct iio_dev *indio) > { > return devm_iio_triggered_buffer_setup(&indio->dev, indio, > &iio_pollfunc_store_time, > - &at91_adc_trigger_handler, NULL); > + &at91_adc_trigger_handler, &at91_buffer_setup_ops); > } > > static unsigned at91_adc_startup_time(unsigned startup_time_min, > @@ -486,10 +729,13 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private) > if (!(status & imr)) > return IRQ_NONE; > > - if (iio_buffer_enabled(indio)) { > + if (iio_buffer_enabled(indio) && !st->dma_st.dma_chan) { > disable_irq_nosync(irq); > iio_trigger_poll(indio->trig); > - } else { > + } else if (iio_buffer_enabled(indio) && st->dma_st.dma_chan) { > + disable_irq_nosync(irq); > + WARN(true, "Unexpected irq occurred\n"); > + } else if (!iio_buffer_enabled(indio)) { > st->conversion_value = at91_adc_readl(st, st->chan->address); > st->conversion_done = true; > wake_up_interruptible(&st->wq_data_available); > @@ -511,7 +757,6 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, > ret = iio_device_claim_direct_mode(indio_dev); > if (ret) > return ret; > - Real nitpick, but this is an unrelated change... Should not be here. > mutex_lock(&st->lock); > > st->chan = chan; > @@ -581,9 +826,123 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev, > return 0; > } > > +static void at91_adc_dma_init(struct platform_device *pdev) > +{ > + struct iio_dev *indio_dev = platform_get_drvdata(pdev); > + struct at91_adc_state *st = iio_priv(indio_dev); > + struct dma_slave_config config = {0}; > + /* > + * We make the buffer double the size of the fifo, > + * such that DMA uses one half of the buffer (full fifo size) > + * and the software uses the other half to read/write. > + */ > + unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE * > + AT91_BUFFER_MAX_CONVERSION_BYTES * 2, > + PAGE_SIZE); > + > + if (st->dma_st.dma_chan) > + return; > + > + st->dma_st.dma_chan = dma_request_slave_channel(&pdev->dev, "rx"); > + > + if (!st->dma_st.dma_chan) { > + dev_info(&pdev->dev, "can't get DMA channel\n"); > + goto dma_exit; > + } > + > + st->dma_st.rx_buf = dma_alloc_coherent(st->dma_st.dma_chan->device->dev, > + pages * PAGE_SIZE, > + &st->dma_st.rx_dma_buf, > + GFP_KERNEL); > + if (!st->dma_st.rx_buf) { > + dev_info(&pdev->dev, "can't allocate coherent DMA area\n"); > + goto dma_chan_disable; > + } > + > + /* Configure DMA channel to read data register */ > + config.direction = DMA_DEV_TO_MEM; > + config.src_addr = (phys_addr_t)(st->dma_st.phys_addr > + + AT91_SAMA5D2_LCDR); > + config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; > + config.src_maxburst = 1; > + config.dst_maxburst = 1; > + > + if (dmaengine_slave_config(st->dma_st.dma_chan, &config)) { > + dev_info(&pdev->dev, "can't configure DMA slave\n"); > + goto dma_free_area; > + } > + > + dev_info(&pdev->dev, "using %s for rx DMA transfers\n", > + dma_chan_name(st->dma_st.dma_chan)); > + > + return; > + > +dma_free_area: > + dma_free_coherent(st->dma_st.dma_chan->device->dev, pages * PAGE_SIZE, > + st->dma_st.rx_buf, st->dma_st.rx_dma_buf); > +dma_chan_disable: > + dma_release_channel(st->dma_st.dma_chan); > + st->dma_st.dma_chan = 0; > +dma_exit: > + dev_info(&pdev->dev, "continuing without DMA support\n"); > +} > + > +static void at91_adc_dma_disable(struct platform_device *pdev) > +{ > + struct iio_dev *indio_dev = platform_get_drvdata(pdev); > + struct at91_adc_state *st = iio_priv(indio_dev); > + unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE * > + AT91_BUFFER_MAX_CONVERSION_BYTES * 2, > + PAGE_SIZE); > + > + /* if we are not using DMA, just return */ > + if (!st->dma_st.dma_chan) > + return; > + > + /* wait for all transactions to be terminated first*/ > + dmaengine_terminate_sync(st->dma_st.dma_chan); > + > + dma_free_coherent(st->dma_st.dma_chan->device->dev, pages * PAGE_SIZE, > + st->dma_st.rx_buf, st->dma_st.rx_dma_buf); > + dma_release_channel(st->dma_st.dma_chan); > + st->dma_st.dma_chan = 0; > + > + dev_info(&pdev->dev, "continuing without DMA support\n"); > +} > + > +static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) > +{ > + struct at91_adc_state *st = iio_priv(indio_dev); > + > + if (val > AT91_HWFIFO_MAX_SIZE) > + return -EINVAL; > + > + if (!st->selected_trig->hw_trig) { > + dev_dbg(&indio_dev->dev, "we need hw trigger for DMA\n"); > + return 0; > + } > + > + dev_dbg(&indio_dev->dev, "new watermark is %u\n", val); > + st->dma_st.watermark = val; > + > + /* > + * The logic here is: if we have watermark 1, it means we do > + * each conversion with it's own IRQ, thus we don't need DMA. > + * If the watermark is higher, we do DMA to do all the transfers in bulk > + */ > + > + if (val == 1) > + at91_adc_dma_disable(to_platform_device(&indio_dev->dev)); > + else if (val > 1) > + at91_adc_dma_init(to_platform_device(&indio_dev->dev)); > + > + return 0; > +} > + > static const struct iio_info at91_adc_info = { > .read_raw = &at91_adc_read_raw, > .write_raw = &at91_adc_write_raw, > + .hwfifo_set_watermark = &at91_adc_set_watermark, > .driver_module = THIS_MODULE, > }; > > @@ -601,6 +960,42 @@ static void at91_adc_hw_init(struct at91_adc_state *st) > at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); > } > > +static ssize_t at91_adc_get_fifo_state(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct iio_dev *indio_dev = > + platform_get_drvdata(to_platform_device(dev)); > + struct at91_adc_state *st = iio_priv(indio_dev); > + > + return scnprintf(buf, PAGE_SIZE, "%d\n", !!st->dma_st.dma_chan); > +} > + > +static ssize_t at91_adc_get_watermark(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct iio_dev *indio_dev = > + platform_get_drvdata(to_platform_device(dev)); > + struct at91_adc_state *st = iio_priv(indio_dev); > + > + return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark); > +} > + > +static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, > + at91_adc_get_fifo_state, NULL, 0); > +static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, > + at91_adc_get_watermark, NULL, 0); > + > +static IIO_CONST_ATTR(hwfifo_watermark_min, "2"); > +static IIO_CONST_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR); > + > +static const struct attribute *at91_adc_fifo_attributes[] = { > + &iio_const_attr_hwfifo_watermark_min.dev_attr.attr, > + &iio_const_attr_hwfifo_watermark_max.dev_attr.attr, > + &iio_dev_attr_hwfifo_watermark.dev_attr.attr, > + &iio_dev_attr_hwfifo_enabled.dev_attr.attr, > + NULL, > +}; > + > static int at91_adc_probe(struct platform_device *pdev) > { > struct iio_dev *indio_dev; > @@ -676,6 +1071,9 @@ static int at91_adc_probe(struct platform_device *pdev) > if (!res) > return -EINVAL; > > + /* if we plan to use DMA, we need the physical address of the regs */ > + st->dma_st.phys_addr = res->start; > + > st->base = devm_ioremap_resource(&pdev->dev, res); > if (IS_ERR(st->base)) > return PTR_ERR(st->base); > @@ -739,11 +1137,22 @@ static int at91_adc_probe(struct platform_device *pdev) > dev_err(&pdev->dev, "couldn't setup the triggers.\n"); > goto per_clk_disable_unprepare; > } > + /* > + * Initially the iio buffer has a length of 2 and > + * a watermark of 1 > + */ > + st->dma_st.watermark = 1; > + > + iio_buffer_set_attrs(indio_dev->buffer, > + at91_adc_fifo_attributes); > } > > + if (dma_coerce_mask_and_coherent(&indio_dev->dev, DMA_BIT_MASK(32))) > + dev_info(&pdev->dev, "cannot set DMA mask to 32-bit\n"); > + > ret = iio_device_register(indio_dev); > if (ret < 0) > - goto per_clk_disable_unprepare; > + goto dma_disable; > > if (st->selected_trig->hw_trig) > dev_info(&pdev->dev, "setting up trigger as %s\n", > @@ -754,6 +1163,8 @@ static int at91_adc_probe(struct platform_device *pdev) > > return 0; > > +dma_disable: > + at91_adc_dma_disable(pdev); > per_clk_disable_unprepare: > clk_disable_unprepare(st->per_clk); > vref_disable: > @@ -770,6 +1181,8 @@ static int at91_adc_remove(struct platform_device *pdev) > > iio_device_unregister(indio_dev); > > + at91_adc_dma_disable(pdev); > + > clk_disable_unprepare(st->per_clk); > > regulator_disable(st->vref); -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html