/* * fsl_ifc_ctrl_probe * * called by device layer when it finds a device matching * one our driver can handled. This code allocates all of * the resources needed for the controller only. The * resources for the NAND banks themselves are allocated * in the chip probe function. */ static int fsl_ifc_ctrl_probe(struct platform_device *dev) { int ret = 0; int version, banks; dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); if (!fsl_ifc_ctrl_dev) return -ENOMEM; dev_set_drvdata(&dev->dev, fsl_ifc_ctrl_dev); /* IOMAP the entire IFC region */ fsl_ifc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0); if (!fsl_ifc_ctrl_dev->regs) { dev_err(&dev->dev, "failed to get memory region\n"); ret = -ENODEV; goto err; } version = ifc_in32(&fsl_ifc_ctrl_dev->regs->ifc_rev) & FSL_IFC_VERSION_MASK; banks = (version == FSL_IFC_VERSION_1_0_0) ? 4 : 8; dev_info(&dev->dev, "IFC version %d.%d, %d banks\n", version >> 24, (version >> 16) & 0xf, banks); fsl_ifc_ctrl_dev->version = version; fsl_ifc_ctrl_dev->banks = banks; if (of_property_read_bool(dev->dev.of_node, "little-endian")) { fsl_ifc_ctrl_dev->little_endian = true; dev_dbg(&dev->dev, "IFC REGISTERS are LITTLE endian\n"); } else { fsl_ifc_ctrl_dev->little_endian = false; dev_dbg(&dev->dev, "IFC REGISTERS are BIG endian\n"); } version = ioread32be(&fsl_ifc_ctrl_dev->regs->ifc_rev) & FSL_IFC_VERSION_MASK; banks = (version == FSL_IFC_VERSION_1_0_0) ? 4 : 8; dev_info(&dev->dev, "IFC version %d.%d, %d banks\n", version >> 24, (version >> 16) & 0xf, banks); fsl_ifc_ctrl_dev->version = version; fsl_ifc_ctrl_dev->banks = banks; /* get the Controller level irq */ fsl_ifc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); if (fsl_ifc_ctrl_dev->irq == NO_IRQ) { dev_err(&dev->dev, "failed to get irq resource " "for IFC\n"); ret = -ENODEV; goto err; } /* get the nand machine irq */ fsl_ifc_ctrl_dev->nand_irq = irq_of_parse_and_map(dev->dev.of_node, 1); fsl_ifc_ctrl_dev->dev = &dev->dev; ret = fsl_ifc_ctrl_init(fsl_ifc_ctrl_dev); if (ret < 0) goto err; init_waitqueue_head(&fsl_ifc_ctrl_dev->nand_wait); ret = request_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_irq, IRQF_SHARED, "fsl-ifc", fsl_ifc_ctrl_dev); if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->irq); goto err_irq; } if (fsl_ifc_ctrl_dev->nand_irq) { ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq, 0, "fsl-ifc-nand", fsl_ifc_ctrl_dev); if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->nand_irq); goto err_nandirq; } } return 0; err_nandirq: free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); err_irq: free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: return ret; }
/* * fsl_ifc_ctrl_probe * * called by device layer when it finds a device matching * one our driver can handled. This code allocates all of * the resources needed for the controller only. The * resources for the NAND banks themselves are allocated * in the chip probe function. */ static int fsl_ifc_ctrl_probe(struct platform_device *dev) { int ret = 0; dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); if (!fsl_ifc_ctrl_dev) return -ENOMEM; dev_set_drvdata(&dev->dev, fsl_ifc_ctrl_dev); /* IOMAP the entire IFC region */ fsl_ifc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0); if (!fsl_ifc_ctrl_dev->regs) { dev_err(&dev->dev, "failed to get memory region\n"); ret = -ENODEV; goto err; } /* get the Controller level irq */ fsl_ifc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); if (fsl_ifc_ctrl_dev->irq == NO_IRQ) { dev_err(&dev->dev, "failed to get irq resource " "for IFC\n"); ret = -ENODEV; goto err; } /* get the nand machine irq */ fsl_ifc_ctrl_dev->nand_irq = irq_of_parse_and_map(dev->dev.of_node, 1); fsl_ifc_ctrl_dev->dev = &dev->dev; ret = fsl_ifc_ctrl_init(fsl_ifc_ctrl_dev); if (ret < 0) goto err; init_waitqueue_head(&fsl_ifc_ctrl_dev->nand_wait); ret = request_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_irq, IRQF_SHARED, "fsl-ifc", fsl_ifc_ctrl_dev); if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->irq); goto err_irq; } if (fsl_ifc_ctrl_dev->nand_irq) { ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq, 0, "fsl-ifc-nand", fsl_ifc_ctrl_dev); if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->nand_irq); goto err_nandirq; } } return 0; err_nandirq: free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); err_irq: free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: return ret; }