summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorSteve Cornelius <steve.cornelius@freescale.com>2012-04-18 14:23:34 -0700
committerJason Liu <r64343@freescale.com>2012-07-20 13:36:50 +0800
commit1b84b539441db259c48a1d19802a2de097997edb (patch)
tree3a8a359b8a34bac603b46175e1e6753c585f0ae0 /drivers/crypto
parent09c1e70f637169fe0fc09e3925a332de3f3d65e8 (diff)
ENGR00180943-11: Add non-device-tree platform property detection
Add non-device-tree platform property detection for driver startup and initialization for iMX6 family, including clock control, job ring detection and initialization, and interrupt mapping. Signed-off-by: Steve Cornelius <steve.cornelius@freescale.com>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/ctrl.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index efb490b8d59b..7c1132097c0f 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -22,6 +22,9 @@ static int caam_remove(struct platform_device *pdev)
ctrlpriv = dev_get_drvdata(ctrldev);
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+#ifndef CONFIG_OF
+ caam_algapi_shutdown(pdev);
+#endif
/* shut down JobRs */
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
@@ -37,6 +40,9 @@ static int caam_remove(struct platform_device *pdev)
/* Unmap controller region */
iounmap(&topregs->ctrl);
+ /* shut clocks off before finalizing shutdown */
+ clk_disable(ctrlpriv->caam_clk);
+
kfree(ctrlpriv->jrdev);
kfree(ctrlpriv);
@@ -48,7 +54,7 @@ static int caam_probe(struct platform_device *pdev)
{
int d, ring, rspec;
struct device *dev;
- struct device_node *nprop, *np;
+ struct device_node *np;
struct caam_ctrl __iomem *ctrl;
struct caam_full __iomem *topregs;
struct caam_drv_private *ctrlpriv;
@@ -57,6 +63,15 @@ static int caam_probe(struct platform_device *pdev)
#ifdef CONFIG_DEBUG_FS
struct caam_perfmon *perfmon;
#endif
+#ifdef CONFIG_OF
+ struct device_node *nprop;
+#else
+ struct resource *res;
+ char *rname, inst;
+#endif
+#ifdef CONFIG_ARM
+ int ret = 0;
+#endif
ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
if (!ctrlpriv)
@@ -65,22 +80,71 @@ static int caam_probe(struct platform_device *pdev)
dev = &pdev->dev;
dev_set_drvdata(dev, ctrlpriv);
ctrlpriv->pdev = pdev;
- nprop = pdev->dev.of_node;
/* Get configuration properties from device tree */
/* First, get register page */
+#ifdef CONFIG_OF
+ nprop = pdev->dev.of_node;
ctrl = of_iomap(nprop, 0);
if (ctrl == NULL) {
dev_err(dev, "caam: of_iomap() failed\n");
return -ENOMEM;
}
+#else
+ /* Get the named resource for the controller base address */
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "iobase_caam");
+ if (!res) {
+ dev_err(dev, "caam: invalid address resource type\n");
+ return -ENODEV;
+ }
+ ctrl = ioremap(res->start, SZ_64K);
+ if (ctrl == NULL) {
+ dev_err(dev, "caam: ioremap() failed\n");
+ return -ENOMEM;
+ }
+#endif
+
ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl;
/* topregs used to derive pointers to CAAM sub-blocks only */
topregs = (struct caam_full __iomem *)ctrl;
/* Get the IRQ of the controller (for security violations only) */
+#ifdef CONFIG_OF
ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
+#else
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "irq_sec_vio");
+ if (!res) {
+ dev_err(dev, "caam: invalid IRQ resource type\n");
+ return -ENODEV;
+ }
+ ctrlpriv->secvio_irq = res->start;
+#endif
+
+/*
+ * ARM targets tend to have clock control subsystems that can
+ * enable/disable clocking to our device. Turn clocking on to proceed
+ */
+#ifdef CONFIG_ARM
+ ctrlpriv->caam_clk = clk_get(&ctrlpriv->pdev->dev, "caam_clk");
+ if (IS_ERR(ctrlpriv->caam_clk)) {
+ ret = PTR_ERR(ctrlpriv->caam_clk);
+ dev_err(&ctrlpriv->pdev->dev,
+ "can't identify CAAM bus clk: %d\n", ret);
+ return -ENODEV;
+ }
+
+ ret = clk_enable(ctrlpriv->caam_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't enable CAAM bus clock: %d\n", ret);
+ return -ENODEV;
+ }
+
+ pr_debug("%s caam_clk:%d\n", __func__,
+ (int)clk_get_rate(ctrlpriv->caam_clk));
+#endif
/*
* Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
@@ -89,8 +153,11 @@ static int caam_probe(struct platform_device *pdev)
setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE |
(sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
+ /* Set DMA masks according to platform ranging */
if (sizeof(dma_addr_t) == sizeof(u64))
dma_set_mask(dev, DMA_BIT_MASK(36));
+ else
+ dma_set_mask(dev, DMA_BIT_MASK(32));
/* Find out how many DECOs are present */
deconum = (rd_reg64(&topregs->ctrl.perfmon.cha_num) &
@@ -102,15 +169,41 @@ static int caam_probe(struct platform_device *pdev)
deco = (struct caam_deco __force **)&topregs->deco;
for (d = 0; d < deconum; d++)
ctrlpriv->deco[d] = deco[d];
-
/*
* Detect and enable JobRs
* First, find out how many ring spec'ed, allocate references
* for all, then go probe each one.
*/
rspec = 0;
+#ifdef CONFIG_OF
for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring")
rspec++;
+#else
+ np = NULL;
+
+ /* Build the name of the IRQ platform resources to identify */
+ rname = kzalloc(strlen(JR_IRQRES_NAME_ROOT) + 1, 0);
+ if (rname == NULL) {
+ iounmap(&topregs->ctrl);
+ return -ENOMEM;
+ }
+
+ /*
+ * Emulate behavor of for_each_compatible_node() for non OF targets
+ * Identify all IRQ platform resources present
+ */
+ for (d = 0; d < 4; d++) {
+ rname[0] = 0;
+ inst = '0' + d;
+ strcat(rname, JR_IRQRES_NAME_ROOT);
+ strncat(rname, &inst, 1);
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, rname);
+ if (res)
+ rspec++;
+ }
+ kfree(rname);
+#endif
ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
if (ctrlpriv->jrdev == NULL) {
iounmap(&topregs->ctrl);
@@ -119,7 +212,11 @@ static int caam_probe(struct platform_device *pdev)
ring = 0;
ctrlpriv->total_jobrs = 0;
+#ifdef CONFIG_OF
for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
+#else
+ for (d = 0; d < rspec; d++) {
+#endif
caam_jr_probe(pdev, np, ring);
ctrlpriv->total_jobrs++;
ring++;
@@ -232,9 +329,22 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv->ctl,
&ctrlpriv->ctl_tdsk_wrap);
#endif
+
+/*
+ * Non OF configurations use plaform_device, and therefore cannot simply
+ * go and get a device node by name, which the algapi module startup code
+ * assumes is possible. Therefore, non OF configurations will have to
+ * start up the API code explicitly, and forego modularization
+ */
+#ifndef CONFIG_OF
+ /* FIXME: check status */
+ caam_algapi_startup(pdev);
+#endif
+
return 0;
}
+#ifdef CONFIG_OF
static struct of_device_id caam_match[] = {
{
.compatible = "fsl,sec-v4.0",
@@ -242,12 +352,17 @@ static struct of_device_id caam_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, caam_match);
+#endif /* CONFIG_OF */
static struct platform_driver caam_driver = {
.driver = {
.name = "caam",
.owner = THIS_MODULE,
+#ifdef CONFIG_OF
.of_match_table = caam_match,
+#else
+
+#endif
},
.probe = caam_probe,
.remove = __devexit_p(caam_remove),
@@ -255,12 +370,20 @@ static struct platform_driver caam_driver = {
static int __init caam_base_init(void)
{
+#ifdef CONFIG_OF
+ return of_register_platform_driver(&caam_driver);
+#else
return platform_driver_register(&caam_driver);
+#endif
}
static void __exit caam_base_exit(void)
{
+#ifdef CONFIG_OF
+ return of_unregister_platform_driver(&caam_driver);
+#else
return platform_driver_unregister(&caam_driver);
+#endif
}
module_init(caam_base_init);