linux/drivers/crypto/atmel-tdes.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * Support for ATMEL DES/TDES HW acceleration.
   5 *
   6 * Copyright (c) 2012 Eukréa Electromatique - ATMEL
   7 * Author: Nicolas Royer <nicolas@eukrea.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as published
  11 * by the Free Software Foundation.
  12 *
  13 * Some ideas are from omap-aes.c drivers.
  14 */
  15
  16
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/slab.h>
  20#include <linux/err.h>
  21#include <linux/clk.h>
  22#include <linux/io.h>
  23#include <linux/hw_random.h>
  24#include <linux/platform_device.h>
  25
  26#include <linux/device.h>
  27#include <linux/module.h>
  28#include <linux/init.h>
  29#include <linux/errno.h>
  30#include <linux/interrupt.h>
  31#include <linux/kernel.h>
  32#include <linux/clk.h>
  33#include <linux/irq.h>
  34#include <linux/io.h>
  35#include <linux/platform_device.h>
  36#include <linux/scatterlist.h>
  37#include <linux/dma-mapping.h>
  38#include <linux/delay.h>
  39#include <linux/crypto.h>
  40#include <linux/cryptohash.h>
  41#include <crypto/scatterwalk.h>
  42#include <crypto/algapi.h>
  43#include <crypto/des.h>
  44#include <crypto/hash.h>
  45#include <crypto/internal/hash.h>
  46#include "atmel-tdes-regs.h"
  47
  48/* TDES flags  */
  49#define TDES_FLAGS_MODE_MASK            0x007f
  50#define TDES_FLAGS_ENCRYPT      BIT(0)
  51#define TDES_FLAGS_CBC          BIT(1)
  52#define TDES_FLAGS_CFB          BIT(2)
  53#define TDES_FLAGS_CFB8         BIT(3)
  54#define TDES_FLAGS_CFB16        BIT(4)
  55#define TDES_FLAGS_CFB32        BIT(5)
  56#define TDES_FLAGS_OFB          BIT(6)
  57
  58#define TDES_FLAGS_INIT         BIT(16)
  59#define TDES_FLAGS_FAST         BIT(17)
  60#define TDES_FLAGS_BUSY         BIT(18)
  61
  62#define ATMEL_TDES_QUEUE_LENGTH 1
  63
  64#define CFB8_BLOCK_SIZE         1
  65#define CFB16_BLOCK_SIZE        2
  66#define CFB32_BLOCK_SIZE        4
  67#define CFB64_BLOCK_SIZE        8
  68
  69
  70struct atmel_tdes_dev;
  71
  72struct atmel_tdes_ctx {
  73        struct atmel_tdes_dev *dd;
  74
  75        int             keylen;
  76        u32             key[3*DES_KEY_SIZE / sizeof(u32)];
  77        unsigned long   flags;
  78};
  79
  80struct atmel_tdes_reqctx {
  81        unsigned long mode;
  82};
  83
  84struct atmel_tdes_dev {
  85        struct list_head        list;
  86        unsigned long           phys_base;
  87        void __iomem            *io_base;
  88
  89        struct atmel_tdes_ctx   *ctx;
  90        struct device           *dev;
  91        struct clk                      *iclk;
  92        int                                     irq;
  93
  94        unsigned long           flags;
  95        int                     err;
  96
  97        spinlock_t              lock;
  98        struct crypto_queue     queue;
  99
 100        struct tasklet_struct   done_task;
 101        struct tasklet_struct   queue_task;
 102
 103        struct ablkcipher_request       *req;
 104        size_t                          total;
 105
 106        struct scatterlist      *in_sg;
 107        size_t                          in_offset;
 108        struct scatterlist      *out_sg;
 109        size_t                          out_offset;
 110
 111        size_t  buflen;
 112        size_t  dma_size;
 113
 114        void    *buf_in;
 115        int             dma_in;
 116        dma_addr_t      dma_addr_in;
 117
 118        void    *buf_out;
 119        int             dma_out;
 120        dma_addr_t      dma_addr_out;
 121};
 122
 123struct atmel_tdes_drv {
 124        struct list_head        dev_list;
 125        spinlock_t              lock;
 126};
 127
 128static struct atmel_tdes_drv atmel_tdes = {
 129        .dev_list = LIST_HEAD_INIT(atmel_tdes.dev_list),
 130        .lock = __SPIN_LOCK_UNLOCKED(atmel_tdes.lock),
 131};
 132
 133static int atmel_tdes_sg_copy(struct scatterlist **sg, size_t *offset,
 134                        void *buf, size_t buflen, size_t total, int out)
 135{
 136        unsigned int count, off = 0;
 137
 138        while (buflen && total) {
 139                count = min((*sg)->length - *offset, total);
 140                count = min(count, buflen);
 141
 142                if (!count)
 143                        return off;
 144
 145                scatterwalk_map_and_copy(buf + off, *sg, *offset, count, out);
 146
 147                off += count;
 148                buflen -= count;
 149                *offset += count;
 150                total -= count;
 151
 152                if (*offset == (*sg)->length) {
 153                        *sg = sg_next(*sg);
 154                        if (*sg)
 155                                *offset = 0;
 156                        else
 157                                total = 0;
 158                }
 159        }
 160
 161        return off;
 162}
 163
 164static inline u32 atmel_tdes_read(struct atmel_tdes_dev *dd, u32 offset)
 165{
 166        return readl_relaxed(dd->io_base + offset);
 167}
 168
 169static inline void atmel_tdes_write(struct atmel_tdes_dev *dd,
 170                                        u32 offset, u32 value)
 171{
 172        writel_relaxed(value, dd->io_base + offset);
 173}
 174
 175static void atmel_tdes_write_n(struct atmel_tdes_dev *dd, u32 offset,
 176                                        u32 *value, int count)
 177{
 178        for (; count--; value++, offset += 4)
 179                atmel_tdes_write(dd, offset, *value);
 180}
 181
 182static struct atmel_tdes_dev *atmel_tdes_find_dev(struct atmel_tdes_ctx *ctx)
 183{
 184        struct atmel_tdes_dev *tdes_dd = NULL;
 185        struct atmel_tdes_dev *tmp;
 186
 187        spin_lock_bh(&atmel_tdes.lock);
 188        if (!ctx->dd) {
 189                list_for_each_entry(tmp, &atmel_tdes.dev_list, list) {
 190                        tdes_dd = tmp;
 191                        break;
 192                }
 193                ctx->dd = tdes_dd;
 194        } else {
 195                tdes_dd = ctx->dd;
 196        }
 197        spin_unlock_bh(&atmel_tdes.lock);
 198
 199        return tdes_dd;
 200}
 201
 202static int atmel_tdes_hw_init(struct atmel_tdes_dev *dd)
 203{
 204        clk_prepare_enable(dd->iclk);
 205
 206        if (!(dd->flags & TDES_FLAGS_INIT)) {
 207                atmel_tdes_write(dd, TDES_CR, TDES_CR_SWRST);
 208                dd->flags |= TDES_FLAGS_INIT;
 209                dd->err = 0;
 210        }
 211
 212        return 0;
 213}
 214
 215static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
 216{
 217        int err;
 218        u32 valcr = 0, valmr = TDES_MR_SMOD_PDC;
 219
 220        err = atmel_tdes_hw_init(dd);
 221
 222        if (err)
 223                return err;
 224
 225        atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
 226
 227        /* MR register must be set before IV registers */
 228        if (dd->ctx->keylen > (DES_KEY_SIZE << 1)) {
 229                valmr |= TDES_MR_KEYMOD_3KEY;
 230                valmr |= TDES_MR_TDESMOD_TDES;
 231        } else if (dd->ctx->keylen > DES_KEY_SIZE) {
 232                valmr |= TDES_MR_KEYMOD_2KEY;
 233                valmr |= TDES_MR_TDESMOD_TDES;
 234        } else {
 235                valmr |= TDES_MR_TDESMOD_DES;
 236        }
 237
 238        if (dd->flags & TDES_FLAGS_CBC) {
 239                valmr |= TDES_MR_OPMOD_CBC;
 240        } else if (dd->flags & TDES_FLAGS_CFB) {
 241                valmr |= TDES_MR_OPMOD_CFB;
 242
 243                if (dd->flags & TDES_FLAGS_CFB8)
 244                        valmr |= TDES_MR_CFBS_8b;
 245                else if (dd->flags & TDES_FLAGS_CFB16)
 246                        valmr |= TDES_MR_CFBS_16b;
 247                else if (dd->flags & TDES_FLAGS_CFB32)
 248                        valmr |= TDES_MR_CFBS_32b;
 249        } else if (dd->flags & TDES_FLAGS_OFB) {
 250                valmr |= TDES_MR_OPMOD_OFB;
 251        }
 252
 253        if ((dd->flags & TDES_FLAGS_ENCRYPT) || (dd->flags & TDES_FLAGS_OFB))
 254                valmr |= TDES_MR_CYPHER_ENC;
 255
 256        atmel_tdes_write(dd, TDES_CR, valcr);
 257        atmel_tdes_write(dd, TDES_MR, valmr);
 258
 259        atmel_tdes_write_n(dd, TDES_KEY1W1R, dd->ctx->key,
 260                                                dd->ctx->keylen >> 2);
 261
 262        if (((dd->flags & TDES_FLAGS_CBC) || (dd->flags & TDES_FLAGS_CFB) ||
 263                (dd->flags & TDES_FLAGS_OFB)) && dd->req->info) {
 264                atmel_tdes_write_n(dd, TDES_IV1R, dd->req->info, 2);
 265        }
 266
 267        return 0;
 268}
 269
 270static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd)
 271{
 272        int err = 0;
 273        size_t count;
 274
 275        atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
 276
 277        if (dd->flags & TDES_FLAGS_FAST) {
 278                dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
 279                dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
 280        } else {
 281                dma_sync_single_for_device(dd->dev, dd->dma_addr_out,
 282                                           dd->dma_size, DMA_FROM_DEVICE);
 283
 284                /* copy data */
 285                count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset,
 286                                dd->buf_out, dd->buflen, dd->dma_size, 1);
 287                if (count != dd->dma_size) {
 288                        err = -EINVAL;
 289                        pr_err("not all data converted: %u\n", count);
 290                }
 291        }
 292
 293        return err;
 294}
 295
 296static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd)
 297{
 298        int err = -ENOMEM;
 299
 300        dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, 0);
 301        dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, 0);
 302        dd->buflen = PAGE_SIZE;
 303        dd->buflen &= ~(DES_BLOCK_SIZE - 1);
 304
 305        if (!dd->buf_in || !dd->buf_out) {
 306                dev_err(dd->dev, "unable to alloc pages.\n");
 307                goto err_alloc;
 308        }
 309
 310        /* MAP here */
 311        dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in,
 312                                        dd->buflen, DMA_TO_DEVICE);
 313        if (dma_mapping_error(dd->dev, dd->dma_addr_in)) {
 314                dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
 315                err = -EINVAL;
 316                goto err_map_in;
 317        }
 318
 319        dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out,
 320                                        dd->buflen, DMA_FROM_DEVICE);
 321        if (dma_mapping_error(dd->dev, dd->dma_addr_out)) {
 322                dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
 323                err = -EINVAL;
 324                goto err_map_out;
 325        }
 326
 327        return 0;
 328
 329err_map_out:
 330        dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen,
 331                DMA_TO_DEVICE);
 332err_map_in:
 333        free_page((unsigned long)dd->buf_out);
 334        free_page((unsigned long)dd->buf_in);
 335err_alloc:
 336        if (err)
 337                pr_err("error: %d\n", err);
 338        return err;
 339}
 340
 341static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd)
 342{
 343        dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
 344                         DMA_FROM_DEVICE);
 345        dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen,
 346                DMA_TO_DEVICE);
 347        free_page((unsigned long)dd->buf_out);
 348        free_page((unsigned long)dd->buf_in);
 349}
 350
 351static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
 352                               dma_addr_t dma_addr_out, int length)
 353{
 354        struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
 355        struct atmel_tdes_dev *dd = ctx->dd;
 356        int len32;
 357
 358        dd->dma_size = length;
 359
 360        if (!(dd->flags & TDES_FLAGS_FAST)) {
 361                dma_sync_single_for_device(dd->dev, dma_addr_in, length,
 362                                           DMA_TO_DEVICE);
 363        }
 364
 365        if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB8))
 366                len32 = DIV_ROUND_UP(length, sizeof(u8));
 367        else if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB16))
 368                len32 = DIV_ROUND_UP(length, sizeof(u16));
 369        else
 370                len32 = DIV_ROUND_UP(length, sizeof(u32));
 371
 372        atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
 373        atmel_tdes_write(dd, TDES_TPR, dma_addr_in);
 374        atmel_tdes_write(dd, TDES_TCR, len32);
 375        atmel_tdes_write(dd, TDES_RPR, dma_addr_out);
 376        atmel_tdes_write(dd, TDES_RCR, len32);
 377
 378        /* Enable Interrupt */
 379        atmel_tdes_write(dd, TDES_IER, TDES_INT_ENDRX);
 380
 381        /* Start DMA transfer */
 382        atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTEN | TDES_PTCR_RXTEN);
 383
 384        return 0;
 385}
 386
 387static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd)
 388{
 389        struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
 390                                        crypto_ablkcipher_reqtfm(dd->req));
 391        int err, fast = 0, in, out;
 392        size_t count;
 393        dma_addr_t addr_in, addr_out;
 394
 395        if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) {
 396                /* check for alignment */
 397                in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32));
 398                out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32));
 399
 400                fast = in && out;
 401        }
 402
 403        if (fast)  {
 404                count = min(dd->total, sg_dma_len(dd->in_sg));
 405                count = min(count, sg_dma_len(dd->out_sg));
 406
 407                if (count != dd->total) {
 408                        pr_err("request length != buffer length\n");
 409                        return -EINVAL;
 410                }
 411
 412                err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
 413                if (!err) {
 414                        dev_err(dd->dev, "dma_map_sg() error\n");
 415                        return -EINVAL;
 416                }
 417
 418                err = dma_map_sg(dd->dev, dd->out_sg, 1,
 419                                DMA_FROM_DEVICE);
 420                if (!err) {
 421                        dev_err(dd->dev, "dma_map_sg() error\n");
 422                        dma_unmap_sg(dd->dev, dd->in_sg, 1,
 423                                DMA_TO_DEVICE);
 424                        return -EINVAL;
 425                }
 426
 427                addr_in = sg_dma_address(dd->in_sg);
 428                addr_out = sg_dma_address(dd->out_sg);
 429
 430                dd->flags |= TDES_FLAGS_FAST;
 431
 432        } else {
 433                /* use cache buffers */
 434                count = atmel_tdes_sg_copy(&dd->in_sg, &dd->in_offset,
 435                                dd->buf_in, dd->buflen, dd->total, 0);
 436
 437                addr_in = dd->dma_addr_in;
 438                addr_out = dd->dma_addr_out;
 439
 440                dd->flags &= ~TDES_FLAGS_FAST;
 441
 442        }
 443
 444        dd->total -= count;
 445
 446        err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count);
 447        if (err) {
 448                dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
 449                dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
 450        }
 451
 452        return err;
 453}
 454
 455
 456static void atmel_tdes_finish_req(struct atmel_tdes_dev *dd, int err)
 457{
 458        struct ablkcipher_request *req = dd->req;
 459
 460        clk_disable_unprepare(dd->iclk);
 461
 462        dd->flags &= ~TDES_FLAGS_BUSY;
 463
 464        req->base.complete(&req->base, err);
 465}
 466
 467static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd,
 468                               struct ablkcipher_request *req)
 469{
 470        struct crypto_async_request *async_req, *backlog;
 471        struct atmel_tdes_ctx *ctx;
 472        struct atmel_tdes_reqctx *rctx;
 473        unsigned long flags;
 474        int err, ret = 0;
 475
 476        spin_lock_irqsave(&dd->lock, flags);
 477        if (req)
 478                ret = ablkcipher_enqueue_request(&dd->queue, req);
 479        if (dd->flags & TDES_FLAGS_BUSY) {
 480                spin_unlock_irqrestore(&dd->lock, flags);
 481                return ret;
 482        }
 483        backlog = crypto_get_backlog(&dd->queue);
 484        async_req = crypto_dequeue_request(&dd->queue);
 485        if (async_req)
 486                dd->flags |= TDES_FLAGS_BUSY;
 487        spin_unlock_irqrestore(&dd->lock, flags);
 488
 489        if (!async_req)
 490                return ret;
 491
 492        if (backlog)
 493                backlog->complete(backlog, -EINPROGRESS);
 494
 495        req = ablkcipher_request_cast(async_req);
 496
 497        /* assign new request to device */
 498        dd->req = req;
 499        dd->total = req->nbytes;
 500        dd->in_offset = 0;
 501        dd->in_sg = req->src;
 502        dd->out_offset = 0;
 503        dd->out_sg = req->dst;
 504
 505        rctx = ablkcipher_request_ctx(req);
 506        ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
 507        rctx->mode &= TDES_FLAGS_MODE_MASK;
 508        dd->flags = (dd->flags & ~TDES_FLAGS_MODE_MASK) | rctx->mode;
 509        dd->ctx = ctx;
 510        ctx->dd = dd;
 511
 512        err = atmel_tdes_write_ctrl(dd);
 513        if (!err)
 514                err = atmel_tdes_crypt_dma_start(dd);
 515        if (err) {
 516                /* des_task will not finish it, so do it here */
 517                atmel_tdes_finish_req(dd, err);
 518                tasklet_schedule(&dd->queue_task);
 519        }
 520
 521        return ret;
 522}
 523
 524
 525static int atmel_tdes_crypt(struct ablkcipher_request *req, unsigned long mode)
 526{
 527        struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx(
 528                        crypto_ablkcipher_reqtfm(req));
 529        struct atmel_tdes_reqctx *rctx = ablkcipher_request_ctx(req);
 530        struct atmel_tdes_dev *dd;
 531
 532        if (mode & TDES_FLAGS_CFB8) {
 533                if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) {
 534                        pr_err("request size is not exact amount of CFB8 blocks\n");
 535                        return -EINVAL;
 536                }
 537        } else if (mode & TDES_FLAGS_CFB16) {
 538                if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) {
 539                        pr_err("request size is not exact amount of CFB16 blocks\n");
 540                        return -EINVAL;
 541                }
 542        } else if (mode & TDES_FLAGS_CFB32) {
 543                if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) {
 544                        pr_err("request size is not exact amount of CFB32 blocks\n");
 545                        return -EINVAL;
 546                }
 547        } else if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) {
 548                pr_err("request size is not exact amount of DES blocks\n");
 549                return -EINVAL;
 550        }
 551
 552        dd = atmel_tdes_find_dev(ctx);
 553        if (!dd)
 554                return -ENODEV;
 555
 556        rctx->mode = mode;
 557
 558        return atmel_tdes_handle_queue(dd, req);
 559}
 560
 561static int atmel_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
 562                           unsigned int keylen)
 563{
 564        u32 tmp[DES_EXPKEY_WORDS];
 565        int err;
 566        struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm);
 567
 568        struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 569
 570        if (keylen != DES_KEY_SIZE) {
 571                crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 572                return -EINVAL;
 573        }
 574
 575        err = des_ekey(tmp, key);
 576        if (err == 0 && (ctfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
 577                ctfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
 578                return -EINVAL;
 579        }
 580
 581        memcpy(ctx->key, key, keylen);
 582        ctx->keylen = keylen;
 583
 584        return 0;
 585}
 586
 587static int atmel_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
 588                           unsigned int keylen)
 589{
 590        struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 591        const char *alg_name;
 592
 593        alg_name = crypto_tfm_alg_name(crypto_ablkcipher_tfm(tfm));
 594
 595        /*
 596         * HW bug in cfb 3-keys mode.
 597         */
 598        if (strstr(alg_name, "cfb") && (keylen != 2*DES_KEY_SIZE)) {
 599                crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 600                return -EINVAL;
 601        } else if ((keylen != 2*DES_KEY_SIZE) && (keylen != 3*DES_KEY_SIZE)) {
 602                crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 603                return -EINVAL;
 604        }
 605
 606        memcpy(ctx->key, key, keylen);
 607        ctx->keylen = keylen;
 608
 609        return 0;
 610}
 611
 612static int atmel_tdes_ecb_encrypt(struct ablkcipher_request *req)
 613{
 614        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT);
 615}
 616
 617static int atmel_tdes_ecb_decrypt(struct ablkcipher_request *req)
 618{
 619        return atmel_tdes_crypt(req, 0);
 620}
 621
 622static int atmel_tdes_cbc_encrypt(struct ablkcipher_request *req)
 623{
 624        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CBC);
 625}
 626
 627static int atmel_tdes_cbc_decrypt(struct ablkcipher_request *req)
 628{
 629        return atmel_tdes_crypt(req, TDES_FLAGS_CBC);
 630}
 631static int atmel_tdes_cfb_encrypt(struct ablkcipher_request *req)
 632{
 633        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB);
 634}
 635
 636static int atmel_tdes_cfb_decrypt(struct ablkcipher_request *req)
 637{
 638        return atmel_tdes_crypt(req, TDES_FLAGS_CFB);
 639}
 640
 641static int atmel_tdes_cfb8_encrypt(struct ablkcipher_request *req)
 642{
 643        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
 644                                                TDES_FLAGS_CFB8);
 645}
 646
 647static int atmel_tdes_cfb8_decrypt(struct ablkcipher_request *req)
 648{
 649        return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB8);
 650}
 651
 652static int atmel_tdes_cfb16_encrypt(struct ablkcipher_request *req)
 653{
 654        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
 655                                                TDES_FLAGS_CFB16);
 656}
 657
 658static int atmel_tdes_cfb16_decrypt(struct ablkcipher_request *req)
 659{
 660        return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB16);
 661}
 662
 663static int atmel_tdes_cfb32_encrypt(struct ablkcipher_request *req)
 664{
 665        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
 666                                                TDES_FLAGS_CFB32);
 667}
 668
 669static int atmel_tdes_cfb32_decrypt(struct ablkcipher_request *req)
 670{
 671        return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB32);
 672}
 673
 674static int atmel_tdes_ofb_encrypt(struct ablkcipher_request *req)
 675{
 676        return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_OFB);
 677}
 678
 679static int atmel_tdes_ofb_decrypt(struct ablkcipher_request *req)
 680{
 681        return atmel_tdes_crypt(req, TDES_FLAGS_OFB);
 682}
 683
 684static int atmel_tdes_cra_init(struct crypto_tfm *tfm)
 685{
 686        tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_tdes_reqctx);
 687
 688        return 0;
 689}
 690
 691static void atmel_tdes_cra_exit(struct crypto_tfm *tfm)
 692{
 693}
 694
 695static struct crypto_alg tdes_algs[] = {
 696{
 697        .cra_name               = "ecb(des)",
 698        .cra_driver_name        = "atmel-ecb-des",
 699        .cra_priority           = 100,
 700        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 701        .cra_blocksize          = DES_BLOCK_SIZE,
 702        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 703        .cra_alignmask          = 0,
 704        .cra_type               = &crypto_ablkcipher_type,
 705        .cra_module             = THIS_MODULE,
 706        .cra_init               = atmel_tdes_cra_init,
 707        .cra_exit               = atmel_tdes_cra_exit,
 708        .cra_u.ablkcipher = {
 709                .min_keysize    = DES_KEY_SIZE,
 710                .max_keysize    = DES_KEY_SIZE,
 711                .setkey         = atmel_des_setkey,
 712                .encrypt        = atmel_tdes_ecb_encrypt,
 713                .decrypt        = atmel_tdes_ecb_decrypt,
 714        }
 715},
 716{
 717        .cra_name               = "cbc(des)",
 718        .cra_driver_name        = "atmel-cbc-des",
 719        .cra_priority           = 100,
 720        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 721        .cra_blocksize          = DES_BLOCK_SIZE,
 722        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 723        .cra_alignmask          = 0,
 724        .cra_type               = &crypto_ablkcipher_type,
 725        .cra_module             = THIS_MODULE,
 726        .cra_init               = atmel_tdes_cra_init,
 727        .cra_exit               = atmel_tdes_cra_exit,
 728        .cra_u.ablkcipher = {
 729                .min_keysize    = DES_KEY_SIZE,
 730                .max_keysize    = DES_KEY_SIZE,
 731                .ivsize         = DES_BLOCK_SIZE,
 732                .setkey         = atmel_des_setkey,
 733                .encrypt        = atmel_tdes_cbc_encrypt,
 734                .decrypt        = atmel_tdes_cbc_decrypt,
 735        }
 736},
 737{
 738        .cra_name               = "cfb(des)",
 739        .cra_driver_name        = "atmel-cfb-des",
 740        .cra_priority           = 100,
 741        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 742        .cra_blocksize          = DES_BLOCK_SIZE,
 743        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 744        .cra_alignmask          = 0,
 745        .cra_type               = &crypto_ablkcipher_type,
 746        .cra_module             = THIS_MODULE,
 747        .cra_init               = atmel_tdes_cra_init,
 748        .cra_exit               = atmel_tdes_cra_exit,
 749        .cra_u.ablkcipher = {
 750                .min_keysize    = DES_KEY_SIZE,
 751                .max_keysize    = DES_KEY_SIZE,
 752                .ivsize         = DES_BLOCK_SIZE,
 753                .setkey         = atmel_des_setkey,
 754                .encrypt        = atmel_tdes_cfb_encrypt,
 755                .decrypt        = atmel_tdes_cfb_decrypt,
 756        }
 757},
 758{
 759        .cra_name               = "cfb8(des)",
 760        .cra_driver_name        = "atmel-cfb8-des",
 761        .cra_priority           = 100,
 762        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 763        .cra_blocksize          = CFB8_BLOCK_SIZE,
 764        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 765        .cra_alignmask          = 0,
 766        .cra_type               = &crypto_ablkcipher_type,
 767        .cra_module             = THIS_MODULE,
 768        .cra_init               = atmel_tdes_cra_init,
 769        .cra_exit               = atmel_tdes_cra_exit,
 770        .cra_u.ablkcipher = {
 771                .min_keysize    = DES_KEY_SIZE,
 772                .max_keysize    = DES_KEY_SIZE,
 773                .ivsize         = DES_BLOCK_SIZE,
 774                .setkey         = atmel_des_setkey,
 775                .encrypt        = atmel_tdes_cfb8_encrypt,
 776                .decrypt        = atmel_tdes_cfb8_decrypt,
 777        }
 778},
 779{
 780        .cra_name               = "cfb16(des)",
 781        .cra_driver_name        = "atmel-cfb16-des",
 782        .cra_priority           = 100,
 783        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 784        .cra_blocksize          = CFB16_BLOCK_SIZE,
 785        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 786        .cra_alignmask          = 0,
 787        .cra_type               = &crypto_ablkcipher_type,
 788        .cra_module             = THIS_MODULE,
 789        .cra_init               = atmel_tdes_cra_init,
 790        .cra_exit               = atmel_tdes_cra_exit,
 791        .cra_u.ablkcipher = {
 792                .min_keysize    = DES_KEY_SIZE,
 793                .max_keysize    = DES_KEY_SIZE,
 794                .ivsize         = DES_BLOCK_SIZE,
 795                .setkey         = atmel_des_setkey,
 796                .encrypt        = atmel_tdes_cfb16_encrypt,
 797                .decrypt        = atmel_tdes_cfb16_decrypt,
 798        }
 799},
 800{
 801        .cra_name               = "cfb32(des)",
 802        .cra_driver_name        = "atmel-cfb32-des",
 803        .cra_priority           = 100,
 804        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 805        .cra_blocksize          = CFB32_BLOCK_SIZE,
 806        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 807        .cra_alignmask          = 0,
 808        .cra_type               = &crypto_ablkcipher_type,
 809        .cra_module             = THIS_MODULE,
 810        .cra_init               = atmel_tdes_cra_init,
 811        .cra_exit               = atmel_tdes_cra_exit,
 812        .cra_u.ablkcipher = {
 813                .min_keysize    = DES_KEY_SIZE,
 814                .max_keysize    = DES_KEY_SIZE,
 815                .ivsize         = DES_BLOCK_SIZE,
 816                .setkey         = atmel_des_setkey,
 817                .encrypt        = atmel_tdes_cfb32_encrypt,
 818                .decrypt        = atmel_tdes_cfb32_decrypt,
 819        }
 820},
 821{
 822        .cra_name               = "ofb(des)",
 823        .cra_driver_name        = "atmel-ofb-des",
 824        .cra_priority           = 100,
 825        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 826        .cra_blocksize          = DES_BLOCK_SIZE,
 827        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 828        .cra_alignmask          = 0,
 829        .cra_type               = &crypto_ablkcipher_type,
 830        .cra_module             = THIS_MODULE,
 831        .cra_init               = atmel_tdes_cra_init,
 832        .cra_exit               = atmel_tdes_cra_exit,
 833        .cra_u.ablkcipher = {
 834                .min_keysize    = DES_KEY_SIZE,
 835                .max_keysize    = DES_KEY_SIZE,
 836                .ivsize         = DES_BLOCK_SIZE,
 837                .setkey         = atmel_des_setkey,
 838                .encrypt        = atmel_tdes_ofb_encrypt,
 839                .decrypt        = atmel_tdes_ofb_decrypt,
 840        }
 841},
 842{
 843        .cra_name               = "ecb(des3_ede)",
 844        .cra_driver_name        = "atmel-ecb-tdes",
 845        .cra_priority           = 100,
 846        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 847        .cra_blocksize          = DES_BLOCK_SIZE,
 848        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 849        .cra_alignmask          = 0,
 850        .cra_type               = &crypto_ablkcipher_type,
 851        .cra_module             = THIS_MODULE,
 852        .cra_init               = atmel_tdes_cra_init,
 853        .cra_exit               = atmel_tdes_cra_exit,
 854        .cra_u.ablkcipher = {
 855                .min_keysize    = 2 * DES_KEY_SIZE,
 856                .max_keysize    = 3 * DES_KEY_SIZE,
 857                .setkey         = atmel_tdes_setkey,
 858                .encrypt        = atmel_tdes_ecb_encrypt,
 859                .decrypt        = atmel_tdes_ecb_decrypt,
 860        }
 861},
 862{
 863        .cra_name               = "cbc(des3_ede)",
 864        .cra_driver_name        = "atmel-cbc-tdes",
 865        .cra_priority           = 100,
 866        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 867        .cra_blocksize          = DES_BLOCK_SIZE,
 868        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 869        .cra_alignmask          = 0,
 870        .cra_type               = &crypto_ablkcipher_type,
 871        .cra_module             = THIS_MODULE,
 872        .cra_init               = atmel_tdes_cra_init,
 873        .cra_exit               = atmel_tdes_cra_exit,
 874        .cra_u.ablkcipher = {
 875                .min_keysize    = 2*DES_KEY_SIZE,
 876                .max_keysize    = 3*DES_KEY_SIZE,
 877                .ivsize         = DES_BLOCK_SIZE,
 878                .setkey         = atmel_tdes_setkey,
 879                .encrypt        = atmel_tdes_cbc_encrypt,
 880                .decrypt        = atmel_tdes_cbc_decrypt,
 881        }
 882},
 883{
 884        .cra_name               = "cfb(des3_ede)",
 885        .cra_driver_name        = "atmel-cfb-tdes",
 886        .cra_priority           = 100,
 887        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 888        .cra_blocksize          = DES_BLOCK_SIZE,
 889        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 890        .cra_alignmask          = 0,
 891        .cra_type               = &crypto_ablkcipher_type,
 892        .cra_module             = THIS_MODULE,
 893        .cra_init               = atmel_tdes_cra_init,
 894        .cra_exit               = atmel_tdes_cra_exit,
 895        .cra_u.ablkcipher = {
 896                .min_keysize    = 2*DES_KEY_SIZE,
 897                .max_keysize    = 2*DES_KEY_SIZE,
 898                .ivsize         = DES_BLOCK_SIZE,
 899                .setkey         = atmel_tdes_setkey,
 900                .encrypt        = atmel_tdes_cfb_encrypt,
 901                .decrypt        = atmel_tdes_cfb_decrypt,
 902        }
 903},
 904{
 905        .cra_name               = "cfb8(des3_ede)",
 906        .cra_driver_name        = "atmel-cfb8-tdes",
 907        .cra_priority           = 100,
 908        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 909        .cra_blocksize          = CFB8_BLOCK_SIZE,
 910        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 911        .cra_alignmask          = 0,
 912        .cra_type               = &crypto_ablkcipher_type,
 913        .cra_module             = THIS_MODULE,
 914        .cra_init               = atmel_tdes_cra_init,
 915        .cra_exit               = atmel_tdes_cra_exit,
 916        .cra_u.ablkcipher = {
 917                .min_keysize    = 2*DES_KEY_SIZE,
 918                .max_keysize    = 2*DES_KEY_SIZE,
 919                .ivsize         = DES_BLOCK_SIZE,
 920                .setkey         = atmel_tdes_setkey,
 921                .encrypt        = atmel_tdes_cfb8_encrypt,
 922                .decrypt        = atmel_tdes_cfb8_decrypt,
 923        }
 924},
 925{
 926        .cra_name               = "cfb16(des3_ede)",
 927        .cra_driver_name        = "atmel-cfb16-tdes",
 928        .cra_priority           = 100,
 929        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 930        .cra_blocksize          = CFB16_BLOCK_SIZE,
 931        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 932        .cra_alignmask          = 0,
 933        .cra_type               = &crypto_ablkcipher_type,
 934        .cra_module             = THIS_MODULE,
 935        .cra_init               = atmel_tdes_cra_init,
 936        .cra_exit               = atmel_tdes_cra_exit,
 937        .cra_u.ablkcipher = {
 938                .min_keysize    = 2*DES_KEY_SIZE,
 939                .max_keysize    = 2*DES_KEY_SIZE,
 940                .ivsize         = DES_BLOCK_SIZE,
 941                .setkey         = atmel_tdes_setkey,
 942                .encrypt        = atmel_tdes_cfb16_encrypt,
 943                .decrypt        = atmel_tdes_cfb16_decrypt,
 944        }
 945},
 946{
 947        .cra_name               = "cfb32(des3_ede)",
 948        .cra_driver_name        = "atmel-cfb32-tdes",
 949        .cra_priority           = 100,
 950        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 951        .cra_blocksize          = CFB32_BLOCK_SIZE,
 952        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 953        .cra_alignmask          = 0,
 954        .cra_type               = &crypto_ablkcipher_type,
 955        .cra_module             = THIS_MODULE,
 956        .cra_init               = atmel_tdes_cra_init,
 957        .cra_exit               = atmel_tdes_cra_exit,
 958        .cra_u.ablkcipher = {
 959                .min_keysize    = 2*DES_KEY_SIZE,
 960                .max_keysize    = 2*DES_KEY_SIZE,
 961                .ivsize         = DES_BLOCK_SIZE,
 962                .setkey         = atmel_tdes_setkey,
 963                .encrypt        = atmel_tdes_cfb32_encrypt,
 964                .decrypt        = atmel_tdes_cfb32_decrypt,
 965        }
 966},
 967{
 968        .cra_name               = "ofb(des3_ede)",
 969        .cra_driver_name        = "atmel-ofb-tdes",
 970        .cra_priority           = 100,
 971        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 972        .cra_blocksize          = DES_BLOCK_SIZE,
 973        .cra_ctxsize            = sizeof(struct atmel_tdes_ctx),
 974        .cra_alignmask          = 0,
 975        .cra_type               = &crypto_ablkcipher_type,
 976        .cra_module             = THIS_MODULE,
 977        .cra_init               = atmel_tdes_cra_init,
 978        .cra_exit               = atmel_tdes_cra_exit,
 979        .cra_u.ablkcipher = {
 980                .min_keysize    = 2*DES_KEY_SIZE,
 981                .max_keysize    = 3*DES_KEY_SIZE,
 982                .ivsize         = DES_BLOCK_SIZE,
 983                .setkey         = atmel_tdes_setkey,
 984                .encrypt        = atmel_tdes_ofb_encrypt,
 985                .decrypt        = atmel_tdes_ofb_decrypt,
 986        }
 987},
 988};
 989
 990static void atmel_tdes_queue_task(unsigned long data)
 991{
 992        struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *)data;
 993
 994        atmel_tdes_handle_queue(dd, NULL);
 995}
 996
 997static void atmel_tdes_done_task(unsigned long data)
 998{
 999        struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *) data;
