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]);
/* Unmap controller region */
iounmap(&topregs->ctrl);
+ /* shut clocks off before finalizing shutdown */
+ clk_disable(ctrlpriv->caam_clk);
+
kfree(ctrlpriv->jrdev);
kfree(ctrlpriv);
{
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;
#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)
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,
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) &
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);
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++;
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",
{},
};
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),
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);