|
@@ -73,6 +73,8 @@ static int caam_jr_shutdown(struct device *dev)
|
|
|
|
|
|
ret = caam_reset_hw_jr(dev);
|
|
|
|
|
|
+ tasklet_kill(&jrp->irqtask);
|
|
|
+
|
|
|
/* Release interrupt */
|
|
|
free_irq(jrp->irq, dev);
|
|
|
|
|
@@ -128,7 +130,7 @@ static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
|
|
|
|
|
|
/*
|
|
|
* Check the output ring for ready responses, kick
|
|
|
- * the threaded irq if jobs done.
|
|
|
+ * tasklet if jobs done.
|
|
|
*/
|
|
|
irqstate = rd_reg32(&jrp->rregs->jrintstatus);
|
|
|
if (!irqstate)
|
|
@@ -150,13 +152,18 @@ static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
|
|
|
/* Have valid interrupt at this point, just ACK and trigger */
|
|
|
wr_reg32(&jrp->rregs->jrintstatus, irqstate);
|
|
|
|
|
|
- return IRQ_WAKE_THREAD;
|
|
|
+ preempt_disable();
|
|
|
+ tasklet_schedule(&jrp->irqtask);
|
|
|
+ preempt_enable();
|
|
|
+
|
|
|
+ return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
-static irqreturn_t caam_jr_threadirq(int irq, void *st_dev)
|
|
|
+/* Deferred service handler, run as interrupt-fired tasklet */
|
|
|
+static void caam_jr_dequeue(unsigned long devarg)
|
|
|
{
|
|
|
int hw_idx, sw_idx, i, head, tail;
|
|
|
- struct device *dev = st_dev;
|
|
|
+ struct device *dev = (struct device *)devarg;
|
|
|
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
|
|
void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg);
|
|
|
u32 *userdesc, userstatus;
|
|
@@ -230,8 +237,6 @@ static irqreturn_t caam_jr_threadirq(int irq, void *st_dev)
|
|
|
|
|
|
/* reenable / unmask IRQs */
|
|
|
clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0);
|
|
|
-
|
|
|
- return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -389,10 +394,11 @@ static int caam_jr_init(struct device *dev)
|
|
|
|
|
|
jrp = dev_get_drvdata(dev);
|
|
|
|
|
|
+ tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev);
|
|
|
+
|
|
|
/* Connect job ring interrupt handler. */
|
|
|
- error = request_threaded_irq(jrp->irq, caam_jr_interrupt,
|
|
|
- caam_jr_threadirq, IRQF_SHARED,
|
|
|
- dev_name(dev), dev);
|
|
|
+ error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
|
|
|
+ dev_name(dev), dev);
|
|
|
if (error) {
|
|
|
dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
|
|
|
jrp->ridx, jrp->irq);
|
|
@@ -454,6 +460,7 @@ out_free_inpring:
|
|
|
out_free_irq:
|
|
|
free_irq(jrp->irq, dev);
|
|
|
out_kill_deq:
|
|
|
+ tasklet_kill(&jrp->irqtask);
|
|
|
return error;
|
|
|
}
|
|
|
|