1000        int err;
1001
1002        err = atmel_tdes_crypt_dma_stop(dd);
1003
1004        err = dd->err ? : err;
1005
1006        if (dd->total && !err) {
1007                err = atmel_tdes_crypt_dma_start(dd);
1008                if (!err)
1009                        return;
1010        }
1011
1012        atmel_tdes_finish_req(dd, err);
1013        atmel_tdes_handle_queue(dd, NULL);
1014}
1015
1016static irqreturn_t atmel_tdes_irq(int irq, void *dev_id)
1017{
1018        struct atmel_tdes_dev *tdes_dd = dev_id;
1019        u32 reg;
1020
1021        reg = atmel_tdes_read(tdes_dd, TDES_ISR);
1022        if (reg & atmel_tdes_read(tdes_dd, TDES_IMR)) {
1023                atmel_tdes_write(tdes_dd, TDES_IDR, reg);
1024                if (TDES_FLAGS_BUSY & tdes_dd->flags)
1025                        tasklet_schedule(&tdes_dd->done_task);
1026                else
1027                        dev_warn(tdes_dd->dev, "TDES interrupt when no active requests.\n");
1028                return IRQ_HANDLED;
1029        }
1030
1031        return IRQ_NONE;
1032}
1033
1034static void atmel_tdes_unregister_algs(struct atmel_tdes_dev *dd)
1035{
1036        int i;
1037
1038        for (i = 0; i < ARRAY_SIZE(tdes_algs); i++)
1039                crypto_unregister_alg(&tdes_algs[i]);
1040}
1041
1042static int atmel_tdes_register_algs(struct atmel_tdes_dev *dd)
1043{
1044        int err, i, j;
1045
1046        for (i = 0; i < ARRAY_SIZE(tdes_algs); i++) {
1047                INIT_LIST_HEAD(&tdes_algs[i].cra_list);
1048                err = crypto_register_alg(&tdes_algs[i]);
1049                if (err)
1050                        goto err_tdes_algs;
1051        }
1052
1053        return 0;
1054
1055err_tdes_algs:
1056        for (j = 0; j < i; j++)
1057                crypto_unregister_alg(&tdes_algs[j]);
1058
1059        return err;
1060}
1061
1062static int __devinit atmel_tdes_probe(struct platform_device *pdev)
1063{
1064        struct atmel_tdes_dev *tdes_dd;
1065        struct device *dev = &pdev->dev;
1066        struct resource *tdes_res;
1067        unsigned long tdes_phys_size;
1068        int err;
1069
1070        tdes_dd = kzalloc(sizeof(struct atmel_tdes_dev), GFP_KERNEL);
1071        if (tdes_dd == NULL) {
1072                dev_err(dev, "unable to alloc data struct.\n");
1073                err = -ENOMEM;
1074                goto tdes_dd_err;
1075        }
1076
1077        tdes_dd->dev = dev;
1078
1079        platform_set_drvdata(pdev, tdes_dd);
1080
1081        INIT_LIST_HEAD(&tdes_dd->list);
1082
1083        tasklet_init(&tdes_dd->done_task, atmel_tdes_done_task,
1084                                        (unsigned long)tdes_dd);
1085        tasklet_init(&tdes_dd->queue_task, atmel_tdes_queue_task,
1086                                        (unsigned long)tdes_dd);
1087
1088        crypto_init_queue(&tdes_dd->queue, ATMEL_TDES_QUEUE_LENGTH);
1089
1090        tdes_dd->irq = -1;
1091
1092        /* Get the base address */
1093        tdes_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1094        if (!tdes_res) {
1095                dev_err(dev, "no MEM resource info\n");
1096                err = -ENODEV;
1097                goto res_err;
1098        }
1099        tdes_dd->phys_base = tdes_res->start;
1100        tdes_phys_size = resource_size(tdes_res);
1101
1102        /* Get the IRQ */
1103        tdes_dd->irq = platform_get_irq(pdev,  0);
1104        if (tdes_dd->irq < 0) {
1105                dev_err(dev, "no IRQ resource info\n");
1106                err = tdes_dd->irq;
1107                goto res_err;
1108        }
1109
1110        err = request_irq(tdes_dd->irq, atmel_tdes_irq, IRQF_SHARED,
1111                        "atmel-tdes", tdes_dd);
1112        if (err) {
1113                dev_err(dev, "unable to request tdes irq.\n");
1114                goto tdes_irq_err;
1115        }
1116
1117        /* Initializing the clock */
1118        tdes_dd->iclk = clk_get(&pdev->dev, NULL);
1119        if (IS_ERR(tdes_dd->iclk)) {
1120                dev_err(dev, "clock intialization failed.\n");
1121                err = PTR_ERR(tdes_dd->iclk);
1122                goto clk_err;
1123        }
1124
1125        tdes_dd->io_base = ioremap(tdes_dd->phys_base, tdes_phys_size);
1126        if (!tdes_dd->io_base) {
1127                dev_err(dev, "can't ioremap\n");
1128                err = -ENOMEM;
1129                goto tdes_io_err;
1130        }
1131
1132        err = atmel_tdes_dma_init(tdes_dd);
1133        if (err)
1134                goto err_tdes_dma;
1135
1136        spin_lock(&atmel_tdes.lock);
1137        list_add_tail(&tdes_dd->list, &atmel_tdes.dev_list);
1138        spin_unlock(&atmel_tdes.lock);
1139
1140        err = atmel_tdes_register_algs(tdes_dd);
1141        if (err)
1142                goto err_algs;
1143
1144        dev_info(dev, "Atmel DES/TDES\n");
1145
1146        return 0;
1147
1148err_algs:
1149        spin_lock(&atmel_tdes.lock);
1150        list_del(&tdes_dd->list);
1151        spin_unlock(&atmel_tdes.lock);
1152        atmel_tdes_dma_cleanup(tdes_dd);
1153err_tdes_dma:
1154        iounmap(tdes_dd->io_base);
1155tdes_io_err:
1156        clk_put(tdes_dd->iclk);
1157clk_err:
1158        free_irq(tdes_dd->irq, tdes_dd);
1159tdes_irq_err:
1160res_err:
1161        tasklet_kill(&tdes_dd->done_task);
1162        tasklet_kill(&tdes_dd->queue_task);
1163        kfree(tdes_dd);
1164        tdes_dd = NULL;
1165tdes_dd_err:
1166        dev_err(dev, "initialization failed.\n");
1167
1168        return err;
1169}
1170
1171static int __devexit atmel_tdes_remove(struct platform_device *pdev)
1172{
1173        static struct atmel_tdes_dev *tdes_dd;
1174
1175        tdes_dd = platform_get_drvdata(pdev);
1176        if (!tdes_dd)
1177                return -ENODEV;
1178        spin_lock(&atmel_tdes.lock);
1179        list_del(&tdes_dd->list);
1180        spin_unlock(&atmel_tdes.lock);
1181
1182        atmel_tdes_unregister_algs(tdes_dd);
1183
1184        tasklet_kill(&tdes_dd->done_task);
1185        tasklet_kill(&tdes_dd->queue_task);
1186
1187        atmel_tdes_dma_cleanup(tdes_dd);
1188
1189        iounmap(tdes_dd->io_base);
1190
1191        clk_put(tdes_dd->iclk);
1192
1193        if (tdes_dd->irq >= 0)
1194                free_irq(tdes_dd->irq, tdes_dd);
1195
1196        kfree(tdes_dd);
1197        tdes_dd = NULL;
1198
1199        return 0;
1200}
1201
1202static struct platform_driver atmel_tdes_driver = {
1203        .probe          = atmel_tdes_probe,
1204        .remove         = __devexit_p(atmel_tdes_remove),
1205        .driver         = {
1206                .name   = "atmel_tdes",
1207                .owner  = THIS_MODULE,
1208        },
1209};
1210
1211module_platform_driver(atmel_tdes_driver);
1212
1213MODULE_DESCRIPTION("Atmel DES/TDES hw acceleration support.");
1214MODULE_LICENSE("GPL v2");
1215MODULE_AUTHOR("Nicolas Royer - Eukréa Electromatique");
1216
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.