On Tue, Dec 23, 2008 at 03:55:36PM +0100, Guennadi Liakhovetski wrote:
You're still not getting it. Consider an implementation of the chained
interrupt handler like this:
static struct ipu_irq_bank irq_bank_fn[IPU_IRQ_NR_FN_BANKS] = {
{
.nr_irqs = 1, /* IDMAC EOF and NF irq */
}, {
.nr_irqs = 24, /* misc interrupts the IPU is not
* interested in, but clients drivers
* may be.
*/
},
};
static struct ipu_irq_bank irq_bank_err[IPU_IRQ_NR_ERR_BANKS] = {
/* 2 groups of error interrupts */
{
.nr_irqs = 1, /* IDMAC channel error irq */
}, {
.nr_irqs = 17, /* misc interrupts the IPU is not
* interested in, but clients drivers
* may be.
*/
},
};
/* Chained IRQ handler for IPU error interrupt */
static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
{
struct ipu *ipu = get_irq_data(irq);
u32 status;
int i, line;
/* These interrupts are handled exclusively by the IPU code */
if (ipu_read_reg(ipu, IPU_INT_STAT_4))
generic_handle_irq(IPU_IRQ);
status = ipu_read_reg(ipu, IPU_INT_STAT_5);
while ((line = ffs(status))) {
status &= ~(1UL << (line - 1));
generic_handle_irq(irq_bank_err[i].irq_base + line - 1);
}
}
/* Chained IRQ handler for IPU function interrupt */
static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
{
struct ipu *ipu = get_irq_data(irq);
u32 status;
int i, line;
/* These interrupts are handled exclusively by the IPU code */
if (ipu_read_reg(ipu, IPU_INT_STAT_1) || ipu_read_reg(ipu, IPU_INT_STAT_2))
generic_handle_irq(IPU_ERR_IRQ);
status = ipu_read_reg(ipu, IPU_INT_STAT_3);
while ((line = ffs(status))) {
status &= ~(1UL << (line - 1));
generic_handle_irq(irq_bank_err[i].irq_base + line - 1);
}
}
and in ipu_idmac.c:
request_irq(IPU_ERR_IRQ, &ipu_err_handler);
request_irq(IPU_IRQ, &ipu_irq);
That said I'm not sure whether we need a chained interrupt handler at all.
Looking at the remaining interrupts it seems that for example the
CSI_EOF (IPU_INT_STAT3 bit 5) interrupt is redundant to the corresponding
channels interrupt. In the camera driver you already realized that it's
the dma end event you're interested in, not the CSI_EOF event. Not sure
if that holds for the other interrupts though.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
--