mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
dmaengine: dw-edma: Add interrupt-emulation hooks
DesignWare eDMA instances support "interrupt emulation", where a
software write can assert the IRQ line without setting the normal
DONE/ABORT status bits.
Introduce core callbacks needed to support this feature:
- .ack_emulated_irq(): core-specific sequence to deassert an emulated
IRQ
- .db_offset(): offset from the DMA register base that is suitable as a
host-writable doorbell target for interrupt emulation
Implement both hooks for the v0 register map. For dw-hdma-v0, provide a
stub .db_offset() returning ~0 until the correct offset is known.
The next patch wires these hooks into the dw-edma IRQ path and exports
the doorbell resources to platform users.
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260215152216.3393561-2-den@valinux.co.jp
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
490c367b5f
commit
2e87268795
|
|
@ -126,6 +126,8 @@ struct dw_edma_core_ops {
|
|||
void (*start)(struct dw_edma_chunk *chunk, bool first);
|
||||
void (*ch_config)(struct dw_edma_chan *chan);
|
||||
void (*debugfs_on)(struct dw_edma *dw);
|
||||
void (*ack_emulated_irq)(struct dw_edma *dw);
|
||||
resource_size_t (*db_offset)(struct dw_edma *dw);
|
||||
};
|
||||
|
||||
struct dw_edma_sg {
|
||||
|
|
@ -206,4 +208,19 @@ void dw_edma_core_debugfs_on(struct dw_edma *dw)
|
|||
dw->core->debugfs_on(dw);
|
||||
}
|
||||
|
||||
static inline int dw_edma_core_ack_emulated_irq(struct dw_edma *dw)
|
||||
{
|
||||
if (!dw->core->ack_emulated_irq)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
dw->core->ack_emulated_irq(dw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline resource_size_t
|
||||
dw_edma_core_db_offset(struct dw_edma *dw)
|
||||
{
|
||||
return dw->core->db_offset(dw);
|
||||
}
|
||||
|
||||
#endif /* _DW_EDMA_CORE_H */
|
||||
|
|
|
|||
|
|
@ -509,6 +509,25 @@ static void dw_edma_v0_core_debugfs_on(struct dw_edma *dw)
|
|||
dw_edma_v0_debugfs_on(dw);
|
||||
}
|
||||
|
||||
static void dw_edma_v0_core_ack_emulated_irq(struct dw_edma *dw)
|
||||
{
|
||||
/*
|
||||
* Interrupt emulation may assert the IRQ without setting
|
||||
* DONE/ABORT status bits. A zero write to INT_CLEAR deasserts the
|
||||
* emulated IRQ, while being a no-op for real interrupts.
|
||||
*/
|
||||
SET_BOTH_32(dw, int_clear, 0);
|
||||
}
|
||||
|
||||
static resource_size_t dw_edma_v0_core_db_offset(struct dw_edma *dw)
|
||||
{
|
||||
/*
|
||||
* rd_int_status is chosen arbitrarily, but wr_int_status would be
|
||||
* equally suitable.
|
||||
*/
|
||||
return offsetof(struct dw_edma_v0_regs, rd_int_status);
|
||||
}
|
||||
|
||||
static const struct dw_edma_core_ops dw_edma_v0_core = {
|
||||
.off = dw_edma_v0_core_off,
|
||||
.ch_count = dw_edma_v0_core_ch_count,
|
||||
|
|
@ -517,6 +536,8 @@ static const struct dw_edma_core_ops dw_edma_v0_core = {
|
|||
.start = dw_edma_v0_core_start,
|
||||
.ch_config = dw_edma_v0_core_ch_config,
|
||||
.debugfs_on = dw_edma_v0_core_debugfs_on,
|
||||
.ack_emulated_irq = dw_edma_v0_core_ack_emulated_irq,
|
||||
.db_offset = dw_edma_v0_core_db_offset,
|
||||
};
|
||||
|
||||
void dw_edma_v0_core_register(struct dw_edma *dw)
|
||||
|
|
|
|||
|
|
@ -283,6 +283,12 @@ static void dw_hdma_v0_core_debugfs_on(struct dw_edma *dw)
|
|||
dw_hdma_v0_debugfs_on(dw);
|
||||
}
|
||||
|
||||
static resource_size_t dw_hdma_v0_core_db_offset(struct dw_edma *dw)
|
||||
{
|
||||
/* Implement once the correct offset is known. */
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static const struct dw_edma_core_ops dw_hdma_v0_core = {
|
||||
.off = dw_hdma_v0_core_off,
|
||||
.ch_count = dw_hdma_v0_core_ch_count,
|
||||
|
|
@ -291,6 +297,7 @@ static const struct dw_edma_core_ops dw_hdma_v0_core = {
|
|||
.start = dw_hdma_v0_core_start,
|
||||
.ch_config = dw_hdma_v0_core_ch_config,
|
||||
.debugfs_on = dw_hdma_v0_core_debugfs_on,
|
||||
.db_offset = dw_hdma_v0_core_db_offset,
|
||||
};
|
||||
|
||||
void dw_hdma_v0_core_register(struct dw_edma *dw)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user