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