On Thu, 21 Oct 2021 14:59:50 +0200 Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: > In some setups the IRQ signal of the XADC might not be wired to the host > system. The driver currently requires that an interrupt is specified. Make > the interrupt optional so the driver can be used in such setups where the > interrupt is not connected. > > Since both the internal triggers as well as events depend on the interrupt > being connected both are not available when the interrupt is not connected. > > Buffered access is still supported even without an interrupt since an > external trigger can be used. > > The IRQ is only optional when using the AXI interface, since the PCAP > interface needs the IRQ for reading and writing registers. > > Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx> Applied to the togreg branch of iio.git and pushed out as testing. Thanks, Jonathan > --- > drivers/iio/adc/xilinx-xadc-core.c | 62 +++++++++++++++++++----------- > 1 file changed, 40 insertions(+), 22 deletions(-) > > diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c > index 83bea5ef765d..2aa4278ecba7 100644 > --- a/drivers/iio/adc/xilinx-xadc-core.c > +++ b/drivers/iio/adc/xilinx-xadc-core.c > @@ -107,6 +107,7 @@ static const unsigned int XADC_ZYNQ_UNMASK_TIMEOUT = 500; > #define XADC_AXI_INT_ALARM_MASK 0x3c0f > > #define XADC_FLAGS_BUFFERED BIT(0) > +#define XADC_FLAGS_IRQ_OPTIONAL BIT(1) > > /* > * The XADC hardware supports a samplerate of up to 1MSPS. Unfortunately it does > @@ -562,7 +563,7 @@ static const struct xadc_ops xadc_7s_axi_ops = { > .get_dclk_rate = xadc_axi_get_dclk, > .update_alarm = xadc_axi_update_alarm, > .interrupt_handler = xadc_axi_interrupt_handler, > - .flags = XADC_FLAGS_BUFFERED, > + .flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL, > .type = XADC_TYPE_S7, > }; > > @@ -573,7 +574,7 @@ static const struct xadc_ops xadc_us_axi_ops = { > .get_dclk_rate = xadc_axi_get_dclk, > .update_alarm = xadc_axi_update_alarm, > .interrupt_handler = xadc_axi_interrupt_handler, > - .flags = XADC_FLAGS_BUFFERED, > + .flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL, > .type = XADC_TYPE_US, > }; > > @@ -1182,7 +1183,7 @@ static const struct of_device_id xadc_of_match_table[] = { > MODULE_DEVICE_TABLE(of, xadc_of_match_table); > > static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np, > - unsigned int *conf) > + unsigned int *conf, int irq) > { > struct device *dev = indio_dev->dev.parent; > struct xadc *xadc = iio_priv(indio_dev); > @@ -1195,6 +1196,7 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np, > u32 ext_mux_chan; > u32 reg; > int ret; > + int i; > > *conf = 0; > > @@ -1273,6 +1275,14 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np, > } > of_node_put(chan_node); > > + /* No IRQ => no events */ > + if (irq <= 0) { > + for (i = 0; i < num_channels; i++) { > + channels[i].event_spec = NULL; > + channels[i].num_event_specs = 0; > + } > + } > + > indio_dev->num_channels = num_channels; > indio_dev->channels = devm_krealloc(dev, channels, > sizeof(*channels) * num_channels, > @@ -1307,6 +1317,7 @@ static int xadc_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > const struct of_device_id *id; > + const struct xadc_ops *ops; > struct iio_dev *indio_dev; > unsigned int bipolar_mask; > unsigned int conf0; > @@ -1322,9 +1333,12 @@ static int xadc_probe(struct platform_device *pdev) > if (!id) > return -EINVAL; > > - irq = platform_get_irq(pdev, 0); > - if (irq <= 0) > - return -ENXIO; > + ops = id->data; > + > + irq = platform_get_irq_optional(pdev, 0); > + if (irq < 0 && > + (irq != -ENXIO || !(ops->flags & XADC_FLAGS_IRQ_OPTIONAL))) > + return irq; > > indio_dev = devm_iio_device_alloc(dev, sizeof(*xadc)); > if (!indio_dev) > @@ -1345,7 +1359,7 @@ static int xadc_probe(struct platform_device *pdev) > indio_dev->modes = INDIO_DIRECT_MODE; > indio_dev->info = &xadc_info; > > - ret = xadc_parse_dt(indio_dev, dev->of_node, &conf0); > + ret = xadc_parse_dt(indio_dev, dev->of_node, &conf0, irq); > if (ret) > return ret; > > @@ -1357,14 +1371,16 @@ static int xadc_probe(struct platform_device *pdev) > if (ret) > return ret; > > - xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst"); > - if (IS_ERR(xadc->convst_trigger)) > - return PTR_ERR(xadc->convst_trigger); > + if (irq > 0) { > + xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst"); > + if (IS_ERR(xadc->convst_trigger)) > + return PTR_ERR(xadc->convst_trigger); > > - xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev, > - "samplerate"); > - if (IS_ERR(xadc->samplerate_trigger)) > - return PTR_ERR(xadc->samplerate_trigger); > + xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev, > + "samplerate"); > + if (IS_ERR(xadc->samplerate_trigger)) > + return PTR_ERR(xadc->samplerate_trigger); > + } > } > > xadc->clk = devm_clk_get(dev, NULL); > @@ -1396,15 +1412,17 @@ static int xadc_probe(struct platform_device *pdev) > } > } > > - ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler, 0, > - dev_name(dev), indio_dev); > - if (ret) > - return ret; > + if (irq > 0) { > + ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler, > + 0, dev_name(dev), indio_dev); > + if (ret) > + return ret; > > - ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work, > - &xadc->zynq_unmask_work); > - if (ret) > - return ret; > + ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work, > + &xadc->zynq_unmask_work); > + if (ret) > + return ret; > + } > > ret = xadc->ops->setup(pdev, indio_dev, irq); > if (ret)