mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-25 11:55:37 +00:00
mfd: stm32-timers: Add support for interrupts
There are two types of STM32 timers that may have: - a global interrupt line - 4 dedicated interrupt lines. Those interrupts are optional as defined in the dt-bindings. Enforce checks on either one, four or no interrupts are provided with their names. Optionally get them here, to be used by child devices. Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> Link: https://lore.kernel.org/r/20230829134029.2402868-5-fabrice.gasnier@foss.st.com Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
parent
6341632041
commit
1c7ea43fc4
2 changed files with 57 additions and 0 deletions
|
@ -215,6 +215,48 @@ static void stm32_timers_dma_remove(struct device *dev,
|
|||
dma_release_channel(ddata->dma.chans[i]);
|
||||
}
|
||||
|
||||
static const char * const stm32_timers_irq_name[STM32_TIMERS_MAX_IRQS] = {
|
||||
"brk", "up", "trg-com", "cc"
|
||||
};
|
||||
|
||||
static int 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;
|
||||
} else if (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;
|
||||
} else if (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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_timers_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -245,6 +287,10 @@ static int stm32_timers_probe(struct platform_device *pdev)
|
|||
|
||||
stm32_timers_get_arr_size(ddata);
|
||||
|
||||
ret = stm32_timers_irq_probe(pdev, ddata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = stm32_timers_dma_probe(dev, ddata);
|
||||
if (ret) {
|
||||
stm32_timers_dma_remove(dev, ddata);
|
||||
|
|
|
@ -102,6 +102,15 @@ enum stm32_timers_dmas {
|
|||
STM32_TIMERS_MAX_DMAS,
|
||||
};
|
||||
|
||||
/* STM32 Timer may have either a unique global interrupt or 4 interrupt lines */
|
||||
enum stm32_timers_irqs {
|
||||
STM32_TIMERS_IRQ_GLOBAL_BRK, /* global or brk IRQ */
|
||||
STM32_TIMERS_IRQ_UP,
|
||||
STM32_TIMERS_IRQ_TRG_COM,
|
||||
STM32_TIMERS_IRQ_CC,
|
||||
STM32_TIMERS_MAX_IRQS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct stm32_timers_dma - STM32 timer DMA handling.
|
||||
* @completion: end of DMA transfer completion
|
||||
|
@ -123,6 +132,8 @@ struct stm32_timers {
|
|||
struct regmap *regmap;
|
||||
u32 max_arr;
|
||||
struct stm32_timers_dma dma; /* Only to be used by the parent */
|
||||
unsigned int nr_irqs;
|
||||
int irq[STM32_TIMERS_MAX_IRQS];
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MFD_STM32_TIMERS)
|
||||
|
|
Loading…
Reference in a new issue