int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
{ int i; unsignedlong flags; int ret = -EINVAL; struct omap_dispc_isr_data *isr_data;
spin_lock_irqsave(&dispc_compat.irq_lock, flags);
for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
isr_data = &dispc_compat.registered_isr[i]; if (isr_data->isr != isr || isr_data->arg != arg ||
isr_data->mask != mask) continue;
/* Called from dss.c. Note that we don't touch clocks here, * but we presume they are on because we got an IRQ. However, * an irq handler may turn the clocks off, so we may not have
* clock later in the function. */ static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
{ int i;
u32 irqstatus, irqenable;
u32 handledirqs = 0;
u32 unhandled_errors; struct omap_dispc_isr_data *isr_data; struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
/* Ack the interrupt. Do it here before clocks are possibly turned
* off */
dispc_clear_irqstatus(irqstatus); /* flush posted write */
dispc_read_irqstatus();
/* make a copy and unlock, so that isrs can unregister
* themselves */
memcpy(registered_isr, dispc_compat.registered_isr, sizeof(registered_isr));
spin_unlock(&dispc_compat.irq_lock);
for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
isr_data = ®istered_isr[i];
/* ignore any sync lost interrupts */ if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
complete(compl);
}
staticvoid dispc_mgr_enable_digit_out(void)
{
DECLARE_COMPLETION_ONSTACK(vsync_compl); int r;
u32 irq_mask;
if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT)) return;
/* * Digit output produces some sync lost interrupts during the first * frame when enabling. Those need to be ignored, so we register for the * sync lost irq to prevent the error handler from triggering.
*/
r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
irq_mask); if (r) {
DSSERR("failed to register %x isr\n", irq_mask); return;
}
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
/* wait for the first evsync */ if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
DSSERR("timeout waiting for digit out to start\n");
r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
irq_mask); if (r)
DSSERR("failed to unregister %x isr\n", irq_mask);
}
staticvoid dispc_mgr_disable_digit_out(void)
{
DECLARE_COMPLETION_ONSTACK(framedone_compl); int r, i;
u32 irq_mask; int num_irqs;
if (!dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT)) return;
/* * When we disable the digit output, we need to wait for FRAMEDONE to * know that DISPC has finished with the output.
*/
if (!irq_mask) { /* * omap 2/3 don't have framedone irq for TV, so we need to use * vsyncs for this.
*/
irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT); /* * We need to wait for both even and odd vsyncs. Note that this * is not totally reliable, as we could get a vsync interrupt * before we disable the output, which leads to timeout in the * wait_for_completion.
*/
num_irqs = 2;
}
r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
irq_mask); if (r)
DSSERR("failed to register %x isr\n", irq_mask);
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
/* if we couldn't register the irq, just sleep and exit */ if (r) {
msleep(100); return;
}
for (i = 0; i < num_irqs; ++i) { if (!wait_for_completion_timeout(&framedone_compl,
msecs_to_jiffies(100)))
DSSERR("timeout waiting for digit out to stop\n");
}
r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
irq_mask); if (r)
DSSERR("failed to unregister %x isr\n", irq_mask);
}
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.