in adc/stm32-adc.c [2203:2331]
static int stm32_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct device *dev = &pdev->dev;
irqreturn_t (*handler)(int irq, void *p) = NULL;
struct stm32_adc *adc;
bool timestamping = false;
int ret;
if (!pdev->dev.of_node)
return -ENODEV;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
adc = iio_priv(indio_dev);
adc->common = dev_get_drvdata(pdev->dev.parent);
spin_lock_init(&adc->lock);
init_completion(&adc->completion);
adc->cfg = (const struct stm32_adc_cfg *)
of_match_device(dev->driver->of_match_table, dev)->data;
indio_dev->name = dev_name(&pdev->dev);
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->info = &stm32_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED;
platform_set_drvdata(pdev, indio_dev);
ret = of_property_read_u32(pdev->dev.of_node, "reg", &adc->offset);
if (ret != 0) {
dev_err(&pdev->dev, "missing reg property\n");
return -EINVAL;
}
adc->irq = platform_get_irq(pdev, 0);
if (adc->irq < 0)
return adc->irq;
ret = devm_request_threaded_irq(&pdev->dev, adc->irq, stm32_adc_isr,
stm32_adc_threaded_isr,
0, pdev->name, indio_dev);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ\n");
return ret;
}
adc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(adc->clk)) {
ret = PTR_ERR(adc->clk);
if (ret == -ENOENT && !adc->cfg->clk_required) {
adc->clk = NULL;
} else {
dev_err(&pdev->dev, "Can't get clock\n");
return ret;
}
}
ret = stm32_adc_of_get_resolution(indio_dev);
if (ret < 0)
return ret;
ret = stm32_adc_dma_request(dev, indio_dev);
if (ret < 0)
return ret;
if (!adc->dma_chan) {
/* For PIO mode only, iio_pollfunc_store_time stores a timestamp
* in the primary trigger IRQ handler and stm32_adc_trigger_handler
* runs in the IRQ thread to push out buffer along with timestamp.
*/
handler = &stm32_adc_trigger_handler;
timestamping = true;
}
ret = stm32_adc_chan_of_init(indio_dev, timestamping);
if (ret < 0)
goto err_dma_disable;
ret = iio_triggered_buffer_setup(indio_dev,
&iio_pollfunc_store_time, handler,
&stm32_adc_buffer_setup_ops);
if (ret) {
dev_err(&pdev->dev, "buffer setup failed\n");
goto err_dma_disable;
}
/* Get stm32-adc-core PM online */
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
pm_runtime_set_autosuspend_delay(dev, STM32_ADC_HW_STOP_DELAY_MS);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
ret = stm32_adc_hw_start(dev);
if (ret)
goto err_buffer_cleanup;
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "iio dev register failed\n");
goto err_hw_stop;
}
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return 0;
err_hw_stop:
stm32_adc_hw_stop(dev);
err_buffer_cleanup:
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
iio_triggered_buffer_cleanup(indio_dev);
err_dma_disable:
if (adc->dma_chan) {
dma_free_coherent(adc->dma_chan->device->dev,
STM32_DMA_BUFFER_SIZE,
adc->rx_buf, adc->rx_dma_buf);
dma_release_channel(adc->dma_chan);
}
return ret;
}