Commit 69ee4dd5 authored by Antoine Ténart's avatar Antoine Ténart Committed by Herbert Xu

crypto: inside-secure - use threaded IRQs for result handling

This patch moves the result handling from an IRQ handler to a threaded
IRQ handler, to improve the number of complete requests being handled at
once.
Suggested-by: default avatarOfer Heifetz <oferh@marvell.com>
Signed-off-by: default avatarAntoine Tenart <antoine.tenart@free-electrons.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8472e778
...@@ -618,15 +618,6 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv ...@@ -618,15 +618,6 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
} }
} }
static void safexcel_handle_result_work(struct work_struct *work)
{
struct safexcel_work_data *data =
container_of(work, struct safexcel_work_data, result_work);
struct safexcel_crypto_priv *priv = data->priv;
safexcel_handle_result_descriptor(priv, data->ring);
}
static void safexcel_dequeue_work(struct work_struct *work) static void safexcel_dequeue_work(struct work_struct *work)
{ {
struct safexcel_work_data *data = struct safexcel_work_data *data =
...@@ -644,12 +635,12 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data) ...@@ -644,12 +635,12 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
{ {
struct safexcel_ring_irq_data *irq_data = data; struct safexcel_ring_irq_data *irq_data = data;
struct safexcel_crypto_priv *priv = irq_data->priv; struct safexcel_crypto_priv *priv = irq_data->priv;
int ring = irq_data->ring; int ring = irq_data->ring, rc = IRQ_NONE;
u32 status, stat; u32 status, stat;
status = readl(priv->base + EIP197_HIA_AIC_R_ENABLED_STAT(ring)); status = readl(priv->base + EIP197_HIA_AIC_R_ENABLED_STAT(ring));
if (!status) if (!status)
return IRQ_NONE; return rc;
/* RDR interrupts */ /* RDR interrupts */
if (status & EIP197_RDR_IRQ(ring)) { if (status & EIP197_RDR_IRQ(ring)) {
...@@ -663,10 +654,7 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data) ...@@ -663,10 +654,7 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
*/ */
dev_err(priv->dev, "RDR: fatal error."); dev_err(priv->dev, "RDR: fatal error.");
} else if (likely(stat & EIP197_xDR_THRESH)) { } else if (likely(stat & EIP197_xDR_THRESH)) {
queue_work(priv->ring[ring].workqueue, rc = IRQ_WAKE_THREAD;
&priv->ring[ring].work_data.result_work);
queue_work(priv->ring[ring].workqueue,
&priv->ring[ring].work_data.work);
} }
/* ACK the interrupts */ /* ACK the interrupts */
...@@ -677,11 +665,26 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data) ...@@ -677,11 +665,26 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
/* ACK the interrupts */ /* ACK the interrupts */
writel(status, priv->base + EIP197_HIA_AIC_R_ACK(ring)); writel(status, priv->base + EIP197_HIA_AIC_R_ACK(ring));
return rc;
}
static irqreturn_t safexcel_irq_ring_thread(int irq, void *data)
{
struct safexcel_ring_irq_data *irq_data = data;
struct safexcel_crypto_priv *priv = irq_data->priv;
int ring = irq_data->ring;
safexcel_handle_result_descriptor(priv, ring);
queue_work(priv->ring[ring].workqueue,
&priv->ring[ring].work_data.work);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int safexcel_request_ring_irq(struct platform_device *pdev, const char *name, static int safexcel_request_ring_irq(struct platform_device *pdev, const char *name,
irq_handler_t handler, irq_handler_t handler,
irq_handler_t threaded_handler,
struct safexcel_ring_irq_data *ring_irq_priv) struct safexcel_ring_irq_data *ring_irq_priv)
{ {
int ret, irq = platform_get_irq_byname(pdev, name); int ret, irq = platform_get_irq_byname(pdev, name);
...@@ -691,8 +694,9 @@ static int safexcel_request_ring_irq(struct platform_device *pdev, const char *n ...@@ -691,8 +694,9 @@ static int safexcel_request_ring_irq(struct platform_device *pdev, const char *n
return irq; return irq;
} }
ret = devm_request_irq(&pdev->dev, irq, handler, 0, ret = devm_request_threaded_irq(&pdev->dev, irq, handler,
dev_name(&pdev->dev), ring_irq_priv); threaded_handler, IRQF_ONESHOT,
dev_name(&pdev->dev), ring_irq_priv);
if (ret) { if (ret) {
dev_err(&pdev->dev, "unable to request IRQ %d\n", irq); dev_err(&pdev->dev, "unable to request IRQ %d\n", irq);
return ret; return ret;
...@@ -839,6 +843,7 @@ static int safexcel_probe(struct platform_device *pdev) ...@@ -839,6 +843,7 @@ static int safexcel_probe(struct platform_device *pdev)
snprintf(irq_name, 6, "ring%d", i); snprintf(irq_name, 6, "ring%d", i);
irq = safexcel_request_ring_irq(pdev, irq_name, safexcel_irq_ring, irq = safexcel_request_ring_irq(pdev, irq_name, safexcel_irq_ring,
safexcel_irq_ring_thread,
ring_irq); ring_irq);
if (irq < 0) { if (irq < 0) {
ret = irq; ret = irq;
...@@ -847,8 +852,6 @@ static int safexcel_probe(struct platform_device *pdev) ...@@ -847,8 +852,6 @@ static int safexcel_probe(struct platform_device *pdev)
priv->ring[i].work_data.priv = priv; priv->ring[i].work_data.priv = priv;
priv->ring[i].work_data.ring = i; priv->ring[i].work_data.ring = i;
INIT_WORK(&priv->ring[i].work_data.result_work,
safexcel_handle_result_work);
INIT_WORK(&priv->ring[i].work_data.work, safexcel_dequeue_work); INIT_WORK(&priv->ring[i].work_data.work, safexcel_dequeue_work);
snprintf(wq_name, 9, "wq_ring%d", i); snprintf(wq_name, 9, "wq_ring%d", i);
......
...@@ -459,7 +459,6 @@ struct safexcel_config { ...@@ -459,7 +459,6 @@ struct safexcel_config {
struct safexcel_work_data { struct safexcel_work_data {
struct work_struct work; struct work_struct work;
struct work_struct result_work;
struct safexcel_crypto_priv *priv; struct safexcel_crypto_priv *priv;
int ring; int ring;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment