int solo_p2m_init(struct solo6010_dev *solo_dev) { struct solo_p2m_dev *p2m_dev; int i; for (i = 0; i < SOLO_NR_P2M; i++) { p2m_dev = &solo_dev->p2m_dev[i]; sema_init(&p2m_dev->sem, 1); init_completion(&p2m_dev->completion); solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i), __pa(p2m_dev->desc)); solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), SOLO_P2M_CSC_16BIT_565 | SOLO_P2M_DMA_INTERVAL(0) | SOLO_P2M_PCI_MASTER_MODE); solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); } run_p2m_test(solo_dev); return 0; }
void solo_p2m_exit(struct solo6010_dev *solo_dev) { int i; for (i = 0; i < SOLO_NR_P2M; i++) solo6010_irq_off(solo_dev, SOLO_IRQ_P2M(i)); }
/* XXX We should check the return value of the sub-device ISR's */ static irqreturn_t solo_isr(int irq, void *data) { struct solo_dev *solo_dev = data; u32 status; int i; status = solo_reg_read(solo_dev, SOLO_IRQ_STAT); if (!status) return IRQ_NONE; if (status & ~solo_dev->irq_mask) { solo_reg_write(solo_dev, SOLO_IRQ_STAT, status & ~solo_dev->irq_mask); status &= solo_dev->irq_mask; } if (status & SOLO_IRQ_PCI_ERR) { u32 err = solo_reg_read(solo_dev, SOLO_PCI_ERR); solo_p2m_error_isr(solo_dev, err); solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_PCI_ERR); } for (i = 0; i < SOLO_NR_P2M; i++) if (status & SOLO_IRQ_P2M(i)) solo_p2m_isr(solo_dev, i); if (status & SOLO_IRQ_IIC) solo_i2c_isr(solo_dev); if (status & SOLO_IRQ_VIDEO_IN) solo_video_in_isr(solo_dev); /* Call this first so enc gets detected flag set */ if (status & SOLO_IRQ_MOTION) solo_motion_isr(solo_dev); if (status & SOLO_IRQ_ENCODER) solo_enc_v4l2_isr(solo_dev); if (status & SOLO_IRQ_G723) solo_g723_isr(solo_dev); return IRQ_HANDLED; }
static irqreturn_t solo6010_isr(int irq, void *data) { struct solo6010_dev *solo_dev = data; u32 status; int i; status = solo_reg_read(solo_dev, SOLO_IRQ_STAT); if (!status) return IRQ_NONE; if (status & ~solo_dev->irq_mask) { solo_reg_write(solo_dev, SOLO_IRQ_STAT, status & ~solo_dev->irq_mask); status &= solo_dev->irq_mask; } if (status & SOLO_IRQ_PCI_ERR) solo_p2m_error_isr(solo_dev); for (i = 0; i < SOLO_NR_P2M; i++) if (status & SOLO_IRQ_P2M(i)) solo_p2m_isr(solo_dev, i); if (status & SOLO_IRQ_IIC) solo_i2c_isr(solo_dev); if (status & SOLO_IRQ_VIDEO_IN) { solo_video_in_isr(solo_dev); solo_timer_sync(solo_dev); } if (status & SOLO_IRQ_ENCODER) solo_enc_v4l2_isr(solo_dev); if (status & SOLO_IRQ_G723) solo_g723_isr(solo_dev); /* Clear all interrupts handled */ solo_reg_write(solo_dev, SOLO_IRQ_STAT, status); return IRQ_HANDLED; }
void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) { solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id)); complete(&solo_dev->p2m_dev[id].completion); }