]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00180943-11: Add non-device-tree platform property detection
authorSteve Cornelius <steve.cornelius@freescale.com>
Wed, 18 Apr 2012 21:23:34 +0000 (14:23 -0700)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:11:40 +0000 (14:11 +0200)
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>
drivers/crypto/caam/ctrl.c

index efb490b8d59b4a364b308cfbaa89d4ca998b0f8e..7c1132097c0f1af26de26d03918c5d71993c89cd 100644 (file)
@@ -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);