linux/drivers/crypto/omap-aes.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * Support for OMAP AES HW acceleration.
   5 *
   6 * Copyright (c) 2010 Nokia Corporation
   7 * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
   8 * Copyright (c) 2011 Texas Instruments Incorporated
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as published
  12 * by the Free Software Foundation.
  13 *
  14 */
  15
  16#define pr_fmt(fmt) "%20s: " fmt, __func__
  17#define prn(num) pr_debug(#num "=%d\n", num)
  18#define prx(num) pr_debug(#num "=%x\n", num)
  19
  20#include <linux/err.h>
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/errno.h>
  24#include <linux/kernel.h>
  25#include <linux/platform_device.h>
  26#include <linux/scatterlist.h>
  27#include <linux/dma-mapping.h>
  28#include <linux/dmaengine.h>
  29#include <linux/pm_runtime.h>
  30#include <linux/of.h>
  31#include <linux/of_device.h>
  32#include <linux/of_address.h>
  33#include <linux/io.h>
  34#include <linux/crypto.h>
  35#include <linux/interrupt.h>
  36#include <crypto/scatterwalk.h>
  37#include <crypto/aes.h>
  38#include <crypto/algapi.h>
  39
  40#define DST_MAXBURST                    4
  41#define DMA_MIN                         (DST_MAXBURST * sizeof(u32))
  42
  43#define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset)
  44
  45/* OMAP TRM gives bitfields as start:end, where start is the higher bit
  46   number. For example 7:0 */
  47#define FLD_MASK(start, end)    (((1 << ((start) - (end) + 1)) - 1) << (end))
  48#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
  49
  50#define AES_REG_KEY(dd, x)              ((dd)->pdata->key_ofs - \
  51                                                ((x ^ 0x01) * 0x04))
  52#define AES_REG_IV(dd, x)               ((dd)->pdata->iv_ofs + ((x) * 0x04))
  53
  54#define AES_REG_CTRL(dd)                ((dd)->pdata->ctrl_ofs)
  55#define AES_REG_CTRL_CTR_WIDTH_MASK     GENMASK(8, 7)
  56#define AES_REG_CTRL_CTR_WIDTH_32       0
  57#define AES_REG_CTRL_CTR_WIDTH_64       BIT(7)
  58#define AES_REG_CTRL_CTR_WIDTH_96       BIT(8)
  59#define AES_REG_CTRL_CTR_WIDTH_128      GENMASK(8, 7)
  60#define AES_REG_CTRL_CTR                BIT(6)
  61#define AES_REG_CTRL_CBC                BIT(5)
  62#define AES_REG_CTRL_KEY_SIZE           GENMASK(4, 3)
  63#define AES_REG_CTRL_DIRECTION          BIT(2)
  64#define AES_REG_CTRL_INPUT_READY        BIT(1)
  65#define AES_REG_CTRL_OUTPUT_READY       BIT(0)
  66#define AES_REG_CTRL_MASK               GENMASK(24, 2)
  67
  68#define AES_REG_DATA_N(dd, x)           ((dd)->pdata->data_ofs + ((x) * 0x04))
  69
  70#define AES_REG_REV(dd)                 ((dd)->pdata->rev_ofs)
  71
  72#define AES_REG_MASK(dd)                ((dd)->pdata->mask_ofs)
  73#define AES_REG_MASK_SIDLE              BIT(6)
  74#define AES_REG_MASK_START              BIT(5)
  75#define AES_REG_MASK_DMA_OUT_EN         BIT(3)
  76#define AES_REG_MASK_DMA_IN_EN          BIT(2)
  77#define AES_REG_MASK_SOFTRESET          BIT(1)
  78#define AES_REG_AUTOIDLE                BIT(0)
  79
  80#define AES_REG_LENGTH_N(x)             (0x54 + ((x) * 0x04))
  81
  82#define AES_REG_IRQ_STATUS(dd)         ((dd)->pdata->irq_status_ofs)
  83#define AES_REG_IRQ_ENABLE(dd)         ((dd)->pdata->irq_enable_ofs)
  84#define AES_REG_IRQ_DATA_IN            BIT(1)
  85#define AES_REG_IRQ_DATA_OUT           BIT(2)
  86#define DEFAULT_TIMEOUT         (5*HZ)
  87
  88#define FLAGS_MODE_MASK         0x000f
  89#define FLAGS_ENCRYPT           BIT(0)
  90#define FLAGS_CBC               BIT(1)
  91#define FLAGS_GIV               BIT(2)
  92#define FLAGS_CTR               BIT(3)
  93
  94#define FLAGS_INIT              BIT(4)
  95#define FLAGS_FAST              BIT(5)
  96#define FLAGS_BUSY              BIT(6)
  97
  98#define AES_BLOCK_WORDS         (AES_BLOCK_SIZE >> 2)
  99
 100struct omap_aes_ctx {
 101        struct omap_aes_dev *dd;
 102
 103        int             keylen;
 104        u32             key[AES_KEYSIZE_256 / sizeof(u32)];
 105        unsigned long   flags;
 106};
 107
 108struct omap_aes_reqctx {
 109        unsigned long mode;
 110};
 111
 112#define OMAP_AES_QUEUE_LENGTH   1
 113#define OMAP_AES_CACHE_SIZE     0
 114
 115struct omap_aes_algs_info {
 116        struct crypto_alg       *algs_list;
 117        unsigned int            size;
 118        unsigned int            registered;
 119};
 120
 121struct omap_aes_pdata {
 122        struct omap_aes_algs_info       *algs_info;
 123        unsigned int    algs_info_size;
 124
 125        void            (*trigger)(struct omap_aes_dev *dd, int length);
 126
 127        u32             key_ofs;
 128        u32             iv_ofs;
 129        u32             ctrl_ofs;
 130        u32             data_ofs;
 131        u32             rev_ofs;
 132        u32             mask_ofs;
 133        u32             irq_enable_ofs;
 134        u32             irq_status_ofs;
 135
 136        u32             dma_enable_in;
 137        u32             dma_enable_out;
 138        u32             dma_start;
 139
 140        u32             major_mask;
 141        u32             major_shift;
 142        u32             minor_mask;
 143        u32             minor_shift;
 144};
 145
 146struct omap_aes_dev {
 147        struct list_head        list;
 148        unsigned long           phys_base;
 149        void __iomem            *io_base;
 150        struct omap_aes_ctx     *ctx;
 151        struct device           *dev;
 152        unsigned long           flags;
 153        int                     err;
 154
 155        struct tasklet_struct   done_task;
 156
 157        struct ablkcipher_request       *req;
 158        struct crypto_engine            *engine;
 159
 160        /*
 161         * total is used by PIO mode for book keeping so introduce
 162         * variable total_save as need it to calc page_order
 163         */
 164        size_t                          total;
 165        size_t                          total_save;
 166
 167        struct scatterlist              *in_sg;
 168        struct scatterlist              *out_sg;
 169
 170        /* Buffers for copying for unaligned cases */
 171        struct scatterlist              in_sgl;
 172        struct scatterlist              out_sgl;
 173        struct scatterlist              *orig_out;
 174        int                             sgs_copied;
 175
 176        struct scatter_walk             in_walk;
 177        struct scatter_walk             out_walk;
 178        struct dma_chan         *dma_lch_in;
 179        struct dma_chan         *dma_lch_out;
 180        int                     in_sg_len;
 181        int                     out_sg_len;
 182        int                     pio_only;
 183        const struct omap_aes_pdata     *pdata;
 184};
 185
 186/* keep registered devices data here */
 187static LIST_HEAD(dev_list);
 188static DEFINE_SPINLOCK(list_lock);
 189
 190#ifdef DEBUG
 191#define omap_aes_read(dd, offset)                               \
 192({                                                              \
 193        int _read_ret;                                          \
 194        _read_ret = __raw_readl(dd->io_base + offset);          \
 195        pr_debug("omap_aes_read(" #offset "=%#x)= %#x\n",       \
 196                 offset, _read_ret);                            \
 197        _read_ret;                                              \
 198})
 199#else
 200static inline u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset)
 201{
 202        return __raw_readl(dd->io_base + offset);
 203}
 204#endif
 205
 206#ifdef DEBUG
 207#define omap_aes_write(dd, offset, value)                               \
 208        do {                                                            \
 209                pr_debug("omap_aes_write(" #offset "=%#x) value=%#x\n", \
 210                         offset, value);                                \
 211                __raw_writel(value, dd->io_base + offset);              \
 212        } while (0)
 213#else
 214static inline void omap_aes_write(struct omap_aes_dev *dd, u32 offset,
 215                                  u32 value)
 216{
 217        __raw_writel(value, dd->io_base + offset);
 218}
 219#endif
 220
 221static inline void omap_aes_write_mask(struct omap_aes_dev *dd, u32 offset,
 222                                        u32 value, u32 mask)
 223{
 224        u32 val;
 225
 226        val = omap_aes_read(dd, offset);
 227        val &= ~mask;
 228        val |= value;
 229        omap_aes_write(dd, offset, val);
 230}
 231
 232static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
 233                                        u32 *value, int count)
 234{
 235        for (; count--; value++, offset += 4)
 236                omap_aes_write(dd, offset, *value);
 237}
 238
 239static int omap_aes_hw_init(struct omap_aes_dev *dd)
 240{
 241        if (!(dd->flags & FLAGS_INIT)) {
 242                dd->flags |= FLAGS_INIT;
 243                dd->err = 0;
 244        }
 245
 246        return 0;
 247}
 248
 249static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
 250{
 251        unsigned int key32;
 252        int i, err;
 253        u32 val;
 254
 255        err = omap_aes_hw_init(dd);
 256        if (err)
 257                return err;
 258
 259        key32 = dd->ctx->keylen / sizeof(u32);
 260
 261        /* it seems a key should always be set even if it has not changed */
 262        for (i = 0; i < key32; i++) {
 263                omap_aes_write(dd, AES_REG_KEY(dd, i),
 264                        __le32_to_cpu(dd->ctx->key[i]));
 265        }
 266
 267        if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->info)
 268                omap_aes_write_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);
 269
 270        val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
 271        if (dd->flags & FLAGS_CBC)
 272                val |= AES_REG_CTRL_CBC;
 273        if (dd->flags & FLAGS_CTR)
 274                val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
 275
 276        if (dd->flags & FLAGS_ENCRYPT)
 277                val |= AES_REG_CTRL_DIRECTION;
 278
 279        omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, AES_REG_CTRL_MASK);
 280
 281        return 0;
 282}
 283
 284static void omap_aes_dma_trigger_omap2(struct omap_aes_dev *dd, int length)
 285{
 286        u32 mask, val;
 287
 288        val = dd->pdata->dma_start;
 289
 290        if (dd->dma_lch_out != NULL)
 291                val |= dd->pdata->dma_enable_out;
 292        if (dd->dma_lch_in != NULL)
 293                val |= dd->pdata->dma_enable_in;
 294
 295        mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
 296               dd->pdata->dma_start;
 297
 298        omap_aes_write_mask(dd, AES_REG_MASK(dd), val, mask);
 299
 300}
 301
 302static void omap_aes_dma_trigger_omap4(struct omap_aes_dev *dd, int length)
 303{
 304        omap_aes_write(dd, AES_REG_LENGTH_N(0), length);
 305        omap_aes_write(dd, AES_REG_LENGTH_N(1), 0);
 306
 307        omap_aes_dma_trigger_omap2(dd, length);
 308}
 309
 310static void omap_aes_dma_stop(struct omap_aes_dev *dd)
 311{
 312        u32 mask;
 313
 314        mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
 315               dd->pdata->dma_start;
 316
 317        omap_aes_write_mask(dd, AES_REG_MASK(dd), 0, mask);
 318}
 319
 320static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
 321{
 322        struct omap_aes_dev *dd = NULL, *tmp;
 323
 324        spin_lock_bh(&list_lock);
 325        if (!ctx->dd) {
 326                list_for_each_entry(tmp, &dev_list, list) {
 327                        /* FIXME: take fist available aes core */
 328                        dd = tmp;
 329                        break;
 330                }
 331                ctx->dd = dd;
 332        } else {
 333                /* already found before */
 334                dd = ctx->dd;
 335        }
 336        spin_unlock_bh(&list_lock);
 337
 338        return dd;
 339}
 340
 341static void omap_aes_dma_out_callback(void *data)
 342{
 343        struct omap_aes_dev *dd = data;
 344
 345        /* dma_lch_out - completed */
 346        tasklet_schedule(&dd->done_task);
 347}
 348
 349static int omap_aes_dma_init(struct omap_aes_dev *dd)
 350{
 351        int err;
 352
 353        dd->dma_lch_out = NULL;
 354        dd->dma_lch_in = NULL;
 355
 356        dd->dma_lch_in = dma_request_chan(dd->dev, "rx");
 357        if (IS_ERR(dd->dma_lch_in)) {
 358                dev_err(dd->dev, "Unable to request in DMA channel\n");
 359                return PTR_ERR(dd->dma_lch_in);
 360        }
 361
 362        dd->dma_lch_out = dma_request_chan(dd->dev, "tx");
 363        if (IS_ERR(dd->dma_lch_out)) {
 364                dev_err(dd->dev, "Unable to request out DMA channel\n");
 365                err = PTR_ERR(dd->dma_lch_out);
 366                goto err_dma_out;
 367        }
 368
 369        return 0;
 370
 371err_dma_out:
 372        dma_release_channel(dd->dma_lch_in);
 373
 374        return err;
 375}
 376
 377static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
 378{
 379        if (dd->pio_only)
 380                return;
 381
 382        dma_release_channel(dd->dma_lch_out);
 383        dma_release_channel(dd->dma_lch_in);
 384}
 385
 386static void sg_copy_buf(void *buf, struct scatterlist *sg,
 387                              unsigned int start, unsigned int nbytes, int out)
 388{
 389        struct scatter_walk walk;
 390
 391        if (!nbytes)
 392                return;
 393
 394        scatterwalk_start(&walk, sg);
 395        scatterwalk_advance(&walk, start);
 396        scatterwalk_copychunks(buf, &walk, nbytes, out);
 397        scatterwalk_done(&walk, out, 0);
 398}
 399
 400static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
 401                struct scatterlist *in_sg, struct scatterlist *out_sg,
 402                int in_sg_len, int out_sg_len)
 403{
 404        struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
 405        struct omap_aes_dev *dd = ctx->dd;
 406        struct dma_async_tx_descriptor *tx_in, *tx_out;
 407        struct dma_slave_config cfg;
 408        int ret;
 409
 410        if (dd->pio_only) {
 411                scatterwalk_start(&dd->in_walk, dd->in_sg);
 412                scatterwalk_start(&dd->out_walk, dd->out_sg);
 413
 414                /* Enable DATAIN interrupt and let it take
 415                   care of the rest */
 416                omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
 417                return 0;
 418        }
 419
 420        dma_sync_sg_for_device(dd->dev, dd->in_sg, in_sg_len, DMA_TO_DEVICE);
 421
 422        memset(&cfg, 0, sizeof(cfg));
 423
 424        cfg.src_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
 425        cfg.dst_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
 426        cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 427        cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 428        cfg.src_maxburst = DST_MAXBURST;
 429        cfg.dst_maxburst = DST_MAXBURST;
 430
 431        /* IN */
 432        ret = dmaengine_slave_config(dd->dma_lch_in, &cfg);
 433        if (ret) {
 434                dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
 435                        ret);
 436                return ret;
 437        }
 438
 439        tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, in_sg_len,
 440                                        DMA_MEM_TO_DEV,
 441                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 442        if (!tx_in) {
 443                dev_err(dd->dev, "IN prep_slave_sg() failed\n");
 444                return -EINVAL;
 445        }
 446
 447        /* No callback necessary */
 448        tx_in->callback_param = dd;
 449
 450        /* OUT */
 451        ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
 452        if (ret) {
 453                dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
 454                        ret);
 455                return ret;
 456        }
 457
 458        tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len,
 459                                        DMA_DEV_TO_MEM,
 460                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 461        if (!tx_out) {
 462                dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
 463                return -EINVAL;
 464        }
 465
 466        tx_out->callback = omap_aes_dma_out_callback;
 467        tx_out->callback_param = dd;
 468
 469        dmaengine_submit(tx_in);
 470        dmaengine_submit(tx_out);
 471
 472        dma_async_issue_pending(dd->dma_lch_in);
 473        dma_async_issue_pending(dd->dma_lch_out);
 474
 475        /* start DMA */
 476        dd->pdata->trigger(dd, dd->total);
 477
 478        return 0;
 479}
 480
 481static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
 482{
 483        struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
 484                                        crypto_ablkcipher_reqtfm(dd->req));
 485        int err;
 486
 487        pr_debug("total: %d\n", dd->total);
 488
 489        if (!dd->pio_only) {
 490                err = dma_map_sg(dd->dev, dd->in_sg, dd->in_sg_len,
 491                                 DMA_TO_DEVICE);
 492                if (!err) {
 493                        dev_err(dd->dev, "dma_map_sg() error\n");
 494                        return -EINVAL;
 495                }
 496
 497                err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 498                                 DMA_FROM_DEVICE);
 499                if (!err) {
 500                        dev_err(dd->dev, "dma_map_sg() error\n");
 501                        return -EINVAL;
 502                }
 503        }
 504
 505        err = omap_aes_crypt_dma(tfm, dd->in_sg, dd->out_sg, dd->in_sg_len,
 506                                 dd->out_sg_len);
 507        if (err && !dd->pio_only) {
 508                dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
 509                dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 510                             DMA_FROM_DEVICE);
 511        }
 512
 513        return err;
 514}
 515
 516static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
 517{
 518        struct ablkcipher_request *req = dd->req;
 519
 520        pr_debug("err: %d\n", err);
 521
 522        crypto_finalize_request(dd->engine, req, err);
 523}
 524
 525static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
 526{
 527        pr_debug("total: %d\n", dd->total);
 528
 529        omap_aes_dma_stop(dd);
 530
 531        dmaengine_terminate_all(dd->dma_lch_in);
 532        dmaengine_terminate_all(dd->dma_lch_out);
 533
 534        return 0;
 535}
 536
 537static int omap_aes_check_aligned(struct scatterlist *sg, int total)
 538{
 539        int len = 0;
 540
 541        if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
 542                return -EINVAL;
 543
 544        while (sg) {
 545                if (!IS_ALIGNED(sg->offset, 4))
 546                        return -1;
 547                if (!IS_ALIGNED(sg->length, AES_BLOCK_SIZE))
 548                        return -1;
 549
 550                len += sg->length;
 551                sg = sg_next(sg);
 552        }
 553
 554        if (len != total)
 555                return -1;
 556
 557        return 0;
 558}
 559
 560static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
 561{
 562        void *buf_in, *buf_out;
 563        int pages, total;
 564
 565        total = ALIGN(dd->total, AES_BLOCK_SIZE);
 566        pages = get_order(total);
 567
 568        buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
 569        buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);
 570
 571        if (!buf_in || !buf_out) {
 572                pr_err("Couldn't allocated pages for unaligned cases.\n");
 573                return -1;
 574        }
 575
 576        dd->orig_out = dd->out_sg;
 577
 578        sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0);
 579
 580        sg_init_table(&dd->in_sgl, 1);
 581        sg_set_buf(&dd->in_sgl, buf_in, total);
 582        dd->in_sg = &dd->in_sgl;
 583
 584        sg_init_table(&dd->out_sgl, 1);
 585        sg_set_buf(&dd->out_sgl, buf_out, total);
 586        dd->out_sg = &dd->out_sgl;
 587
 588        return 0;
 589}
 590
 591static int omap_aes_handle_queue(struct omap_aes_dev *dd,
 592                                 struct ablkcipher_request *req)
 593{
 594        if (req)
 595                return crypto_transfer_request_to_engine(dd->engine, req);
 596
 597        return 0;
 598}
 599
 600static int omap_aes_prepare_req(struct crypto_engine *engine,
 601                                struct ablkcipher_request *req)
 602{
 603        struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
 604                        crypto_ablkcipher_reqtfm(req));
 605        struct omap_aes_dev *dd = omap_aes_find_dev(ctx);
 606        struct omap_aes_reqctx *rctx;
 607        int len;
 608
 609        if (!dd)
 610                return -ENODEV;
 611
 612        /* assign new request to device */
 613        dd->req = req;
 614        dd->total = req->nbytes;
 615        dd->total_save = req->nbytes;
 616        dd->in_sg = req->src;
 617        dd->out_sg = req->dst;
 618
 619        if (omap_aes_check_aligned(dd->in_sg, dd->total) ||
 620            omap_aes_check_aligned(dd->out_sg, dd->total)) {
 621                if (omap_aes_copy_sgs(dd))
 622                        pr_err("Failed to copy SGs for unaligned cases\n");
 623                dd->sgs_copied = 1;
 624        } else {
 625                dd->sgs_copied = 0;
 626        }
 627
 628        len = ALIGN(dd->total, AES_BLOCK_SIZE);
 629        dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, len);
 630        dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, len);
 631        BUG_ON(dd->in_sg_len < 0 || dd->out_sg_len < 0);
 632
 633        rctx = ablkcipher_request_ctx(req);
 634        ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
 635        rctx->mode &= FLAGS_MODE_MASK;
 636        dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
 637
 638        dd->ctx = ctx;
 639        ctx->dd = dd;
 640
 641        return omap_aes_write_ctrl(dd);
 642}
 643
 644static int omap_aes_crypt_req(struct crypto_engine *engine,
 645                              struct ablkcipher_request *req)
 646{
 647        struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
 648                        crypto_ablkcipher_reqtfm(req));
 649        struct omap_aes_dev *dd = omap_aes_find_dev(ctx);
 650
 651        if (!dd)
 652                return -ENODEV;
 653
 654        return omap_aes_crypt_dma_start(dd);
 655}
 656
 657static void omap_aes_done_task(unsigned long data)
 658{
 659        struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
 660        void *buf_in, *buf_out;
 661        int pages, len;
 662
 663        pr_debug("enter done_task\n");
 664
 665        if (!dd->pio_only) {
 666                dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len,
 667                                       DMA_FROM_DEVICE);
 668                dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
 669                dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 670                             DMA_FROM_DEVICE);
 671                omap_aes_crypt_dma_stop(dd);
 672        }
 673
 674        if (dd->sgs_copied) {
 675                buf_in = sg_virt(&dd->in_sgl);
 676                buf_out = sg_virt(&dd->out_sgl);
 677
 678                sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1);
 679
 680                len = ALIGN(dd->total_save, AES_BLOCK_SIZE);
 681                pages = get_order(len);
 682                free_pages((unsigned long)buf_in, pages);
 683                free_pages((unsigned long)buf_out, pages);
 684        }
 685
 686        omap_aes_finish_req(dd, 0);
 687
 688        pr_debug("exit\n");
 689}
 690
 691static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
 692{
 693        struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
 694                        crypto_ablkcipher_reqtfm(req));
 695        struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
 696        struct omap_aes_dev *dd;
 697
 698        pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
 699                  !!(mode & FLAGS_ENCRYPT),
 700                  !!(mode & FLAGS_CBC));
 701
 702        dd = omap_aes_find_dev(ctx);
 703        if (!dd)
 704                return -ENODEV;
 705
 706        rctx->mode = mode;
 707
 708        return omap_aes_handle_queue(dd, req);
 709}
 710
 711/* ********************** ALG API ************************************ */
 712
 713static int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
 714                           unsigned int keylen)
 715{
 716        struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 717
 718        if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
 719                   keylen != AES_KEYSIZE_256)
 720                return -EINVAL;
 721
 722        pr_debug("enter, keylen: %d\n", keylen);
 723
 724        memcpy(ctx->key, key, keylen);
 725        ctx->keylen = keylen;
 726
 727        return 0;
 728}
 729
 730static int omap_aes_ecb_encrypt(struct ablkcipher_request *req)
 731{
 732        return omap_aes_crypt(req, FLAGS_ENCRYPT);
 733}
 734
 735static int omap_aes_ecb_decrypt(struct ablkcipher_request *req)
 736{
 737        return omap_aes_crypt(req, 0);
 738}
 739
 740static int omap_aes_cbc_encrypt(struct ablkcipher_request *req)
 741{
 742        return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
 743}
 744
 745static int omap_aes_cbc_decrypt(struct ablkcipher_request *req)
 746{
 747        return omap_aes_crypt(req, FLAGS_CBC);
 748}
 749
 750static int omap_aes_ctr_encrypt(struct ablkcipher_request *req)
 751{
 752        return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CTR);
 753}
 754
 755static int omap_aes_ctr_decrypt(struct ablkcipher_request *req)
 756{
 757        return omap_aes_crypt(req, FLAGS_CTR);
 758}
 759
 760static int omap_aes_cra_init(struct crypto_tfm *tfm)
 761{
 762        struct omap_aes_dev *dd = NULL;
 763        int err;
 764
 765        /* Find AES device, currently picks the first device */
 766        spin_lock_bh(&list_lock);
 767        list_for_each_entry(dd, &dev_list, list) {
 768                break;
 769        }
 770        spin_unlock_bh(&list_lock);
 771
 772        err = pm_runtime_get_sync(dd->dev);
 773        if (err < 0) {
 774                dev_err(dd->dev, "%s: failed to get_sync(%d)\n",
 775                        __func__, err);
 776                return err;
 777        }
 778
 779        tfm->crt_ablkcipher.reqsize = sizeof(struct omap_aes_reqctx);
 780
 781        return 0;
 782}
 783
 784static void omap_aes_cra_exit(struct crypto_tfm *tfm)
 785{
 786        struct omap_aes_dev *dd = NULL;
 787
 788        /* Find AES device, currently picks the first device */
 789        spin_lock_bh(&list_lock);
 790        list_for_each_entry(dd, &dev_list, list) {
 791                break;
 792        }
 793        spin_unlock_bh(&list_lock);
 794
 795        pm_runtime_put_sync(dd->dev);
 796}
 797
 798/* ********************** ALGS ************************************ */
 799
 800static struct crypto_alg algs_ecb_cbc[] = {
 801{
 802        .cra_name               = "ecb(aes)",
 803        .cra_driver_name        = "ecb-aes-omap",
 804        .cra_priority           = 300,
 805        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 806                                  CRYPTO_ALG_KERN_DRIVER_ONLY |
 807                                  CRYPTO_ALG_ASYNC,
 808        .cra_blocksize          = AES_BLOCK_SIZE,
 809        .cra_ctxsize            = sizeof(struct omap_aes_ctx),
 810        .cra_alignmask          = 0,
 811        .cra_type               = &crypto_ablkcipher_type,
 812        .cra_module             = THIS_MODULE,
 813        .cra_init               = omap_aes_cra_init,
 814        .cra_exit               = omap_aes_cra_exit,
 815        .cra_u.ablkcipher = {
 816                .min_keysize    = AES_MIN_KEY_SIZE,
 817                .max_keysize    = AES_MAX_KEY_SIZE,
 818                .setkey         = omap_aes_setkey,
 819                .encrypt        = omap_aes_ecb_encrypt,
 820                .decrypt        = omap_aes_ecb_decrypt,
 821        }
 822},
 823{
 824        .cra_name               = "cbc(aes)",
 825        .cra_driver_name        = "cbc-aes-omap",
 826        .cra_priority           = 300,
 827        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 828                                  CRYPTO_ALG_KERN_DRIVER_ONLY |
 829                                  CRYPTO_ALG_ASYNC,
 830        .cra_blocksize          = AES_BLOCK_SIZE,
 831        .cra_ctxsize            = sizeof(struct omap_aes_ctx),
 832        .cra_alignmask          = 0,
 833        .cra_type               = &crypto_ablkcipher_type,
 834        .cra_module             = THIS_MODULE,
 835        .cra_init               = omap_aes_cra_init,
 836        .cra_exit               = omap_aes_cra_exit,
 837        .cra_u.ablkcipher = {
 838                .min_keysize    = AES_MIN_KEY_SIZE,
 839                .max_keysize    = AES_MAX_KEY_SIZE,
 840                .ivsize         = AES_BLOCK_SIZE,
 841                .setkey         = omap_aes_setkey,
 842                .encrypt        = omap_aes_cbc_encrypt,
 843                .decrypt        = omap_aes_cbc_decrypt,
 844        }
 845}
 846};
 847
 848static struct crypto_alg algs_ctr[] = {
 849{
 850        .cra_name               = "ctr(aes)",
 851        .cra_driver_name        = "ctr-aes-omap",
 852        .cra_priority           = 300,
 853        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 854                                  CRYPTO_ALG_KERN_DRIVER_ONLY |
 855                                  CRYPTO_ALG_ASYNC,
 856        .cra_blocksize          = AES_BLOCK_SIZE,
 857        .cra_ctxsize            = sizeof(struct omap_aes_ctx),
 858        .cra_alignmask          = 0,
 859        .cra_type               = &crypto_ablkcipher_type,
 860        .cra_module             = THIS_MODULE,
 861        .cra_init               = omap_aes_cra_init,
 862        .cra_exit               = omap_aes_cra_exit,
 863        .cra_u.ablkcipher = {
 864                .min_keysize    = AES_MIN_KEY_SIZE,
 865                .max_keysize    = AES_MAX_KEY_SIZE,
 866                .geniv          = "eseqiv",
 867                .ivsize         = AES_BLOCK_SIZE,
 868                .setkey         = omap_aes_setkey,
 869                .encrypt        = omap_aes_ctr_encrypt,
 870                .decrypt        = omap_aes_ctr_decrypt,
 871        }
 872} ,
 873};
 874
 875static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc[] = {
 876        {
 877                .algs_list      = algs_ecb_cbc,
 878                .size           = ARRAY_SIZE(algs_ecb_cbc),
 879        },
 880};
 881
 882static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
 883        .algs_info      = omap_aes_algs_info_ecb_cbc,
 884        .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc),
 885        .trigger        = omap_aes_dma_trigger_omap2,
 886        .key_ofs        = 0x1c,
 887        .iv_ofs         = 0x20,
 888        .ctrl_ofs       = 0x30,
 889        .data_ofs       = 0x34,
 890        .rev_ofs        = 0x44,
 891        .mask_ofs       = 0x48,
 892        .dma_enable_in  = BIT(2),
 893        .dma_enable_out = BIT(3),
 894        .dma_start      = BIT(5),
 895        .major_mask     = 0xf0,
 896        .major_shift    = 4,
 897        .minor_mask     = 0x0f,
 898        .minor_shift    = 0,
 899};
 900
 901#ifdef CONFIG_OF
 902static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc_ctr[] = {
 903        {
 904                .algs_list      = algs_ecb_cbc,
 905                .size           = ARRAY_SIZE(algs_ecb_cbc),
 906        },
 907        {
 908                .algs_list      = algs_ctr,
 909                .size           = ARRAY_SIZE(algs_ctr),
 910        },
 911};
 912
 913static const struct omap_aes_pdata omap_aes_pdata_omap3 = {
 914        .algs_info      = omap_aes_algs_info_ecb_cbc_ctr,
 915        .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
 916        .trigger        = omap_aes_dma_trigger_omap2,
 917        .key_ofs        = 0x1c,
 918        .iv_ofs         = 0x20,
 919        .ctrl_ofs       = 0x30,
 920        .data_ofs       = 0x34,
 921        .rev_ofs        = 0x44,
 922        .mask_ofs       = 0x48,
 923        .dma_enable_in  = BIT(2),
 924        .dma_enable_out = BIT(3),
 925        .dma_start      = BIT(5),
 926        .major_mask     = 0xf0,
 927        .major_shift    = 4,
 928        .minor_mask     = 0x0f,
 929        .minor_shift    = 0,
 930};
 931
 932static const struct omap_aes_pdata omap_aes_pdata_omap4 = {
 933        .algs_info      = omap_aes_algs_info_ecb_cbc_ctr,
 934        .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
 935        .trigger        = omap_aes_dma_trigger_omap4,
 936        .key_ofs        = 0x3c,
 937        .iv_ofs         = 0x40,
 938        .ctrl_ofs       = 0x50,
 939        .data_ofs       = 0x60,
 940        .rev_ofs        = 0x80,
 941        .mask_ofs       = 0x84,
 942        .irq_status_ofs = 0x8c,
 943        .irq_enable_ofs = 0x90,
 944        .dma_enable_in  = BIT(5),
 945        .dma_enable_out = BIT(6),
 946        .major_mask     = 0x0700,
 947        .major_shift    = 8,
 948        .minor_mask     = 0x003f,
 949        .minor_shift    = 0,
 950};
 951
 952static irqreturn_t omap_aes_irq(int irq, void *dev_id)
 953{
 954        struct omap_aes_dev *dd = dev_id;
 955        u32 status, i;
 956        u32 *src, *dst;
 957
 958        status = omap_aes_read(dd, AES_REG_IRQ_STATUS(dd));
 959        if (status & AES_REG_IRQ_DATA_IN) {
 960                omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
 961
 962                BUG_ON(!dd->in_sg);
 963
 964                BUG_ON(_calc_walked(in) > dd->in_sg->length);
 965
 966                src = sg_virt(dd->in_sg) + _calc_walked(in);
 967
 968                for (i = 0; i < AES_BLOCK_WORDS; i++) {
 969                        omap_aes_write(dd, AES_REG_DATA_N(dd, i), *src);
 970
 971                        scatterwalk_advance(&dd->in_walk, 4);
 972                        if (dd->in_sg->length == _calc_walked(in)) {
 973                                dd->in_sg = sg_next(dd->in_sg);
 974                                if (dd->in_sg) {
 975                                        scatterwalk_start(&dd->in_walk,
 976                                                          dd->in_sg);
 977                                        src = sg_virt(dd->in_sg) +
 978                                              _calc_walked(in);
 979                                }
 980                        } else {
 981                                src++;
 982                        }
 983                }
 984
 985                /* Clear IRQ status */
 986                status &= ~AES_REG_IRQ_DATA_IN;
 987                omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
 988
 989                /* Enable DATA_OUT interrupt */
 990                omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
 991
 992        } else if (status & AES_REG_IRQ_DATA_OUT) {
 993                omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
 994
 995                BUG_ON(!dd->out_sg);
 996
 997                BUG_ON(_calc_walked(out) > dd->out_sg->length);
 998
 999                dst = sg_virt(dd->out_sg) + _calc_walked(out);
1000
1001                for (i = 0; i < AES_BLOCK_WORDS; i++) {
1002                        *dst = omap_aes_read(dd, AES_REG_DATA_N(dd, i));
1003                        scatterwalk_advance(&dd->out_walk, 4);
1004                        if (dd->out_sg->length == _calc_walked(out)) {
1005                                dd->out_sg = sg_next(dd->out_sg);
1006                                if (dd->out_sg) {
1007                                        scatterwalk_start(&dd->out_walk,
1008                                                          dd->out_sg);
1009                                        dst = sg_virt(dd->out_sg) +
1010                                              _calc_walked(out);
1011                                }
1012                        } else {
1013                                dst++;
1014                        }
1015                }
1016
1017                dd->total -= min_t(size_t, AES_BLOCK_SIZE, dd->total);
1018
1019                /* Clear IRQ status */
1020                status &= ~AES_REG_IRQ_DATA_OUT;
1021                omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
1022
1023                if (!dd->total)
1024                        /* All bytes read! */
1025                        tasklet_schedule(&dd->done_task);
1026                else
1027                        /* Enable DATA_IN interrupt for next block */
1028                        omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
1029        }
1030
1031        return IRQ_HANDLED;
1032}
1033
1034static const struct of_device_id omap_aes_of_match[] = {
1035        {
1036                .compatible     = "ti,omap2-aes",
1037                .data           = &omap_aes_pdata_omap2,
1038        },
1039        {
1040                .compatible     = "ti,omap3-aes",
1041                .data           = &omap_aes_pdata_omap3,
1042        },
1043        {
1044                .compatible     = "ti,omap4-aes",
1045                .data           = &omap_aes_pdata_omap4,
1046        },
1047        {},
1048};
1049MODULE_DEVICE_TABLE(of, omap_aes_of_match);
1050
1051static int omap_aes_get_res_of(struct omap_aes_dev *dd,
1052                struct device *dev, struct resource *res)
1053{
1054        struct device_node *node = dev->of_node;
1055        const struct of_device_id *match;
1056        int err = 0;
1057
1058        match = of_match_device(of_match_ptr(omap_aes_of_match), dev);
1059        if (!match) {
1060                dev_err(dev, "no compatible OF match\n");
1061                err = -EINVAL;
1062                goto err;
1063        }
1064
1065        err = of_address_to_resource(node, 0, res);
1066        if (err < 0) {
1067                dev_err(dev, "can't translate OF node address\n");
1068                err = -EINVAL;
1069                goto err;
1070        }
1071
1072        dd->pdata = match->data;
1073
1074err:
1075        return err;
1076}
1077#else
1078static const struct of_device_id omap_aes_of_match[] = {
1079        {},
1080};
1081
1082static int omap_aes_get_res_of(struct omap_aes_dev *dd,
1083                struct device *dev, struct resource *res)
1084{
1085        return -EINVAL;
1086}
1087#endif
1088
1089static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
1090                struct platform_device *pdev, struct resource *res)
1091{
1092        struct device *dev = &pdev->dev;
1093        struct resource *r;
1094        int err = 0;
1095
1096        /* Get the base address */
1097        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1098        if (!r) {
1099                dev_err(dev, "no MEM resource info\n");
1100                err = -ENODEV;
1101                goto err;
1102        }
1103        memcpy(res, r, sizeof(*res));
1104
1105        /* Only OMAP2/3 can be non-DT */
1106        dd->pdata = &omap_aes_pdata_omap2;
1107
1108err:
1109        return err;
1110}
1111
1112static int omap_aes_probe(struct platform_device *pdev)
1113{
1114        struct device *dev = &pdev->dev;
1115        struct omap_aes_dev *dd;
1116        struct crypto_alg *algp;
1117        struct resource res;
1118        int err = -ENOMEM, i, j, irq = -1;
1119        u32 reg;
1120
1121        dd = devm_kzalloc(dev, sizeof(struct omap_aes_dev), GFP_KERNEL);
1122        if (dd == NULL) {
1123                dev_err(dev, "unable to alloc data struct.\n");
1124                goto err_data;
1125        }
1126        dd->dev = dev;
1127        platform_set_drvdata(pdev, dd);
1128
1129        err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) :
1130                               omap_aes_get_res_pdev(dd, pdev, &res);
1131        if (err)
1132                goto err_res;
1133
1134        dd->io_base = devm_ioremap_resource(dev, &res);
1135        if (IS_ERR(dd->io_base)) {
1136                err = PTR_ERR(dd->io_base);
1137                goto err_res;
1138        }
1139        dd->phys_base = res.start;
1140
1141        pm_runtime_enable(dev);
1142        err = pm_runtime_get_sync(dev);
1143        if (err < 0) {
1144                dev_err(dev, "%s: failed to get_sync(%d)\n",
1145                        __func__, err);
1146                goto err_res;
1147        }
1148
1149        omap_aes_dma_stop(dd);
1150
1151        reg = omap_aes_read(dd, AES_REG_REV(dd));
1152
1153        pm_runtime_put_sync(dev);
1154
1155        dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
1156                 (reg & dd->pdata->major_mask) >> dd->pdata->major_shift,
1157                 (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift);
1158
1159        tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
1160
1161        err = omap_aes_dma_init(dd);
1162        if (err == -EPROBE_DEFER) {
1163                goto err_irq;
1164        } else if (err && AES_REG_IRQ_STATUS(dd) && AES_REG_IRQ_ENABLE(dd)) {
1165                dd->pio_only = 1;
1166
1167                irq = platform_get_irq(pdev, 0);
1168                if (irq < 0) {
1169                        dev_err(dev, "can't get IRQ resource\n");
1170                        goto err_irq;
1171                }
1172
1173                err = devm_request_irq(dev, irq, omap_aes_irq, 0,
1174                                dev_name(dev), dd);
1175                if (err) {
1176                        dev_err(dev, "Unable to grab omap-aes IRQ\n");
1177                        goto err_irq;
1178                }
1179        }
1180
1181
1182        INIT_LIST_HEAD(&dd->list);
1183        spin_lock(&list_lock);
1184        list_add_tail(&dd->list, &dev_list);
1185        spin_unlock(&list_lock);
1186
1187        for (i = 0; i < dd->pdata->algs_info_size; i++) {
1188                for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
1189                        algp = &dd->pdata->algs_info[i].algs_list[j];
1190
1191                        pr_debug("reg alg: %s\n", algp->cra_name);
1192                        INIT_LIST_HEAD(&algp->cra_list);
1193
1194                        err = crypto_register_alg(algp);
1195                        if (err)
1196                                goto err_algs;
1197
1198                        dd->pdata->algs_info[i].registered++;
1199                }
1200        }
1201
1202        /* Initialize crypto engine */
1203        dd->engine = crypto_engine_alloc_init(dev, 1);
1204        if (!dd->engine)
1205                goto err_algs;
1206
1207        dd->engine->prepare_request = omap_aes_prepare_req;
1208        dd->engine->crypt_one_request = omap_aes_crypt_req;
1209        err = crypto_engine_start(dd->engine);
1210        if (err)
1211                goto err_engine;
1212
1213        return 0;
1214err_engine:
1215        crypto_engine_exit(dd->engine);
1216err_algs:
1217        for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1218                for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1219                        crypto_unregister_alg(
1220                                        &dd->pdata->algs_info[i].algs_list[j]);
1221
1222        omap_aes_dma_cleanup(dd);
1223err_irq:
1224        tasklet_kill(&dd->done_task);
1225        pm_runtime_disable(dev);
1226err_res:
1227        dd = NULL;
1228err_data:
1229        dev_err(dev, "initialization failed.\n");
1230        return err;
1231}
1232
1233static int omap_aes_remove(struct platform_device *pdev)
1234{
1235        struct omap_aes_dev *dd = platform_get_drvdata(pdev);
1236        int i, j;
1237
1238        if (!dd)
1239                return -ENODEV;
1240
1241        spin_lock(&list_lock);
1242        list_del(&dd->list);
1243        spin_unlock(&list_lock);
1244
1245        for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1246                for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1247                        crypto_unregister_alg(
1248                                        &dd->pdata->algs_info[i].algs_list[j]);
1249
1250        crypto_engine_exit(dd->engine);
1251        tasklet_kill(&dd->done_task);
1252        omap_aes_dma_cleanup(dd);
1253        pm_runtime_disable(dd->dev);
1254        dd = NULL;
1255
1256        return 0;
1257}
1258
1259#ifdef CONFIG_PM_SLEEP
1260static int omap_aes_suspend(struct device *dev)
1261{
1262        pm_runtime_put_sync(dev);
1263        return 0;
1264}
1265
1266static int omap_aes_resume(struct device *dev)
1267{
1268        pm_runtime_get_sync(dev);
1269        return 0;
1270}
1271#endif
1272
1273static SIMPLE_DEV_PM_OPS(omap_aes_pm_ops, omap_aes_suspend, omap_aes_resume);
1274
1275static struct platform_driver omap_aes_driver = {
1276        .probe  = omap_aes_probe,
1277        .remove = omap_aes_remove,
1278        .driver = {
1279                .name   = "omap-aes",
1280                .pm     = &omap_aes_pm_ops,
1281                .of_match_table = omap_aes_of_match,
1282        },
1283};
1284
1285module_platform_driver(omap_aes_driver);
1286
1287MODULE_DESCRIPTION("OMAP AES hw acceleration support.");
1288MODULE_LICENSE("GPL v2");
1289MODULE_AUTHOR("Dmitry Kasatkin");
1290
1291
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.