| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * CAAM/SEC 4.x transport/backend driver |
|---|
| 3 | 4 | * JobR backend functionality |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Copyright 2008-2012 Freescale Semiconductor, Inc. |
|---|
| 7 | + * Copyright 2019 NXP |
|---|
| 6 | 8 | */ |
|---|
| 7 | 9 | |
|---|
| 8 | 10 | #include <linux/of_irq.h> |
|---|
| .. | .. |
|---|
| 22 | 24 | } ____cacheline_aligned; |
|---|
| 23 | 25 | |
|---|
| 24 | 26 | static struct jr_driver_data driver_data; |
|---|
| 27 | +static DEFINE_MUTEX(algs_lock); |
|---|
| 28 | +static unsigned int active_devs; |
|---|
| 29 | + |
|---|
| 30 | +static void register_algs(struct caam_drv_private_jr *jrpriv, |
|---|
| 31 | + struct device *dev) |
|---|
| 32 | +{ |
|---|
| 33 | + mutex_lock(&algs_lock); |
|---|
| 34 | + |
|---|
| 35 | + if (++active_devs != 1) |
|---|
| 36 | + goto algs_unlock; |
|---|
| 37 | + |
|---|
| 38 | + caam_algapi_init(dev); |
|---|
| 39 | + caam_algapi_hash_init(dev); |
|---|
| 40 | + caam_pkc_init(dev); |
|---|
| 41 | + jrpriv->hwrng = !caam_rng_init(dev); |
|---|
| 42 | + caam_qi_algapi_init(dev); |
|---|
| 43 | + |
|---|
| 44 | +algs_unlock: |
|---|
| 45 | + mutex_unlock(&algs_lock); |
|---|
| 46 | +} |
|---|
| 47 | + |
|---|
| 48 | +static void unregister_algs(void) |
|---|
| 49 | +{ |
|---|
| 50 | + mutex_lock(&algs_lock); |
|---|
| 51 | + |
|---|
| 52 | + if (--active_devs != 0) |
|---|
| 53 | + goto algs_unlock; |
|---|
| 54 | + |
|---|
| 55 | + caam_qi_algapi_exit(); |
|---|
| 56 | + |
|---|
| 57 | + caam_pkc_exit(); |
|---|
| 58 | + caam_algapi_hash_exit(); |
|---|
| 59 | + caam_algapi_exit(); |
|---|
| 60 | + |
|---|
| 61 | +algs_unlock: |
|---|
| 62 | + mutex_unlock(&algs_lock); |
|---|
| 63 | +} |
|---|
| 64 | + |
|---|
| 65 | +static void caam_jr_crypto_engine_exit(void *data) |
|---|
| 66 | +{ |
|---|
| 67 | + struct device *jrdev = data; |
|---|
| 68 | + struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev); |
|---|
| 69 | + |
|---|
| 70 | + /* Free the resources of crypto-engine */ |
|---|
| 71 | + crypto_engine_exit(jrpriv->engine); |
|---|
| 72 | +} |
|---|
| 25 | 73 | |
|---|
| 26 | 74 | static int caam_reset_hw_jr(struct device *dev) |
|---|
| 27 | 75 | { |
|---|
| .. | .. |
|---|
| 69 | 117 | static int caam_jr_shutdown(struct device *dev) |
|---|
| 70 | 118 | { |
|---|
| 71 | 119 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); |
|---|
| 72 | | - dma_addr_t inpbusaddr, outbusaddr; |
|---|
| 73 | 120 | int ret; |
|---|
| 74 | 121 | |
|---|
| 75 | 122 | ret = caam_reset_hw_jr(dev); |
|---|
| 76 | 123 | |
|---|
| 77 | 124 | tasklet_kill(&jrp->irqtask); |
|---|
| 78 | | - |
|---|
| 79 | | - /* Release interrupt */ |
|---|
| 80 | | - free_irq(jrp->irq, dev); |
|---|
| 81 | | - |
|---|
| 82 | | - /* Free rings */ |
|---|
| 83 | | - inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); |
|---|
| 84 | | - outbusaddr = rd_reg64(&jrp->rregs->outring_base); |
|---|
| 85 | | - dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH, |
|---|
| 86 | | - jrp->inpring, inpbusaddr); |
|---|
| 87 | | - dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, |
|---|
| 88 | | - jrp->outring, outbusaddr); |
|---|
| 89 | | - kfree(jrp->entinfo); |
|---|
| 90 | 125 | |
|---|
| 91 | 126 | return ret; |
|---|
| 92 | 127 | } |
|---|
| .. | .. |
|---|
| 100 | 135 | jrdev = &pdev->dev; |
|---|
| 101 | 136 | jrpriv = dev_get_drvdata(jrdev); |
|---|
| 102 | 137 | |
|---|
| 138 | + if (jrpriv->hwrng) |
|---|
| 139 | + caam_rng_exit(jrdev->parent); |
|---|
| 140 | + |
|---|
| 103 | 141 | /* |
|---|
| 104 | 142 | * Return EBUSY if job ring already allocated. |
|---|
| 105 | 143 | */ |
|---|
| .. | .. |
|---|
| 107 | 145 | dev_err(jrdev, "Device is busy\n"); |
|---|
| 108 | 146 | return -EBUSY; |
|---|
| 109 | 147 | } |
|---|
| 148 | + |
|---|
| 149 | + /* Unregister JR-based RNG & crypto algorithms */ |
|---|
| 150 | + unregister_algs(); |
|---|
| 110 | 151 | |
|---|
| 111 | 152 | /* Remove the node from Physical JobR list maintained by driver */ |
|---|
| 112 | 153 | spin_lock(&driver_data.jr_alloc_lock); |
|---|
| .. | .. |
|---|
| 117 | 158 | ret = caam_jr_shutdown(jrdev); |
|---|
| 118 | 159 | if (ret) |
|---|
| 119 | 160 | dev_err(jrdev, "Failed to shut down job ring\n"); |
|---|
| 120 | | - irq_dispose_mapping(jrpriv->irq); |
|---|
| 121 | 161 | |
|---|
| 122 | 162 | return ret; |
|---|
| 123 | 163 | } |
|---|
| .. | .. |
|---|
| 169 | 209 | void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); |
|---|
| 170 | 210 | u32 *userdesc, userstatus; |
|---|
| 171 | 211 | void *userarg; |
|---|
| 212 | + u32 outring_used = 0; |
|---|
| 172 | 213 | |
|---|
| 173 | | - while (rd_reg32(&jrp->rregs->outring_used)) { |
|---|
| 214 | + while (outring_used || |
|---|
| 215 | + (outring_used = rd_reg32(&jrp->rregs->outring_used))) { |
|---|
| 174 | 216 | |
|---|
| 175 | 217 | head = READ_ONCE(jrp->head); |
|---|
| 176 | | - |
|---|
| 177 | | - spin_lock(&jrp->outlock); |
|---|
| 178 | 218 | |
|---|
| 179 | 219 | sw_idx = tail = jrp->tail; |
|---|
| 180 | 220 | hw_idx = jrp->out_ring_read_index; |
|---|
| .. | .. |
|---|
| 182 | 222 | for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { |
|---|
| 183 | 223 | sw_idx = (tail + i) & (JOBR_DEPTH - 1); |
|---|
| 184 | 224 | |
|---|
| 185 | | - if (jrp->outring[hw_idx].desc == |
|---|
| 225 | + if (jr_outentry_desc(jrp->outring, hw_idx) == |
|---|
| 186 | 226 | caam_dma_to_cpu(jrp->entinfo[sw_idx].desc_addr_dma)) |
|---|
| 187 | 227 | break; /* found */ |
|---|
| 188 | 228 | } |
|---|
| .. | .. |
|---|
| 191 | 231 | |
|---|
| 192 | 232 | /* Unmap just-run descriptor so we can post-process */ |
|---|
| 193 | 233 | dma_unmap_single(dev, |
|---|
| 194 | | - caam_dma_to_cpu(jrp->outring[hw_idx].desc), |
|---|
| 234 | + caam_dma_to_cpu(jr_outentry_desc(jrp->outring, |
|---|
| 235 | + hw_idx)), |
|---|
| 195 | 236 | jrp->entinfo[sw_idx].desc_size, |
|---|
| 196 | 237 | DMA_TO_DEVICE); |
|---|
| 197 | 238 | |
|---|
| 198 | 239 | /* mark completed, avoid matching on a recycled desc addr */ |
|---|
| 199 | 240 | jrp->entinfo[sw_idx].desc_addr_dma = 0; |
|---|
| 200 | 241 | |
|---|
| 201 | | - /* Stash callback params for use outside of lock */ |
|---|
| 242 | + /* Stash callback params */ |
|---|
| 202 | 243 | usercall = jrp->entinfo[sw_idx].callbk; |
|---|
| 203 | 244 | userarg = jrp->entinfo[sw_idx].cbkarg; |
|---|
| 204 | 245 | userdesc = jrp->entinfo[sw_idx].desc_addr_virt; |
|---|
| 205 | | - userstatus = caam32_to_cpu(jrp->outring[hw_idx].jrstatus); |
|---|
| 246 | + userstatus = caam32_to_cpu(jr_outentry_jrstatus(jrp->outring, |
|---|
| 247 | + hw_idx)); |
|---|
| 206 | 248 | |
|---|
| 207 | 249 | /* |
|---|
| 208 | 250 | * Make sure all information from the job has been obtained |
|---|
| .. | .. |
|---|
| 231 | 273 | jrp->tail = tail; |
|---|
| 232 | 274 | } |
|---|
| 233 | 275 | |
|---|
| 234 | | - spin_unlock(&jrp->outlock); |
|---|
| 235 | | - |
|---|
| 236 | 276 | /* Finally, execute user's callback */ |
|---|
| 237 | 277 | usercall(dev, userdesc, userstatus, userarg); |
|---|
| 278 | + outring_used--; |
|---|
| 238 | 279 | } |
|---|
| 239 | 280 | |
|---|
| 240 | 281 | /* reenable / unmask IRQs */ |
|---|
| .. | .. |
|---|
| 283 | 324 | |
|---|
| 284 | 325 | /** |
|---|
| 285 | 326 | * caam_jr_free() - Free the Job Ring |
|---|
| 286 | | - * @rdev - points to the dev that identifies the Job ring to |
|---|
| 327 | + * @rdev: points to the dev that identifies the Job ring to |
|---|
| 287 | 328 | * be released. |
|---|
| 288 | 329 | **/ |
|---|
| 289 | 330 | void caam_jr_free(struct device *rdev) |
|---|
| .. | .. |
|---|
| 295 | 336 | EXPORT_SYMBOL(caam_jr_free); |
|---|
| 296 | 337 | |
|---|
| 297 | 338 | /** |
|---|
| 298 | | - * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK, |
|---|
| 299 | | - * -EBUSY if the queue is full, -EIO if it cannot map the caller's |
|---|
| 339 | + * caam_jr_enqueue() - Enqueue a job descriptor head. Returns -EINPROGRESS |
|---|
| 340 | + * if OK, -ENOSPC if the queue is full, -EIO if it cannot map the caller's |
|---|
| 300 | 341 | * descriptor. |
|---|
| 301 | | - * @dev: device of the job ring to be used. This device should have |
|---|
| 302 | | - * been assigned prior by caam_jr_register(). |
|---|
| 342 | + * @dev: struct device of the job ring to be used |
|---|
| 303 | 343 | * @desc: points to a job descriptor that execute our request. All |
|---|
| 304 | 344 | * descriptors (and all referenced data) must be in a DMAable |
|---|
| 305 | 345 | * region, and all data references must be physical addresses |
|---|
| .. | .. |
|---|
| 309 | 349 | * of this request. This has the form: |
|---|
| 310 | 350 | * callback(struct device *dev, u32 *desc, u32 stat, void *arg) |
|---|
| 311 | 351 | * where: |
|---|
| 312 | | - * @dev: contains the job ring device that processed this |
|---|
| 352 | + * dev: contains the job ring device that processed this |
|---|
| 313 | 353 | * response. |
|---|
| 314 | | - * @desc: descriptor that initiated the request, same as |
|---|
| 354 | + * desc: descriptor that initiated the request, same as |
|---|
| 315 | 355 | * "desc" being argued to caam_jr_enqueue(). |
|---|
| 316 | | - * @status: untranslated status received from CAAM. See the |
|---|
| 356 | + * status: untranslated status received from CAAM. See the |
|---|
| 317 | 357 | * reference manual for a detailed description of |
|---|
| 318 | 358 | * error meaning, or see the JRSTA definitions in the |
|---|
| 319 | 359 | * register header file |
|---|
| 320 | | - * @areq: optional pointer to an argument passed with the |
|---|
| 360 | + * areq: optional pointer to an argument passed with the |
|---|
| 321 | 361 | * original request |
|---|
| 322 | 362 | * @areq: optional pointer to a user argument for use at callback |
|---|
| 323 | 363 | * time. |
|---|
| .. | .. |
|---|
| 344 | 384 | head = jrp->head; |
|---|
| 345 | 385 | tail = READ_ONCE(jrp->tail); |
|---|
| 346 | 386 | |
|---|
| 347 | | - if (!rd_reg32(&jrp->rregs->inpring_avail) || |
|---|
| 387 | + if (!jrp->inpring_avail || |
|---|
| 348 | 388 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { |
|---|
| 349 | 389 | spin_unlock_bh(&jrp->inplock); |
|---|
| 350 | 390 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); |
|---|
| 351 | | - return -EBUSY; |
|---|
| 391 | + return -ENOSPC; |
|---|
| 352 | 392 | } |
|---|
| 353 | 393 | |
|---|
| 354 | 394 | head_entry = &jrp->entinfo[head]; |
|---|
| .. | .. |
|---|
| 358 | 398 | head_entry->cbkarg = areq; |
|---|
| 359 | 399 | head_entry->desc_addr_dma = desc_dma; |
|---|
| 360 | 400 | |
|---|
| 361 | | - jrp->inpring[jrp->inp_ring_write_index] = cpu_to_caam_dma(desc_dma); |
|---|
| 401 | + jr_inpentry_set(jrp->inpring, head, cpu_to_caam_dma(desc_dma)); |
|---|
| 362 | 402 | |
|---|
| 363 | 403 | /* |
|---|
| 364 | 404 | * Guarantee that the descriptor's DMA address has been written to |
|---|
| .. | .. |
|---|
| 367 | 407 | */ |
|---|
| 368 | 408 | smp_wmb(); |
|---|
| 369 | 409 | |
|---|
| 370 | | - jrp->inp_ring_write_index = (jrp->inp_ring_write_index + 1) & |
|---|
| 371 | | - (JOBR_DEPTH - 1); |
|---|
| 372 | 410 | jrp->head = (head + 1) & (JOBR_DEPTH - 1); |
|---|
| 373 | 411 | |
|---|
| 374 | 412 | /* |
|---|
| 375 | 413 | * Ensure that all job information has been written before |
|---|
| 376 | | - * notifying CAAM that a new job was added to the input ring. |
|---|
| 414 | + * notifying CAAM that a new job was added to the input ring |
|---|
| 415 | + * using a memory barrier. The wr_reg32() uses api iowrite32() |
|---|
| 416 | + * to do the register write. iowrite32() issues a memory barrier |
|---|
| 417 | + * before the write operation. |
|---|
| 377 | 418 | */ |
|---|
| 378 | | - wmb(); |
|---|
| 379 | 419 | |
|---|
| 380 | 420 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); |
|---|
| 381 | 421 | |
|---|
| 422 | + jrp->inpring_avail--; |
|---|
| 423 | + if (!jrp->inpring_avail) |
|---|
| 424 | + jrp->inpring_avail = rd_reg32(&jrp->rregs->inpring_avail); |
|---|
| 425 | + |
|---|
| 382 | 426 | spin_unlock_bh(&jrp->inplock); |
|---|
| 383 | 427 | |
|---|
| 384 | | - return 0; |
|---|
| 428 | + return -EINPROGRESS; |
|---|
| 385 | 429 | } |
|---|
| 386 | 430 | EXPORT_SYMBOL(caam_jr_enqueue); |
|---|
| 387 | 431 | |
|---|
| .. | .. |
|---|
| 396 | 440 | |
|---|
| 397 | 441 | jrp = dev_get_drvdata(dev); |
|---|
| 398 | 442 | |
|---|
| 399 | | - tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev); |
|---|
| 400 | | - |
|---|
| 401 | | - /* Connect job ring interrupt handler. */ |
|---|
| 402 | | - error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, |
|---|
| 403 | | - dev_name(dev), dev); |
|---|
| 404 | | - if (error) { |
|---|
| 405 | | - dev_err(dev, "can't connect JobR %d interrupt (%d)\n", |
|---|
| 406 | | - jrp->ridx, jrp->irq); |
|---|
| 407 | | - goto out_kill_deq; |
|---|
| 408 | | - } |
|---|
| 409 | | - |
|---|
| 410 | 443 | error = caam_reset_hw_jr(dev); |
|---|
| 411 | 444 | if (error) |
|---|
| 412 | | - goto out_free_irq; |
|---|
| 445 | + return error; |
|---|
| 413 | 446 | |
|---|
| 414 | | - error = -ENOMEM; |
|---|
| 415 | | - jrp->inpring = dma_alloc_coherent(dev, sizeof(*jrp->inpring) * |
|---|
| 416 | | - JOBR_DEPTH, &inpbusaddr, GFP_KERNEL); |
|---|
| 447 | + jrp->inpring = dmam_alloc_coherent(dev, SIZEOF_JR_INPENTRY * |
|---|
| 448 | + JOBR_DEPTH, &inpbusaddr, |
|---|
| 449 | + GFP_KERNEL); |
|---|
| 417 | 450 | if (!jrp->inpring) |
|---|
| 418 | | - goto out_free_irq; |
|---|
| 451 | + return -ENOMEM; |
|---|
| 419 | 452 | |
|---|
| 420 | | - jrp->outring = dma_alloc_coherent(dev, sizeof(*jrp->outring) * |
|---|
| 421 | | - JOBR_DEPTH, &outbusaddr, GFP_KERNEL); |
|---|
| 453 | + jrp->outring = dmam_alloc_coherent(dev, SIZEOF_JR_OUTENTRY * |
|---|
| 454 | + JOBR_DEPTH, &outbusaddr, |
|---|
| 455 | + GFP_KERNEL); |
|---|
| 422 | 456 | if (!jrp->outring) |
|---|
| 423 | | - goto out_free_inpring; |
|---|
| 457 | + return -ENOMEM; |
|---|
| 424 | 458 | |
|---|
| 425 | | - jrp->entinfo = kcalloc(JOBR_DEPTH, sizeof(*jrp->entinfo), GFP_KERNEL); |
|---|
| 459 | + jrp->entinfo = devm_kcalloc(dev, JOBR_DEPTH, sizeof(*jrp->entinfo), |
|---|
| 460 | + GFP_KERNEL); |
|---|
| 426 | 461 | if (!jrp->entinfo) |
|---|
| 427 | | - goto out_free_outring; |
|---|
| 462 | + return -ENOMEM; |
|---|
| 428 | 463 | |
|---|
| 429 | 464 | for (i = 0; i < JOBR_DEPTH; i++) |
|---|
| 430 | 465 | jrp->entinfo[i].desc_addr_dma = !0; |
|---|
| 431 | 466 | |
|---|
| 432 | 467 | /* Setup rings */ |
|---|
| 433 | | - jrp->inp_ring_write_index = 0; |
|---|
| 434 | 468 | jrp->out_ring_read_index = 0; |
|---|
| 435 | 469 | jrp->head = 0; |
|---|
| 436 | 470 | jrp->tail = 0; |
|---|
| .. | .. |
|---|
| 440 | 474 | wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); |
|---|
| 441 | 475 | wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); |
|---|
| 442 | 476 | |
|---|
| 443 | | - jrp->ringsize = JOBR_DEPTH; |
|---|
| 477 | + jrp->inpring_avail = JOBR_DEPTH; |
|---|
| 444 | 478 | |
|---|
| 445 | 479 | spin_lock_init(&jrp->inplock); |
|---|
| 446 | | - spin_lock_init(&jrp->outlock); |
|---|
| 447 | 480 | |
|---|
| 448 | 481 | /* Select interrupt coalescing parameters */ |
|---|
| 449 | 482 | clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | |
|---|
| 450 | 483 | (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | |
|---|
| 451 | 484 | (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); |
|---|
| 452 | 485 | |
|---|
| 453 | | - return 0; |
|---|
| 486 | + tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev); |
|---|
| 454 | 487 | |
|---|
| 455 | | -out_free_outring: |
|---|
| 456 | | - dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, |
|---|
| 457 | | - jrp->outring, outbusaddr); |
|---|
| 458 | | -out_free_inpring: |
|---|
| 459 | | - dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH, |
|---|
| 460 | | - jrp->inpring, inpbusaddr); |
|---|
| 461 | | - dev_err(dev, "can't allocate job rings for %d\n", jrp->ridx); |
|---|
| 462 | | -out_free_irq: |
|---|
| 463 | | - free_irq(jrp->irq, dev); |
|---|
| 464 | | -out_kill_deq: |
|---|
| 465 | | - tasklet_kill(&jrp->irqtask); |
|---|
| 488 | + /* Connect job ring interrupt handler. */ |
|---|
| 489 | + error = devm_request_irq(dev, jrp->irq, caam_jr_interrupt, IRQF_SHARED, |
|---|
| 490 | + dev_name(dev), dev); |
|---|
| 491 | + if (error) { |
|---|
| 492 | + dev_err(dev, "can't connect JobR %d interrupt (%d)\n", |
|---|
| 493 | + jrp->ridx, jrp->irq); |
|---|
| 494 | + tasklet_kill(&jrp->irqtask); |
|---|
| 495 | + } |
|---|
| 496 | + |
|---|
| 466 | 497 | return error; |
|---|
| 467 | 498 | } |
|---|
| 468 | 499 | |
|---|
| 500 | +static void caam_jr_irq_dispose_mapping(void *data) |
|---|
| 501 | +{ |
|---|
| 502 | + irq_dispose_mapping((unsigned long)data); |
|---|
| 503 | +} |
|---|
| 469 | 504 | |
|---|
| 470 | 505 | /* |
|---|
| 471 | 506 | * Probe routine for each detected JobR subsystem. |
|---|
| .. | .. |
|---|
| 477 | 512 | struct caam_job_ring __iomem *ctrl; |
|---|
| 478 | 513 | struct caam_drv_private_jr *jrpriv; |
|---|
| 479 | 514 | static int total_jobrs; |
|---|
| 515 | + struct resource *r; |
|---|
| 480 | 516 | int error; |
|---|
| 481 | 517 | |
|---|
| 482 | 518 | jrdev = &pdev->dev; |
|---|
| 483 | | - jrpriv = devm_kmalloc(jrdev, sizeof(*jrpriv), GFP_KERNEL); |
|---|
| 519 | + jrpriv = devm_kzalloc(jrdev, sizeof(*jrpriv), GFP_KERNEL); |
|---|
| 484 | 520 | if (!jrpriv) |
|---|
| 485 | 521 | return -ENOMEM; |
|---|
| 486 | 522 | |
|---|
| .. | .. |
|---|
| 492 | 528 | nprop = pdev->dev.of_node; |
|---|
| 493 | 529 | /* Get configuration properties from device tree */ |
|---|
| 494 | 530 | /* First, get register page */ |
|---|
| 495 | | - ctrl = of_iomap(nprop, 0); |
|---|
| 531 | + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 532 | + if (!r) { |
|---|
| 533 | + dev_err(jrdev, "platform_get_resource() failed\n"); |
|---|
| 534 | + return -ENOMEM; |
|---|
| 535 | + } |
|---|
| 536 | + |
|---|
| 537 | + ctrl = devm_ioremap(jrdev, r->start, resource_size(r)); |
|---|
| 496 | 538 | if (!ctrl) { |
|---|
| 497 | | - dev_err(jrdev, "of_iomap() failed\n"); |
|---|
| 539 | + dev_err(jrdev, "devm_ioremap() failed\n"); |
|---|
| 498 | 540 | return -ENOMEM; |
|---|
| 499 | 541 | } |
|---|
| 500 | 542 | |
|---|
| 501 | 543 | jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl; |
|---|
| 502 | 544 | |
|---|
| 503 | | - if (sizeof(dma_addr_t) == sizeof(u64)) { |
|---|
| 504 | | - if (caam_dpaa2) |
|---|
| 505 | | - error = dma_set_mask_and_coherent(jrdev, |
|---|
| 506 | | - DMA_BIT_MASK(49)); |
|---|
| 507 | | - else if (of_device_is_compatible(nprop, |
|---|
| 508 | | - "fsl,sec-v5.0-job-ring")) |
|---|
| 509 | | - error = dma_set_mask_and_coherent(jrdev, |
|---|
| 510 | | - DMA_BIT_MASK(40)); |
|---|
| 511 | | - else |
|---|
| 512 | | - error = dma_set_mask_and_coherent(jrdev, |
|---|
| 513 | | - DMA_BIT_MASK(36)); |
|---|
| 514 | | - } else { |
|---|
| 515 | | - error = dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(32)); |
|---|
| 516 | | - } |
|---|
| 545 | + error = dma_set_mask_and_coherent(jrdev, caam_get_dma_mask(jrdev)); |
|---|
| 517 | 546 | if (error) { |
|---|
| 518 | 547 | dev_err(jrdev, "dma_set_mask_and_coherent failed (%d)\n", |
|---|
| 519 | 548 | error); |
|---|
| 520 | | - iounmap(ctrl); |
|---|
| 549 | + return error; |
|---|
| 550 | + } |
|---|
| 551 | + |
|---|
| 552 | + /* Initialize crypto engine */ |
|---|
| 553 | + jrpriv->engine = crypto_engine_alloc_init(jrdev, false); |
|---|
| 554 | + if (!jrpriv->engine) { |
|---|
| 555 | + dev_err(jrdev, "Could not init crypto-engine\n"); |
|---|
| 556 | + return -ENOMEM; |
|---|
| 557 | + } |
|---|
| 558 | + |
|---|
| 559 | + error = devm_add_action_or_reset(jrdev, caam_jr_crypto_engine_exit, |
|---|
| 560 | + jrdev); |
|---|
| 561 | + if (error) |
|---|
| 562 | + return error; |
|---|
| 563 | + |
|---|
| 564 | + /* Start crypto engine */ |
|---|
| 565 | + error = crypto_engine_start(jrpriv->engine); |
|---|
| 566 | + if (error) { |
|---|
| 567 | + dev_err(jrdev, "Could not start crypto-engine\n"); |
|---|
| 521 | 568 | return error; |
|---|
| 522 | 569 | } |
|---|
| 523 | 570 | |
|---|
| 524 | 571 | /* Identify the interrupt */ |
|---|
| 525 | 572 | jrpriv->irq = irq_of_parse_and_map(nprop, 0); |
|---|
| 573 | + if (!jrpriv->irq) { |
|---|
| 574 | + dev_err(jrdev, "irq_of_parse_and_map failed\n"); |
|---|
| 575 | + return -EINVAL; |
|---|
| 576 | + } |
|---|
| 577 | + |
|---|
| 578 | + error = devm_add_action_or_reset(jrdev, caam_jr_irq_dispose_mapping, |
|---|
| 579 | + (void *)(unsigned long)jrpriv->irq); |
|---|
| 580 | + if (error) |
|---|
| 581 | + return error; |
|---|
| 526 | 582 | |
|---|
| 527 | 583 | /* Now do the platform independent part */ |
|---|
| 528 | 584 | error = caam_jr_init(jrdev); /* now turn on hardware */ |
|---|
| 529 | | - if (error) { |
|---|
| 530 | | - irq_dispose_mapping(jrpriv->irq); |
|---|
| 531 | | - iounmap(ctrl); |
|---|
| 585 | + if (error) |
|---|
| 532 | 586 | return error; |
|---|
| 533 | | - } |
|---|
| 534 | 587 | |
|---|
| 535 | 588 | jrpriv->dev = jrdev; |
|---|
| 536 | 589 | spin_lock(&driver_data.jr_alloc_lock); |
|---|
| .. | .. |
|---|
| 539 | 592 | |
|---|
| 540 | 593 | atomic_set(&jrpriv->tfm_count, 0); |
|---|
| 541 | 594 | |
|---|
| 595 | + register_algs(jrpriv, jrdev->parent); |
|---|
| 596 | + |
|---|
| 542 | 597 | return 0; |
|---|
| 543 | 598 | } |
|---|
| 544 | 599 | |
|---|