| .. | .. |
|---|
| 272 | 272 | static void rk_crypto_irq_timer_handle(struct timer_list *t) |
|---|
| 273 | 273 | { |
|---|
| 274 | 274 | struct rk_crypto_dev *rk_dev = from_timer(rk_dev, t, timer); |
|---|
| 275 | + unsigned long flags; |
|---|
| 276 | + |
|---|
| 277 | + spin_lock_irqsave(&rk_dev->lock, flags); |
|---|
| 275 | 278 | |
|---|
| 276 | 279 | rk_dev->err = -ETIMEDOUT; |
|---|
| 277 | 280 | rk_dev->stat.timeout_cnt++; |
|---|
| 281 | + |
|---|
| 282 | + rk_unload_data(rk_dev); |
|---|
| 283 | + |
|---|
| 284 | + spin_unlock_irqrestore(&rk_dev->lock, flags); |
|---|
| 285 | + |
|---|
| 278 | 286 | tasklet_schedule(&rk_dev->done_task); |
|---|
| 279 | 287 | } |
|---|
| 280 | 288 | |
|---|
| .. | .. |
|---|
| 282 | 290 | { |
|---|
| 283 | 291 | struct rk_crypto_dev *rk_dev = platform_get_drvdata(dev_id); |
|---|
| 284 | 292 | struct rk_alg_ctx *alg_ctx; |
|---|
| 293 | + unsigned long flags; |
|---|
| 285 | 294 | |
|---|
| 286 | | - spin_lock(&rk_dev->lock); |
|---|
| 295 | + spin_lock_irqsave(&rk_dev->lock, flags); |
|---|
| 296 | + |
|---|
| 297 | + /* reset timeout timer */ |
|---|
| 298 | + start_irq_timer(rk_dev); |
|---|
| 287 | 299 | |
|---|
| 288 | 300 | alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); |
|---|
| 289 | 301 | |
|---|
| .. | .. |
|---|
| 292 | 304 | if (alg_ctx->ops.irq_handle) |
|---|
| 293 | 305 | alg_ctx->ops.irq_handle(irq, dev_id); |
|---|
| 294 | 306 | |
|---|
| 295 | | - tasklet_schedule(&rk_dev->done_task); |
|---|
| 307 | + /* already trigger timeout */ |
|---|
| 308 | + if (rk_dev->err != -ETIMEDOUT) { |
|---|
| 309 | + spin_unlock_irqrestore(&rk_dev->lock, flags); |
|---|
| 310 | + tasklet_schedule(&rk_dev->done_task); |
|---|
| 311 | + } else { |
|---|
| 312 | + spin_unlock_irqrestore(&rk_dev->lock, flags); |
|---|
| 313 | + } |
|---|
| 296 | 314 | |
|---|
| 297 | | - spin_unlock(&rk_dev->lock); |
|---|
| 298 | 315 | return IRQ_HANDLED; |
|---|
| 299 | 316 | } |
|---|
| 300 | 317 | |
|---|