Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03feec9c authored by Mark A. Greer's avatar Mark A. Greer Committed by Herbert Xu
Browse files

crypto: omap-sham - Add Device Tree Support



Add Device Tree suport to the omap-sham crypto
driver.  Currently, only support for OMAP2 and
OMAP3 is being added but support for OMAP4 will
be added in a subsequent patch.

CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: default avatarMark A. Greer <mgreer@animalcreek.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent dd49a69e
Loading
Loading
Loading
Loading
+106 −33
Original line number Original line Diff line number Diff line
@@ -30,6 +30,10 @@
#include <linux/dmaengine.h>
#include <linux/dmaengine.h>
#include <linux/omap-dma.h>
#include <linux/omap-dma.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/crypto.h>
#include <linux/crypto.h>
#include <linux/cryptohash.h>
#include <linux/cryptohash.h>
@@ -145,6 +149,7 @@ struct omap_sham_dev {
	int			irq;
	int			irq;
	spinlock_t		lock;
	spinlock_t		lock;
	int			err;
	int			err;
	unsigned int		dma;
	struct dma_chan		*dma_lch;
	struct dma_chan		*dma_lch;
	struct tasklet_struct	done_task;
	struct tasklet_struct	done_task;


@@ -1155,13 +1160,99 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}


#ifdef CONFIG_OF
static const struct of_device_id omap_sham_of_match[] = {
	{
		.compatible	= "ti,omap2-sham",
	},
	{},
};
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 device_node *node = dev->of_node;
	const struct of_device_id *match;
	int err = 0;

	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;
	}

	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 */

err:
	return err;
}
#else
static int omap_sham_get_res_dev(struct omap_sham_dev *dd,
		struct device *dev, struct resource *res)
{
	return -EINVAL;
}
#endif

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;

	/* 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));

	/* 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;
	}

	/* 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;

err:
	return err;
}

static int __devinit omap_sham_probe(struct platform_device *pdev)
static int __devinit omap_sham_probe(struct platform_device *pdev)
{
{
	struct omap_sham_dev *dd;
	struct omap_sham_dev *dd;
	struct device *dev = &pdev->dev;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct resource res;
	dma_cap_mask_t mask;
	dma_cap_mask_t mask;
	unsigned dma_chan;
	int err, i, j;
	int err, i, j;


	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1178,33 +1269,18 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
	tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd);
	tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd);
	crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);
	crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);


	dd->irq = -1;
	err = (dev->of_node) ? omap_sham_get_res_of(dd, dev, &res) :

			       omap_sham_get_res_pdev(dd, pdev, &res);
	/* Get the base address */
	if (err)
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "no MEM resource info\n");
		err = -ENODEV;
		goto res_err;
	}
	dd->phys_base = res->start;

	/* Get the DMA */
	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(dev, "no DMA resource info\n");
		err = -ENODEV;
		goto res_err;
		goto res_err;
	}
	dma_chan = res->start;


	/* Get the IRQ */
	dd->io_base = devm_request_and_ioremap(dev, &res);
	dd->irq = platform_get_irq(pdev,  0);
	if (!dd->io_base) {
	if (dd->irq < 0) {
		dev_err(dev, "can't ioremap\n");
		dev_err(dev, "no IRQ resource info\n");
		err = -ENOMEM;
		err = dd->irq;
		goto res_err;
		goto res_err;
	}
	}
	dd->phys_base = res.start;


	err = request_irq(dd->irq, omap_sham_irq,
	err = request_irq(dd->irq, omap_sham_irq,
			IRQF_TRIGGER_LOW, dev_name(dev), dd);
			IRQF_TRIGGER_LOW, dev_name(dev), dd);
@@ -1216,10 +1292,10 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
	dma_cap_zero(mask);
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	dma_cap_set(DMA_SLAVE, mask);


	dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dma_chan);
	dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dd->dma);
	if (!dd->dma_lch) {
	if (!dd->dma_lch) {
		dev_err(dev, "unable to obtain RX DMA engine channel %u\n",
		dev_err(dev, "unable to obtain RX DMA engine channel %u\n",
			dma_chan);
			dd->dma);
		err = -ENXIO;
		err = -ENXIO;
		goto dma_err;
		goto dma_err;
	}
	}
@@ -1255,12 +1331,10 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
err_algs:
err_algs:
	for (j = 0; j < i; j++)
	for (j = 0; j < i; j++)
		crypto_unregister_ahash(&algs[j]);
		crypto_unregister_ahash(&algs[j]);
	iounmap(dd->io_base);
	pm_runtime_disable(dev);
	pm_runtime_disable(dev);
io_err:
io_err:
	dma_release_channel(dd->dma_lch);
	dma_release_channel(dd->dma_lch);
dma_err:
dma_err:
	if (dd->irq >= 0)
	free_irq(dd->irq, dd);
	free_irq(dd->irq, dd);
res_err:
res_err:
	kfree(dd);
	kfree(dd);
@@ -1285,10 +1359,8 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
	for (i = 0; i < ARRAY_SIZE(algs); i++)
	for (i = 0; i < ARRAY_SIZE(algs); i++)
		crypto_unregister_ahash(&algs[i]);
		crypto_unregister_ahash(&algs[i]);
	tasklet_kill(&dd->done_task);
	tasklet_kill(&dd->done_task);
	iounmap(dd->io_base);
	pm_runtime_disable(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	dma_release_channel(dd->dma_lch);
	dma_release_channel(dd->dma_lch);
	if (dd->irq >= 0)
	free_irq(dd->irq, dd);
	free_irq(dd->irq, dd);
	kfree(dd);
	kfree(dd);
	dd = NULL;
	dd = NULL;
@@ -1321,6 +1393,7 @@ static struct platform_driver omap_sham_driver = {
		.name	= "omap-sham",
		.name	= "omap-sham",
		.owner	= THIS_MODULE,
		.owner	= THIS_MODULE,
		.pm	= &omap_sham_pm_ops,
		.pm	= &omap_sham_pm_ops,
		.of_match_table	= omap_sham_of_match,
	},
	},
};
};