static irqreturn_t pxa3xx_gcu_handle_irq(int irq, void *ctx) { struct pxa3xx_gcu_priv *priv = ctx; struct pxa3xx_gcu_shared *shared = priv->shared; u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL; QDUMP("-Interrupt"); if (!status) return IRQ_NONE; spin_lock(&priv->spinlock); shared->num_interrupts++; if (status & IE_EEOB) { QDUMP(" [EEOB]"); flush_running(priv); wake_up_all(&priv->wait_free); if (priv->ready) { run_ready(priv); } else { /* There is no more data prepared by the userspace. * Set hw_running = 0 and wait for the next userspace * kick-off */ shared->num_idle++; shared->hw_running = 0; QDUMP(" '-> Idle."); /* set ring buffer length to zero */ gc_writel(priv, REG_GCRBLR, 0); wake_up_all(&priv->wait_idle); } shared->num_done++; } else { QERROR(" [???]"); dump_whole_state(priv); } /* Clear the interrupt */ gc_writel(priv, REG_GCISCR, status); spin_unlock(&priv->spinlock); return IRQ_HANDLED; }
void step_scripts( polclock_t* clocksleft, bool* pactivity ) { // cerr << "r"; THREAD_CHECKPOINT( scripts, 102 ); *pactivity = (!runlist.empty()); THREAD_CHECKPOINT( scripts, 103 ); run_ready(); // cerr << "h"; THREAD_CHECKPOINT( scripts, 104 ); check_blocked( clocksleft ); THREAD_CHECKPOINT( scripts, 105 ); if (!runlist.empty()) *clocksleft = 0; THREAD_CHECKPOINT( scripts, 106 ); }
static ssize_t pxa3xx_gcu_misc_write(struct file *filp, const char *buff, size_t count, loff_t *offp) { int ret; unsigned long flags; struct pxa3xx_gcu_batch *buffer; struct pxa3xx_gcu_priv *priv = container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); int words = count / 4; /* Does not need to be atomic. There's a lock in user space, * but anyhow, this is just for statistics. */ priv->shared->num_writes++; priv->shared->num_words += words; /* Last word reserved for batch buffer end command */ if (words >= PXA3XX_GCU_BATCH_WORDS) return -E2BIG; /* Wait for a free buffer */ if (!priv->free) { ret = pxa3xx_gcu_wait_free(priv); if (ret < 0) return ret; } /* * Get buffer from free list */ spin_lock_irqsave(&priv->spinlock, flags); buffer = priv->free; priv->free = buffer->next; spin_unlock_irqrestore(&priv->spinlock, flags); /* Copy data from user into buffer */ ret = copy_from_user(buffer->ptr, buff, words * 4); if (ret) { spin_lock_irqsave(&priv->spinlock, flags); buffer->next = priv->free; priv->free = buffer; spin_unlock_irqrestore(&priv->spinlock, flags); return -EFAULT; } buffer->length = words; /* Append batch buffer end command */ buffer->ptr[words] = 0x01000000; /* * Add buffer to ready list */ spin_lock_irqsave(&priv->spinlock, flags); buffer->next = NULL; if (priv->ready) { BUG_ON(priv->ready_last == NULL); priv->ready_last->next = buffer; } else priv->ready = buffer; priv->ready_last = buffer; if (!priv->shared->hw_running) run_ready(priv); spin_unlock_irqrestore(&priv->spinlock, flags); return words * 4; }