/* Backup ARR to restore it after getting the maximum value */
regmap_read(ddata->regmap, TIM_ARR, &arr);
/* * Only the available bits will be written so when readback * we get the maximum value of auto reload register
*/
regmap_write(ddata->regmap, TIM_ARR, ~0L);
regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr);
regmap_write(ddata->regmap, TIM_ARR, arr);
}
/* Optional DMA support: get valid DMA channel(s) or NULL */ for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) {
snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1);
ddata->dma.chans[i] = dma_request_chan(dev, name);
}
ddata->dma.chans[STM32_TIMERS_DMA_UP] = dma_request_chan(dev, "up");
ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = dma_request_chan(dev, "trig");
ddata->dma.chans[STM32_TIMERS_DMA_COM] = dma_request_chan(dev, "com");
for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) { if (IS_ERR(ddata->dma.chans[i])) { /* Save the first error code to return */ if (PTR_ERR(ddata->dma.chans[i]) != -ENODEV && !ret)
ret = PTR_ERR(ddata->dma.chans[i]);
ddata->dma.chans[i] = NULL;
}
}
return ret;
}
staticvoid stm32_timers_dma_remove(struct device *dev, struct stm32_timers *ddata)
{ int i;
for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) if (ddata->dma.chans[i])
dma_release_channel(ddata->dma.chans[i]);
}
staticint stm32_timers_irq_probe(struct platform_device *pdev, struct stm32_timers *ddata)
{ int i, ret;
/* * STM32 Timer may have either: * - a unique global interrupt line * - four dedicated interrupt lines that may be handled separately. * Optionally get them here, to be used by child devices.
*/
ret = platform_get_irq_byname_optional(pdev, "global"); if (ret < 0 && ret != -ENXIO) { return ret;
} elseif (ret != -ENXIO) {
ddata->irq[STM32_TIMERS_IRQ_GLOBAL_BRK] = ret;
ddata->nr_irqs = 1; return 0;
}
for (i = 0; i < STM32_TIMERS_MAX_IRQS; i++) {
ret = platform_get_irq_byname_optional(pdev, stm32_timers_irq_name[i]); if (ret < 0 && ret != -ENXIO) { return ret;
} elseif (ret != -ENXIO) {
ddata->irq[i] = ret;
ddata->nr_irqs++;
}
}
if (ddata->nr_irqs && ddata->nr_irqs != STM32_TIMERS_MAX_IRQS) {
dev_err(&pdev->dev, "Invalid number of IRQs %d\n", ddata->nr_irqs); return -EINVAL;
}
/* * Don't use devm_ here: enfore of_platform_depopulate() happens before * DMA are released, to avoid race on DMA.
*/
of_platform_depopulate(&pdev->dev);
stm32_timers_dma_remove(&pdev->dev, ddata);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.