From: Stephen Rothwell Date: Tue, 19 Feb 2013 23:37:11 +0000 (+1100) Subject: Merge remote-tracking branch 'crypto-current/master' X-Git-Tag: next-20130220~119 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=79409e07f95de645bf328970f6108118f74a0de7;p=karo-tx-linux.git Merge remote-tracking branch 'crypto-current/master' --- 79409e07f95de645bf328970f6108118f74a0de7 diff --cc drivers/crypto/omap-sham.c index 90d34adc2a66,dc2d354219c6..3d1611f5aecf --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@@ -1088,56 -1484,181 +1484,181 @@@ static irqreturn_t omap_sham_irq_omap2( SHA_REG_CTRL_OUTPUT_READY); omap_sham_read(dd, SHA_REG_CTRL); - if (!test_bit(FLAGS_BUSY, &dd->flags)) { - dev_warn(dd->dev, "Interrupt when no active requests.\n"); - return IRQ_HANDLED; - } + return omap_sham_irq_common(dd); + } - set_bit(FLAGS_OUTPUT_READY, &dd->flags); - tasklet_schedule(&dd->done_task); + static irqreturn_t omap_sham_irq_omap4(int irq, void *dev_id) + { + struct omap_sham_dev *dd = dev_id; - return IRQ_HANDLED; + omap_sham_write_mask(dd, SHA_REG_MASK(dd), 0, SHA_REG_MASK_IT_EN); + + return omap_sham_irq_common(dd); } - static void omap_sham_dma_callback(int lch, u16 ch_status, void *data) + static struct omap_sham_algs_info omap_sham_algs_info_omap2[] = { + { + .algs_list = algs_sha1_md5, + .size = ARRAY_SIZE(algs_sha1_md5), + }, + }; + + static const struct omap_sham_pdata omap_sham_pdata_omap2 = { + .algs_info = omap_sham_algs_info_omap2, + .algs_info_size = ARRAY_SIZE(omap_sham_algs_info_omap2), + .flags = BIT(FLAGS_BE32_SHA1), + .digest_size = SHA1_DIGEST_SIZE, + .copy_hash = omap_sham_copy_hash_omap2, + .write_ctrl = omap_sham_write_ctrl_omap2, + .trigger = omap_sham_trigger_omap2, + .poll_irq = omap_sham_poll_irq_omap2, + .intr_hdlr = omap_sham_irq_omap2, + .idigest_ofs = 0x00, + .din_ofs = 0x1c, + .digcnt_ofs = 0x14, + .rev_ofs = 0x5c, + .mask_ofs = 0x60, + .sysstatus_ofs = 0x64, + .major_mask = 0xf0, + .major_shift = 4, + .minor_mask = 0x0f, + .minor_shift = 0, + }; + + #ifdef CONFIG_OF + static struct omap_sham_algs_info omap_sham_algs_info_omap4[] = { + { + .algs_list = algs_sha1_md5, + .size = ARRAY_SIZE(algs_sha1_md5), + }, + { + .algs_list = algs_sha224_sha256, + .size = ARRAY_SIZE(algs_sha224_sha256), + }, + }; + + static const struct omap_sham_pdata omap_sham_pdata_omap4 = { + .algs_info = omap_sham_algs_info_omap4, + .algs_info_size = ARRAY_SIZE(omap_sham_algs_info_omap4), + .flags = BIT(FLAGS_AUTO_XOR), + .digest_size = SHA256_DIGEST_SIZE, + .copy_hash = omap_sham_copy_hash_omap4, + .write_ctrl = omap_sham_write_ctrl_omap4, + .trigger = omap_sham_trigger_omap4, + .poll_irq = omap_sham_poll_irq_omap4, + .intr_hdlr = omap_sham_irq_omap4, + .idigest_ofs = 0x020, + .din_ofs = 0x080, + .digcnt_ofs = 0x040, + .rev_ofs = 0x100, + .mask_ofs = 0x110, + .sysstatus_ofs = 0x114, + .major_mask = 0x0700, + .major_shift = 8, + .minor_mask = 0x003f, + .minor_shift = 0, + }; + + static const struct of_device_id omap_sham_of_match[] = { + { + .compatible = "ti,omap2-sham", + .data = &omap_sham_pdata_omap2, + }, + { + .compatible = "ti,omap4-sham", + .data = &omap_sham_pdata_omap4, + }, + {}, + }; + MODULE_DEVICE_TABLE(of, omap_sham_of_match); + + static int omap_sham_get_res_of(struct omap_sham_dev *dd, + struct device *dev, struct resource *res) { - struct omap_sham_dev *dd = data; + struct device_node *node = dev->of_node; + const struct of_device_id *match; + int err = 0; - if (ch_status != OMAP_DMA_BLOCK_IRQ) { - pr_err("omap-sham DMA error status: 0x%hx\n", ch_status); - dd->err = -EIO; - clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */ + match = of_match_device(of_match_ptr(omap_sham_of_match), dev); + if (!match) { + dev_err(dev, "no compatible OF match\n"); + err = -EINVAL; + goto err; } - set_bit(FLAGS_DMA_READY, &dd->flags); - tasklet_schedule(&dd->done_task); + err = of_address_to_resource(node, 0, res); + if (err < 0) { + dev_err(dev, "can't translate OF node address\n"); + err = -EINVAL; + goto err; + } + + dd->irq = of_irq_to_resource(node, 0, NULL); + if (!dd->irq) { + dev_err(dev, "can't translate OF irq value\n"); + err = -EINVAL; + goto err; + } + + dd->dma = -1; /* Dummy value that's unused */ + dd->pdata = match->data; + + err: + return err; } + #else + static const struct of_device_id omap_sham_of_match[] = { + {}, + }; - static int omap_sham_dma_init(struct omap_sham_dev *dd) + static int omap_sham_get_res_of(struct omap_sham_dev *dd, + struct device *dev, struct resource *res) { - int err; + return -EINVAL; + } + #endif - dd->dma_lch = -1; + static int omap_sham_get_res_pdev(struct omap_sham_dev *dd, + struct platform_device *pdev, struct resource *res) + { + struct device *dev = &pdev->dev; + struct resource *r; + int err = 0; - err = omap_request_dma(dd->dma, dev_name(dd->dev), - omap_sham_dma_callback, dd, &dd->dma_lch); - if (err) { - dev_err(dd->dev, "Unable to request DMA channel\n"); - return err; + /* Get the base address */ + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(dev, "no MEM resource info\n"); + err = -ENODEV; + goto err; } + memcpy(res, r, sizeof(*res)); - return 0; - } + /* Get the IRQ */ + dd->irq = platform_get_irq(pdev, 0); + if (dd->irq < 0) { + dev_err(dev, "no IRQ resource info\n"); + err = dd->irq; + goto err; + } - static void omap_sham_dma_cleanup(struct omap_sham_dev *dd) - { - if (dd->dma_lch >= 0) { - omap_free_dma(dd->dma_lch); - dd->dma_lch = -1; + /* Get the DMA */ + r = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!r) { + dev_err(dev, "no DMA resource info\n"); + err = -ENODEV; + goto err; } + dd->dma = r->start; + + /* Only OMAP2/3 can be non-DT */ + dd->pdata = &omap_sham_pdata_omap2; + + err: + return err; } -static int __devinit omap_sham_probe(struct platform_device *pdev) +static int omap_sham_probe(struct platform_device *pdev) { struct omap_sham_dev *dd; struct device *dev = &pdev->dev; @@@ -1250,10 -1759,10 +1759,10 @@@ data_err return err; } -static int __devexit omap_sham_remove(struct platform_device *pdev) +static int omap_sham_remove(struct platform_device *pdev) { static struct omap_sham_dev *dd; - int i; + int i, j; dd = platform_get_drvdata(pdev); if (!dd)