示例#1
0
void __init rcar_gen2_pm_init(void)
{
	void __iomem *p;
	u32 bar;
	static int once;
	struct device_node *np;
	bool has_a7 = false;
	bool has_a15 = false;
	struct resource res;
	int error;

	if (once++)
		return;

	for_each_of_cpu_node(np) {
		if (of_device_is_compatible(np, "arm,cortex-a15"))
			has_a15 = true;
		else if (of_device_is_compatible(np, "arm,cortex-a7"))
			has_a7 = true;
	}

	np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram");
	if (!np) {
		/* No smp-sram in DT, fall back to hardcoded address */
		res = (struct resource)DEFINE_RES_MEM(ICRAM1,
						      shmobile_boot_size);
		goto map;
	}

	error = of_address_to_resource(np, 0, &res);
	if (error) {
		pr_err("Failed to get smp-sram address: %d\n", error);
		return;
	}

map:
	/* RAM for jump stub, because BAR requires 256KB aligned address */
	if (res.start & (256 * 1024 - 1) ||
	    resource_size(&res) < shmobile_boot_size) {
		pr_err("Invalid smp-sram region\n");
		return;
	}

	p = ioremap(res.start, resource_size(&res));
	if (!p)
		return;
	/*
	 * install the reset vector, use the largest version if we have enough
	 * memory available
	 */
	if (resource_size(&res) >= shmobile_boot_size_gen2) {
		shmobile_boot_cpu_gen2 = read_cpuid_mpidr();
		memcpy_toio(p, shmobile_boot_vector_gen2,
			    shmobile_boot_size_gen2);
	} else {
		memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
	}
	iounmap(p);

	/* setup reset vectors */
	p = ioremap_nocache(RST, 0x63);
	bar = phys_to_sbar(res.start);
	if (has_a15) {
		writel_relaxed(bar, p + CA15BAR);
		writel_relaxed(bar | SBAR_BAREN, p + CA15BAR);

		/* de-assert reset for CA15 CPUs */
		writel_relaxed((readl_relaxed(p + CA15RESCNT) &
				~CA15RESCNT_CPUS) | CA15RESCNT_CODE,
			       p + CA15RESCNT);
	}
	if (has_a7) {
		writel_relaxed(bar, p + CA7BAR);
		writel_relaxed(bar | SBAR_BAREN, p + CA7BAR);

		/* de-assert reset for CA7 CPUs */
		writel_relaxed((readl_relaxed(p + CA7RESCNT) &
				~CA7RESCNT_CPUS) | CA7RESCNT_CODE,
			       p + CA7RESCNT);
	}
	iounmap(p);

	shmobile_smp_apmu_suspend_init();
}
示例#2
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
					   const struct of_device_id *match)
{
	struct edac_pci_ctl_info *pci;
	struct mpc85xx_pci_pdata *pdata;
	struct resource r;
	int res = 0;

	if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL))
		return -ENOMEM;

	pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mpc85xx_pci_err");
	if (!pci)
		return -ENOMEM;

	pdata = pci->pvt_info;
	pdata->name = "mpc85xx_pci_err";
	pdata->irq = NO_IRQ;
	dev_set_drvdata(&op->dev, pci);
	pci->dev = &op->dev;
	pci->mod_name = EDAC_MOD_STR;
	pci->ctl_name = pdata->name;
	pci->dev_name = op->dev.bus_id;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		pci->edac_check = mpc85xx_pci_check;

	pdata->edac_idx = edac_pci_idx++;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "PCI err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

	if (!devm_request_mem_region(&op->dev, r.start,
					r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->pci_vbase = devm_ioremap(&op->dev, r.start,
					r.end - r.start + 1);
	if (!pdata->pci_vbase) {
		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	orig_pci_err_cap_dr =
	    in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);

	/* PCI master abort is expected during config cycles */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);

	orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);

	/* disable master abort reporting */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);

	/* clear error bits */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);

	if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
		debugf3("%s(): failed edac_pci_add_device()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_pci_isr, IRQF_DISABLED,
				       "[EDAC] PCI err", pci);
		if (res < 0) {
			printk(KERN_ERR
			       "%s: Unable to requiest irq %d for "
			       "MPC85xx PCI err\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
		       pdata->irq);
	}

	devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");

	return 0;

err2:
	edac_pci_del_device(&op->dev);
err:
	edac_pci_free_ctl_info(pci);
	devres_release_group(&op->dev, mpc85xx_pci_err_probe);
	return res;
}
示例#3
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
					  const struct of_device_id *match)
{
	struct mem_ctl_info *mci;
	struct mpc85xx_mc_pdata *pdata;
	struct resource r;
	u32 sdram_ctl;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_mc_err_probe, GFP_KERNEL))
		return -ENOMEM;

	mci = edac_mc_alloc(sizeof(*pdata), 4, 1, edac_mc_idx);
	if (!mci) {
		devres_release_group(&op->dev, mpc85xx_mc_err_probe);
		return -ENOMEM;
	}

	pdata = mci->pvt_info;
	pdata->name = "mpc85xx_mc_err";
	pdata->irq = NO_IRQ;
	mci->dev = &op->dev;
	pdata->edac_idx = edac_mc_idx++;
	dev_set_drvdata(mci->dev, mci);
	mci->ctl_name = pdata->name;
	mci->dev_name = pdata->name;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for MC err regs\n",
		       __func__);
		goto err;
	}

	if (!devm_request_mem_region(&op->dev, r.start,
				     r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->mc_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
	if (!pdata->mc_vbase) {
		printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	sdram_ctl = in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG);
	if (!(sdram_ctl & DSC_ECC_EN)) {
		/* no ECC */
		printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
		res = -ENODEV;
		goto err;
	}

	debugf3("%s(): init mci\n", __func__);
	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 |
	    MEM_FLAG_DDR | MEM_FLAG_DDR2;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->edac_cap = EDAC_FLAG_SECDED;
	mci->mod_name = EDAC_MOD_STR;
	mci->mod_ver = MPC85XX_REVISION;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		mci->edac_check = mpc85xx_mc_check;

	mci->ctl_page_to_phys = NULL;

	mci->scrub_mode = SCRUB_SW_SRC;

	mpc85xx_set_mc_sysfs_attributes(mci);

	mpc85xx_init_csrows(mci);

#ifdef CONFIG_EDAC_DEBUG
	edac_mc_register_mcidev_debug((struct attribute **)debug_attr);
#endif

	/* store the original error disable bits */
	orig_ddr_err_disable =
	    in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE);
	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE, 0);

	/* clear all error bits */
	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);

	if (edac_mc_add_mc(mci)) {
		debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN,
			 DDR_EIE_MBEE | DDR_EIE_SBEE);

		/* store the original error management threshold */
		orig_ddr_err_sbe = in_be32(pdata->mc_vbase +
					   MPC85XX_MC_ERR_SBE) & 0xff0000;

		/* set threshold to 1 error per interrupt */
		out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000);

		/* register interrupts */
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_mc_isr,
					IRQF_DISABLED | IRQF_SHARED,
				       "[EDAC] MC err", mci);
		if (res < 0) {
			printk(KERN_ERR "%s: Unable to request irq %d for "
			       "MPC85xx DRAM ERR\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC\n",
		       pdata->irq);
	}

	devres_remove_group(&op->dev, mpc85xx_mc_err_probe);
	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " MC err registered\n");

	return 0;

err2:
	edac_mc_del_mc(&op->dev);
err:
	devres_release_group(&op->dev, mpc85xx_mc_err_probe);
	edac_mc_free(mci);
	return res;
}
示例#4
0
/**
 * of_platform_device_create - Alloc, initialize and register an of_device
 * @np: pointer to node to create device for
 * @parent: device model parent device.
 *
 * Returns pointer to created platform device, or NULL if a device was not
 * registered. Unavailable devices will not get registered.
 */
static struct device_d *of_platform_device_create(struct device_node *np,
						struct device_d *parent)
{
	struct device_d *dev;
	struct resource *res = NULL, temp_res;
	int i, j, ret, num_reg = 0, match;

	if (!of_device_is_available(np))
		return NULL;

	/* count the io resources */
	if (of_can_translate_address(np))
		while (of_address_to_resource(np, num_reg, &temp_res) == 0)
			num_reg++;

	/* Populate the resource table */
	if (num_reg) {
		res = xzalloc(sizeof(*res) * num_reg);
		for (i = 0; i < num_reg; i++) {
			ret = of_address_to_resource(np, i, &res[i]);
			if (ret) {
				free(res);
				return NULL;
			}
		}

		/*
		 * A device may already be registered as platform_device.
		 * Instead of registering the same device again, just
		 * add this node to the existing device.
		 */
		for_each_device(dev) {
			if (!dev->resource)
				continue;

			for (i = 0, match = 0; i < num_reg; i++)
				for (j = 0; j < dev->num_resources; j++)
					if (dev->resource[j].start ==
						res[i].start &&
					    dev->resource[j].end ==
						res[i].end) {
						match++;
						break;
					}

			/* check if all address resources match */
			if (match == num_reg) {
				debug("connecting %s to %s\n",
					np->name, dev_name(dev));
				dev->device_node = np;
				free(res);
				return dev;
			}
		}
	}

	/* setup generic device info */
	dev = xzalloc(sizeof(*dev));
	dev->id = DEVICE_ID_SINGLE;
	dev->device_node = np;
	dev->parent = parent;
	dev->resource = res;
	dev->num_resources = num_reg;
	of_device_make_bus_id(dev);

	debug("%s: register device %s, io=" PRINTF_CONVERSION_RESOURCE "\n",
			__func__, dev_name(dev),
		(num_reg) ? dev->resource[0].start : (-1));

	ret = platform_device_register(dev);
	if (!ret)
		return dev;

	free(dev);
	if (num_reg)
		free(res);
	return NULL;
}
示例#5
0
static int of_isp1760_probe(struct platform_device *dev,
		const struct of_device_id *match)
{
	struct usb_hcd *hcd;
	struct device_node *dp = dev->dev.of_node;
	struct resource *res;
	struct resource memory;
	struct of_irq oirq;
	int virq;
	resource_size_t res_len;
	int ret;
	const unsigned int *prop;
	unsigned int devflags = 0;

	ret = of_address_to_resource(dp, 0, &memory);
	if (ret)
		return -ENXIO;

	res_len = resource_size(&memory);

	res = request_mem_region(memory.start, res_len, dev_name(&dev->dev));
	if (!res)
		return -EBUSY;

	if (of_irq_map_one(dp, 0, &oirq)) {
		ret = -ENODEV;
		goto release_reg;
	}

	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
			oirq.size);

	if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
		devflags |= ISP1760_FLAG_ISP1761;

	/* Some systems wire up only 16 of the 32 data lines */
	prop = of_get_property(dp, "bus-width", NULL);
	if (prop && *prop == 16)
		devflags |= ISP1760_FLAG_BUS_WIDTH_16;

	if (of_get_property(dp, "port1-otg", NULL) != NULL)
		devflags |= ISP1760_FLAG_OTG_EN;

	if (of_get_property(dp, "analog-oc", NULL) != NULL)
		devflags |= ISP1760_FLAG_ANALOG_OC;

	if (of_get_property(dp, "dack-polarity", NULL) != NULL)
		devflags |= ISP1760_FLAG_DACK_POL_HIGH;

	if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
		devflags |= ISP1760_FLAG_DREQ_POL_HIGH;

	hcd = isp1760_register(memory.start, res_len, virq,
		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
		devflags);
	if (IS_ERR(hcd)) {
		ret = PTR_ERR(hcd);
		goto release_reg;
	}

	dev_set_drvdata(&dev->dev, hcd);
	return ret;

release_reg:
	release_mem_region(memory.start, res_len);
	return ret;
}
示例#6
0
static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev,
                                        const struct of_device_id *match)
{
	struct resource res;
	struct mii_bus *new_bus;
	struct fec_info *fec;
	int (*get_bus_freq)(struct device_node *) = match->data;
	int ret = -ENOMEM, clock, speed;

	new_bus = mdiobus_alloc();
	if (!new_bus)
		goto out;

	fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
	if (!fec)
		goto out_mii;

	new_bus->priv = fec;
	new_bus->name = "FEC MII Bus";
	new_bus->read = &fs_enet_fec_mii_read;
	new_bus->write = &fs_enet_fec_mii_write;
	new_bus->reset = &fs_enet_fec_mii_reset;

	ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
	if (ret)
		goto out_res;

	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);

	fec->fecp = ioremap(res.start, res.end - res.start + 1);
	if (!fec->fecp)
		goto out_fec;

	if (get_bus_freq) {
		clock = get_bus_freq(ofdev->dev.of_node);
		if (!clock) {
			/* Use maximum divider if clock is unknown */
			dev_warn(&ofdev->dev, "could not determine IPS clock\n");
			clock = 0x3F * 5000000;
		}
	} else
		clock = ppc_proc_freq;

	/*
	 * Scale for a MII clock <= 2.5 MHz
	 * Note that only 6 bits (25:30) are available for MII speed.
	 */
	speed = (clock + 4999999) / 5000000;
	if (speed > 0x3F) {
		speed = 0x3F;
		dev_err(&ofdev->dev,
			"MII clock (%d Hz) exceeds max (2.5 MHz)\n",
			clock / speed);
	}

	fec->mii_speed = speed << 1;

	setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
	setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
	                                  FEC_ECNTRL_ETHER_EN);
	out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
	clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);

	new_bus->phy_mask = ~0;
	new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
	if (!new_bus->irq)
		goto out_unmap_regs;

	new_bus->parent = &ofdev->dev;
	dev_set_drvdata(&ofdev->dev, new_bus);

	ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
	if (ret)
		goto out_free_irqs;

	return 0;

out_free_irqs:
	dev_set_drvdata(&ofdev->dev, NULL);
	kfree(new_bus->irq);
out_unmap_regs:
	iounmap(fec->fecp);
out_res:
out_fec:
	kfree(fec);
out_mii:
	mdiobus_free(new_bus);
out:
	return ret;
}
示例#7
0
static int fsl_ssi_probe(struct platform_device *pdev)
{
	struct fsl_ssi_private *ssi_private;
	int ret = 0;
	struct device_attribute *dev_attr = NULL;
	struct device_node *np = pdev->dev.of_node;
	const char *p, *sprop;
	const uint32_t *iprop;
	struct resource res;
	char name[64];

	/* SSIs that are not connected on the board should have a
	 *      status = "disabled"
	 * property in their device tree nodes.
	 */
	if (!of_device_is_available(np))
		return -ENODEV;

	/* The DAI name is the last part of the full name of the node. */
	p = strrchr(np->full_name, '/') + 1;
	ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p),
			      GFP_KERNEL);
	if (!ssi_private) {
		dev_err(&pdev->dev, "could not allocate DAI object\n");
		return -ENOMEM;
	}

	strcpy(ssi_private->name, p);

	/* Initialize this copy of the CPU DAI driver structure */
	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
	       sizeof(fsl_ssi_dai_template));
	ssi_private->cpu_dai_drv.name = ssi_private->name;

	/* Get the addresses and IRQ */
	ret = of_address_to_resource(np, 0, &res);
	if (ret) {
		dev_err(&pdev->dev, "could not determine device resources\n");
		goto error_kmalloc;
	}
	ssi_private->ssi = of_iomap(np, 0);
	if (!ssi_private->ssi) {
		dev_err(&pdev->dev, "could not map device resources\n");
		ret = -ENOMEM;
		goto error_kmalloc;
	}
	ssi_private->ssi_phys = res.start;

	ssi_private->irq = irq_of_parse_and_map(np, 0);
	if (ssi_private->irq == NO_IRQ) {
		dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
		ret = -ENXIO;
		goto error_iomap;
	}

	/* The 'name' should not have any slashes in it. */
	ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
			  ssi_private);
	if (ret < 0) {
		dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
		goto error_irqmap;
	}

	/* Are the RX and the TX clocks locked? */
	if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
		ssi_private->cpu_dai_drv.symmetric_rates = 1;
		ssi_private->cpu_dai_drv.symmetric_channels = 1;
		ssi_private->cpu_dai_drv.symmetric_samplebits = 1;
	}

	/* Determine the FIFO depth. */
	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
	if (iprop)
		ssi_private->fifo_depth = be32_to_cpup(iprop);
	else
                /* Older 8610 DTs didn't have the fifo-depth property */
		ssi_private->fifo_depth = 8;

	ssi_private->baudclk_locked = false;
	spin_lock_init(&ssi_private->baudclk_lock);

	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
		ssi_private->ssi_on_imx = true;

		ssi_private->coreclk = devm_clk_get(&pdev->dev, "ipg");
		if (IS_ERR(ssi_private->coreclk)) {
			ret = PTR_ERR(ssi_private->coreclk);
			dev_err(&pdev->dev, "could not get ipg clock: %d\n", ret);
			goto error_irq;
		}
		ssi_private->clk = devm_clk_get(&pdev->dev, "baud");
		if (IS_ERR(ssi_private->clk)) {
			ret = PTR_ERR(ssi_private->clk);
			dev_err(&pdev->dev, "could not get baud clock: %d\n", ret);
			goto error_irq;
		}

		/*
		 * We have burstsize be "fifo_depth - 2" to match the SSI
		 * watermark setting in fsl_ssi_startup().
		 */
		ssi_private->dma_params_tx.maxburst =
			ssi_private->fifo_depth - 2;
		ssi_private->dma_params_rx.maxburst =
			ssi_private->fifo_depth - 2;
		ssi_private->dma_params_tx.addr =
			ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
		ssi_private->dma_params_rx.addr =
			ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
	}
示例#8
0
static int __devinit of_flash_probe(struct platform_device *dev,
				    const struct of_device_id *match)
{
#ifdef CONFIG_MTD_PARTITIONS
	const char **part_probe_types;
#endif
	struct device_node *dp = dev->dev.of_node;
	struct resource res;
	struct of_flash *info;
	const char *probe_type = match->data;
	const u32 *width;
	int err;
	int i;
	int count;
	const u32 *p;
	int reg_tuple_size;
	struct mtd_info **mtd_list = NULL;
	resource_size_t res_size;

	reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);

	/*
	 * Get number of "reg" tuples. Scan for MTD devices on area's
	 * described by each "reg" region. This makes it possible (including
	 * the concat support) to support the Intel P30 48F4400 chips which
	 * consists internally of 2 non-identical NOR chips on one die.
	 */
	p = of_get_property(dp, "reg", &count);
	if (count % reg_tuple_size != 0) {
		dev_err(&dev->dev, "Malformed reg property on %s\n",
				dev->dev.of_node->full_name);
		err = -EINVAL;
		goto err_flash_remove;
	}
	count /= reg_tuple_size;

	err = -ENOMEM;
	info = kzalloc(sizeof(struct of_flash) +
		       sizeof(struct of_flash_list) * count, GFP_KERNEL);
	if (!info)
		goto err_flash_remove;

	dev_set_drvdata(&dev->dev, info);

	mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
	if (!mtd_list)
		goto err_flash_remove;

	for (i = 0; i < count; i++) {
		err = -ENXIO;
		if (of_address_to_resource(dp, i, &res)) {
			dev_err(&dev->dev, "Can't get IO address from device"
				" tree\n");
			goto err_out;
		}

		dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
			(unsigned long long)res.start,
			(unsigned long long)res.end);

		err = -EBUSY;
		res_size = resource_size(&res);
		info->list[i].res = request_mem_region(res.start, res_size,
						       dev_name(&dev->dev));
		if (!info->list[i].res)
			goto err_out;

		err = -ENXIO;
		width = of_get_property(dp, "bank-width", NULL);
		if (!width) {
			dev_err(&dev->dev, "Can't get bank width from device"
				" tree\n");
			goto err_out;
		}

		info->list[i].map.name = dev_name(&dev->dev);
		info->list[i].map.phys = res.start;
		info->list[i].map.size = res_size;
		info->list[i].map.bankwidth = *width;

		err = -ENOMEM;
		info->list[i].map.virt = ioremap(info->list[i].map.phys,
						 info->list[i].map.size);
		if (!info->list[i].map.virt) {
			dev_err(&dev->dev, "Failed to ioremap() flash"
				" region\n");
			goto err_out;
		}

		simple_map_init(&info->list[i].map);

		if (probe_type) {
			info->list[i].mtd = do_map_probe(probe_type,
							 &info->list[i].map);
		} else {
			info->list[i].mtd = obsolete_probe(dev,
							   &info->list[i].map);
		}
		mtd_list[i] = info->list[i].mtd;

		err = -ENXIO;
		if (!info->list[i].mtd) {
			dev_err(&dev->dev, "do_map_probe() failed\n");
			goto err_out;
		} else {
			info->list_size++;
		}
		info->list[i].mtd->owner = THIS_MODULE;
		info->list[i].mtd->dev.parent = &dev->dev;
	}

	err = 0;
	if (info->list_size == 1) {
		info->cmtd = info->list[0].mtd;
	} else if (info->list_size > 1) {
		/*
		 * We detected multiple devices. Concatenate them together.
		 */
#ifdef CONFIG_MTD_CONCAT
		info->cmtd = mtd_concat_create(mtd_list, info->list_size,
					       dev_name(&dev->dev));
		if (info->cmtd == NULL)
			err = -ENXIO;
#else
		printk(KERN_ERR "physmap_of: multiple devices "
		       "found but MTD concat support disabled.\n");
		err = -ENXIO;
#endif
	}
	if (err)
		goto err_out;

#ifdef CONFIG_MTD_PARTITIONS
	part_probe_types = of_get_probes(dp);
	err = parse_mtd_partitions(info->cmtd, part_probe_types,
				   &info->parts, 0);
	if (err < 0) {
		of_free_probes(part_probe_types);
		goto err_out;
	}
	of_free_probes(part_probe_types);

#ifdef CONFIG_MTD_OF_PARTS
	if (err == 0) {
		err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
		if (err < 0)
			goto err_out;
	}
#endif

	if (err == 0) {
		err = parse_obsolete_partitions(dev, info, dp);
		if (err < 0)
			goto err_out;
	}

	if (err > 0)
		add_mtd_partitions(info->cmtd, info->parts, err);
	else
#endif
		add_mtd_device(info->cmtd);

	kfree(mtd_list);

	return 0;

err_out:
	kfree(mtd_list);
err_flash_remove:
	of_flash_remove(dev);

	return err;
}
示例#9
0
文件: suspend.c 项目: 3null/linux
static int pmc_probe(struct platform_device *ofdev)
{
	const struct of_device_id *match;
	struct device_node *np = ofdev->dev.of_node;
	struct resource res;
	const struct pmc_type *type;
	int ret = 0;

	match = of_match_device(pmc_match, &ofdev->dev);
	if (!match)
		return -EINVAL;

	type = match->data;

	if (!of_device_is_available(np))
		return -ENODEV;

	has_deep_sleep = type->has_deep_sleep;
	immrbase = get_immrbase();
	pmc_dev = ofdev;

	is_pci_agent = mpc83xx_is_pci_agent();
	if (is_pci_agent < 0)
		return is_pci_agent;

	ret = of_address_to_resource(np, 0, &res);
	if (ret)
		return -ENODEV;

	pmc_irq = irq_of_parse_and_map(np, 0);
	if (pmc_irq != NO_IRQ) {
		ret = request_irq(pmc_irq, pmc_irq_handler, IRQF_SHARED,
		                  "pmc", ofdev);

		if (ret)
			return -EBUSY;
	}

	pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));

	if (!pmc_regs) {
		ret = -ENOMEM;
		goto out;
	}

	ret = of_address_to_resource(np, 1, &res);
	if (ret) {
		ret = -ENODEV;
		goto out_pmc;
	}

	clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));

	if (!clock_regs) {
		ret = -ENOMEM;
		goto out_pmc;
	}

	if (has_deep_sleep) {
		syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
				     sizeof(*syscr_regs));
		if (!syscr_regs) {
			ret = -ENOMEM;
			goto out_syscr;
		}
	}

	if (is_pci_agent)
		mpc83xx_set_agent();

	suspend_set_ops(&mpc83xx_suspend_ops);
	return 0;

out_syscr:
	iounmap(clock_regs);
out_pmc:
	iounmap(pmc_regs);
out:
	if (pmc_irq != NO_IRQ)
		free_irq(pmc_irq, ofdev);

	return ret;
}
示例#10
0
static int __init xen_guest_init(void)
{
	struct xen_add_to_physmap xatp;
	static struct shared_info *shared_info_page = 0;
	struct device_node *node;
	int len;
	const char *s = NULL;
	const char *version = NULL;
	const char *xen_prefix = "xen,xen-";
	struct resource res;
	phys_addr_t grant_frames;

	node = of_find_compatible_node(NULL, NULL, "xen,xen");
	if (!node) {
		pr_debug("No Xen support\n");
		return 0;
	}
	s = of_get_property(node, "compatible", &len);
	if (strlen(xen_prefix) + 3  < len &&
			!strncmp(xen_prefix, s, strlen(xen_prefix)))
		version = s + strlen(xen_prefix);
	if (version == NULL) {
		pr_debug("Xen version not found\n");
		return 0;
	}
	if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
		return 0;
	grant_frames = res.start;
	xen_events_irq = irq_of_parse_and_map(node, 0);
	pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n",
			version, xen_events_irq, &grant_frames);

	if (xen_events_irq < 0)
		return -ENODEV;

	xen_domain_type = XEN_HVM_DOMAIN;

	xen_setup_features();

	if (xen_feature(XENFEAT_dom0))
		xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED;
	else
		xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED);

	if (!shared_info_page)
		shared_info_page = (struct shared_info *)
			get_zeroed_page(GFP_KERNEL);
	if (!shared_info_page) {
		pr_err("not enough memory\n");
		return -ENOMEM;
	}
	xatp.domid = DOMID_SELF;
	xatp.idx = 0;
	xatp.space = XENMAPSPACE_shared_info;
	xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
		BUG();

	HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;

	/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
	 * page, we use it in the event channel upcall and in some pvclock
	 * related functions. 
	 * The shared info contains exactly 1 CPU (the boot CPU). The guest
	 * is required to use VCPUOP_register_vcpu_info to place vcpu info
	 * for secondary CPUs as they are brought up.
	 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
	 */
	xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
			                       sizeof(struct vcpu_info));
	if (xen_vcpu_info == NULL)
		return -ENOMEM;

	if (gnttab_setup_auto_xlat_frames(grant_frames)) {
		free_percpu(xen_vcpu_info);
		return -ENOMEM;
	}
	gnttab_init();
	if (!xen_initial_domain())
		xenbus_probe(NULL);

	/*
	 * Making sure board specific code will not set up ops for
	 * cpu idle and cpu freq.
	 */
	disable_cpuidle();
	disable_cpufreq();

	xen_init_IRQ();

	if (request_percpu_irq(xen_events_irq, xen_arm_callback,
			       "events", &xen_vcpu)) {
		pr_err("Error request IRQ %d\n", xen_events_irq);
		return -EINVAL;
	}

	xen_percpu_init();

	register_cpu_notifier(&xen_cpu_notifier);

	return 0;
}
static int __devinit xwdt_probe(struct platform_device *pdev)
{
	int rc;
	u32 *tmptr;
	u32 *pfreq;

	no_timeout = 0;

	pfreq = (u32 *)of_get_property(pdev->dev.of_node->parent,
					"clock-frequency", NULL);

	if (pfreq == NULL) {
		pr_warn("The watchdog clock frequency cannot be obtained!\n");
		no_timeout = 1;
	}

	rc = of_address_to_resource(pdev->dev.of_node, 0, &xdev.res);
	if (rc) {
		pr_warn("invalid address!\n");
		return rc;
	}

	tmptr = (u32 *)of_get_property(pdev->dev.of_node,
					"xlnx,wdt-interval", NULL);
	if (tmptr == NULL) {
		pr_warn("Parameter \"xlnx,wdt-interval\" not found in device tree!\n");
		no_timeout = 1;
	} else {
		xdev.wdt_interval = *tmptr;
	}

	tmptr = (u32 *)of_get_property(pdev->dev.of_node,
					"xlnx,wdt-enable-once", NULL);
	if (tmptr == NULL) {
		pr_warn("Parameter \"xlnx,wdt-enable-once\" not found in device tree!\n");
		xdev.nowayout = WATCHDOG_NOWAYOUT;
	}

/*
 *  Twice of the 2^wdt_interval / freq  because the first wdt overflow is
 *  ignored (interrupt), reset is only generated at second wdt overflow
 */
	if (!no_timeout)
		timeout = 2 * ((1<<xdev.wdt_interval) / *pfreq);

	if (!request_mem_region(xdev.res.start,
			xdev.res.end - xdev.res.start + 1, WATCHDOG_NAME)) {
		rc = -ENXIO;
		pr_err("memory request failure!\n");
		goto err_out;
	}

	xdev.base = ioremap(xdev.res.start, xdev.res.end - xdev.res.start + 1);
	if (xdev.base == NULL) {
		rc = -ENOMEM;
		pr_err("ioremap failure!\n");
		goto release_mem;
	}

	rc = xwdt_selftest();
	if (rc == XWT_TIMER_FAILED) {
		pr_err("SelfTest routine error!\n");
		goto unmap_io;
	}

	xwdt_get_status(&xdev.boot_status);

	rc = misc_register(&xwdt_miscdev);
	if (rc) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       xwdt_miscdev.minor, rc);
		goto unmap_io;
	}

	if (no_timeout)
		pr_info("driver loaded (timeout=? sec, nowayout=%d)\n",
			xdev.nowayout);
	else
		pr_info("driver loaded (timeout=%d sec, nowayout=%d)\n",
			timeout, xdev.nowayout);

	expect_close = 0;
	clear_bit(0, &driver_open);

	return 0;

unmap_io:
	iounmap(xdev.base);
release_mem:
	release_mem_region(xdev.res.start, resource_size(&xdev.res));
err_out:
	return rc;
}
示例#12
0
static void __init mpc85xx_ads_pic_init(void)
{
    struct mpic *mpic;
    struct resource r;
    struct device_node *np = NULL;
#ifdef CONFIG_CPM2
    int irq;
#endif

    np = of_find_node_by_type(np, "open-pic");

    if (np == NULL) {
        printk(KERN_ERR "Could not find open-pic node\n");
        return;
    }

    if(of_address_to_resource(np, 0, &r)) {
        printk(KERN_ERR "Could not map mpic register space\n");
        of_node_put(np);
        return;
    }

    mpic = mpic_alloc(np, r.start,
                      MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
                      4, 0, " OpenPIC  ");
    BUG_ON(mpic == NULL);
    of_node_put(np);

    mpic_assign_isu(mpic, 0, r.start + 0x10200);
    mpic_assign_isu(mpic, 1, r.start + 0x10280);
    mpic_assign_isu(mpic, 2, r.start + 0x10300);
    mpic_assign_isu(mpic, 3, r.start + 0x10380);
    mpic_assign_isu(mpic, 4, r.start + 0x10400);
    mpic_assign_isu(mpic, 5, r.start + 0x10480);
    mpic_assign_isu(mpic, 6, r.start + 0x10500);
    mpic_assign_isu(mpic, 7, r.start + 0x10580);

    /* Unused on this platform (leave room for 8548) */
    mpic_assign_isu(mpic, 8, r.start + 0x10600);
    mpic_assign_isu(mpic, 9, r.start + 0x10680);
    mpic_assign_isu(mpic, 10, r.start + 0x10700);
    mpic_assign_isu(mpic, 11, r.start + 0x10780);

    /* External Interrupts */
    mpic_assign_isu(mpic, 12, r.start + 0x10000);
    mpic_assign_isu(mpic, 13, r.start + 0x10080);
    mpic_assign_isu(mpic, 14, r.start + 0x10100);

    mpic_init(mpic);

#ifdef CONFIG_CPM2
    /* Setup CPM2 PIC */
    np = of_find_node_by_type(NULL, "cpm-pic");
    if (np == NULL) {
        printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
        return;
    }
    irq = irq_of_parse_and_map(np, 0);

    cpm2_pic_init(np);
    set_irq_chained_handler(irq, cpm2_cascade);
#endif
}
示例#13
0
/**
 * ehci_hcd_xilinx_of_probe - Probe method for the USB host controller
 * @op:		pointer to the platform_device bound to the host controller
 *
 * This function requests resources and sets up appropriate properties for the
 * host controller. Because the Xilinx USB host controller can be configured
 * as HS only or HS/FS only, it checks the configuration in the device tree
 * entry, and sets an appropriate value for hcd->has_tt.
 */
static int ehci_hcd_xilinx_of_probe(struct platform_device *op)
{
	struct device_node *dn = op->dev.of_node;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci;
	struct resource res;
	int irq;
	int rv;
	int *value;

	if (usb_disabled())
		return -ENODEV;

	dev_dbg(&op->dev, "initializing XILINX-OF USB Controller\n");

	rv = of_address_to_resource(dn, 0, &res);
	if (rv)
		return rv;

	hcd = usb_create_hcd(&ehci_xilinx_of_hc_driver, &op->dev,
				"XILINX-OF USB");
	if (!hcd)
		return -ENOMEM;

	hcd->rsrc_start = res.start;
	hcd->rsrc_len = resource_size(&res);

	irq = irq_of_parse_and_map(dn, 0);
	if (!irq) {
		dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n",
			__FILE__);
		rv = -EBUSY;
		goto err_irq;
	}

	hcd->regs = devm_ioremap_resource(&op->dev, &res);
	if (IS_ERR(hcd->regs)) {
		rv = PTR_ERR(hcd->regs);
		goto err_irq;
	}

	ehci = hcd_to_ehci(hcd);

	/* This core always has big-endian register interface and uses
	 * big-endian memory descriptors.
	 */
	ehci->big_endian_mmio = 1;
	ehci->big_endian_desc = 1;

	/* Check whether the FS support option is selected in the hardware.
	 */
	value = (int *)of_get_property(dn, "xlnx,support-usb-fs", NULL);
	if (value && (*value == 1)) {
		ehci_dbg(ehci, "USB host controller supports FS devices\n");
		hcd->has_tt = 1;
	} else {
		ehci_dbg(ehci,
			"USB host controller is HS only\n");
		hcd->has_tt = 0;
	}

	/* Debug registers are at the first 0x100 region
	 */
	ehci->caps = hcd->regs + 0x100;

	rv = usb_add_hcd(hcd, irq, 0);
	if (rv == 0) {
		device_wakeup_enable(hcd->self.controller);
		return 0;
	}

err_irq:
	usb_put_hcd(hcd);

	return rv;
}
示例#14
0
static int __init gfar_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *mdio_dev, *gfar_dev;
	struct resource res;
	int ret;

	for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) {
		int k;
		struct device_node *child = NULL;
		struct gianfar_mdio_data mdio_data;

		memset(&res, 0, sizeof(res));
		memset(&mdio_data, 0, sizeof(mdio_data));

		ret = of_address_to_resource(np, 0, &res);
		if (ret)
			goto mdio_err;

		mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1);
		if (IS_ERR(mdio_dev)) {
			ret = PTR_ERR(mdio_dev);
			goto mdio_err;
		}

		for (k = 0; k < 32; k++)
			mdio_data.irq[k] = -1;

		while ((child = of_get_next_child(np, child)) != NULL) {
			if (child->n_intrs) {
				u32 *id = (u32 *) get_property(child, "reg", NULL);
				mdio_data.irq[*id] = child->intrs[0].line;
			}
		}

		ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data));
		if (ret)
			goto mdio_unreg;
	}

	for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) {
		struct resource r[4];
		struct device_node *phy, *mdio;
		struct gianfar_platform_data gfar_data;
		unsigned int *id;
		char *model;
		void *mac_addr;
		phandle *ph;

		memset(r, 0, sizeof(r));
		memset(&gfar_data, 0, sizeof(gfar_data));

		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			goto gfar_err;

		r[1].start = np->intrs[0].line;
		r[1].end = np->intrs[0].line;
		r[1].flags = IORESOURCE_IRQ;

		model = get_property(np, "model", NULL);

		/* If we aren't the FEC we have multiple interrupts */
		if (model && strcasecmp(model, "FEC")) {
			r[1].name = gfar_tx_intr;

			r[2].name = gfar_rx_intr;
			r[2].start = np->intrs[1].line;
			r[2].end = np->intrs[1].line;
			r[2].flags = IORESOURCE_IRQ;

			r[3].name = gfar_err_intr;
			r[3].start = np->intrs[2].line;
			r[3].end = np->intrs[2].line;
			r[3].flags = IORESOURCE_IRQ;
		}

		gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1);

		if (IS_ERR(gfar_dev)) {
			ret = PTR_ERR(gfar_dev);
			goto gfar_err;
		}

		mac_addr = get_property(np, "address", NULL);
		memcpy(gfar_data.mac_addr, mac_addr, 6);

		if (model && !strcasecmp(model, "TSEC"))
			gfar_data.device_flags =
				FSL_GIANFAR_DEV_HAS_GIGABIT |
				FSL_GIANFAR_DEV_HAS_COALESCE |
				FSL_GIANFAR_DEV_HAS_RMON |
				FSL_GIANFAR_DEV_HAS_MULTI_INTR;
		if (model && !strcasecmp(model, "eTSEC"))
			gfar_data.device_flags =
				FSL_GIANFAR_DEV_HAS_GIGABIT |
				FSL_GIANFAR_DEV_HAS_COALESCE |
				FSL_GIANFAR_DEV_HAS_RMON |
				FSL_GIANFAR_DEV_HAS_MULTI_INTR |
				FSL_GIANFAR_DEV_HAS_CSUM |
				FSL_GIANFAR_DEV_HAS_VLAN |
				FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;

		ph = (phandle *) get_property(np, "phy-handle", NULL);
		phy = of_find_node_by_phandle(*ph);

		if (phy == NULL) {
			ret = -ENODEV;
			goto gfar_unreg;
		}

		mdio = of_get_parent(phy);

		id = (u32 *) get_property(phy, "reg", NULL);
		ret = of_address_to_resource(mdio, 0, &res);
		if (ret) {
			of_node_put(phy);
			of_node_put(mdio);
			goto gfar_unreg;
		}

		gfar_data.phy_id = *id;
		gfar_data.bus_id = res.start;

		of_node_put(phy);
		of_node_put(mdio);

		ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data));
		if (ret)
			goto gfar_unreg;
	}

	return 0;

mdio_unreg:
	platform_device_unregister(mdio_dev);
mdio_err:
	return ret;

gfar_unreg:
	platform_device_unregister(gfar_dev);
gfar_err:
	return ret;
}
示例#15
0
static int milkymist_uart_probe(struct platform_device *op)
{
	struct uart_port *port;
	struct device_node *np = op->dev.of_node;
	int ret;
	struct resource res;
	const unsigned int *pid, *clk;
	int id;
	int irq;

	ret = of_address_to_resource(np, 0, &res);
	if (ret) {
		dev_err(&op->dev, "invalid address\n");
		return ret;
	}

	irq = irq_of_parse_and_map(np, 0);

	clk = of_get_property(np, "clock-frequency", NULL);
	if (!clk) {
		dev_warn(&op->dev, "no clock-frequency property set\n");
		return -ENODEV;
	}

	pid = of_get_property(np, "port-number", NULL);

	if (pid)
		id = *pid;
	else {
		/* find free id */
		for (id = 0; id < MILKYMIST_NR_UARTS; id++)
			if (milkymist_uart_ports[id].mapbase == 0)
				break;
	}

	if (id < 0 || id >= MILKYMIST_NR_UARTS) {
		dev_err(&op->dev, "milkymist_uart%i too large\n", id);
		return -EINVAL;
	}

	if (milkymist_uart_ports[id].mapbase
			&& milkymist_uart_ports[id].mapbase != res.start) {
		dev_err(&op->dev, "milkymist_uart%i already in use\n", id);
		return -EBUSY;
	}

	ret = uart_register_driver(&milkymist_uart_driver);
	if (ret) {
		dev_err(&op->dev, "uart_register_driver() failed; err=%i\n", ret);
		return ret;
	}

	port = &milkymist_uart_ports[id];

	spin_lock_init(&port->lock);
	port->line = id;
	port->regshift = 2;
	port->iotype = UPIO_MEM;
	port->mapbase = res.start;
	port->membase = NULL;
	port->flags = UPF_BOOT_AUTOCONF;
	port->irq = irq;

	port->ops = &milkymist_uart_ops;
	port->type = PORT_UNKNOWN;
	port->uartclk = *clk;
	
	port->dev = &op->dev;

	dev_set_drvdata(&op->dev, port);

	ret = uart_add_one_port(&milkymist_uart_driver, port);
	if (ret) {
		dev_err(&op->dev, "uart_add_one_port() failed; err=%i\n", ret);
		port->mapbase = 0;
		return ret;
	}

	//device_init_wakeup(&op->dev, 1);

	return 0;
}
static int __init shm_driver_init(void)
{
	int res, i;
	struct device_node *np;
	struct resource r;
	struct proc_dir_entry *pent = NULL;
	struct proc_dir_entry *pstat = NULL;

	np = of_find_compatible_node(NULL, NULL, "mrvl,berlin-shm");
	if (!np)
		goto err_node;
	res = of_address_to_resource(np, 0, &r);
	if (res)
		goto err_reg_device;
	shm_base_cache = r.start;
	shm_size_cache = resource_size(&r);
	res = of_address_to_resource(np, 1, &r);
	if (res)
		goto err_reg_device;
	shm_base_noncache = r.start;
	shm_size_noncache = resource_size(&r);
	of_node_put(np);
	/* Figure out our device number. */
	res =
	    register_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0),
				   GALOIS_SHM_MINORS, SHM_DEVICE_NAME);
	if (res < 0) {
		shm_error("unable to get shm device major [%d]\n",
			  GALOIS_SHM_MAJOR);
		goto err_reg_device;
	}
	shm_debug("register cdev device major [%d]\n", GALOIS_SHM_MAJOR);

	/* Now setup cdevs. */
	for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) {
		res = shm_driver_setup_cdev(shm_driver_dev_list[i].cdev,
					    GALOIS_SHM_MAJOR,
					    shm_driver_dev_list[i].minor,
					    shm_driver_dev_list[i].fops);
		if (res) {
			shm_error("shm_driver_setup_cdev failed in [%d].\n", i);
			goto err_add_device;
		}
		shm_debug("setup cdevs device minor [%d]\n",
			  shm_driver_dev_list[i].minor);
	}

	/* add shm devices to sysfs */
	shm_dev_class = class_create(THIS_MODULE, SHM_DEVICE_NAME);
	if (IS_ERR(shm_dev_class)) {
		shm_error("class_create failed.\n");
		res = -ENODEV;
		goto err_add_device;
	}

	for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) {
		device_create(shm_dev_class, NULL,
			      MKDEV(GALOIS_SHM_MAJOR,
				    shm_driver_dev_list[i].minor), NULL,
			      shm_driver_dev_list[i].name);
		shm_debug("create device sysfs [%s]\n",
			  shm_driver_dev_list[i].name);
	}

	/* create shm cache device */
	res =
	    shm_device_create(&shm_device, shm_base_cache, shm_size_cache,
			      SHM_DEVICE_THRESHOLD);
	if (res != 0) {
		shm_error("shm_device_create failed.\n");
		goto err_add_device;
	}
	/* init shrinker */
	shm_device->m_shrinker = shm_lowmem_shrink_killer;
	/* create shm cache device */
	res = shm_device_create(&shm_device_noncache, shm_base_noncache,
			      shm_size_noncache, SHM_DEVICE_THRESHOLD);
	if (res != 0) {
		shm_error("shm_device_create failed.\n");
		goto err_add_device;
	}
	/* init shrinker */
	shm_device_noncache->m_shrinker = NULL;
	/* create shm kernel API, need map for noncache and cache device!!! */
	res = MV_SHM_Init(shm_device_noncache, shm_device);
	if (res != 0) {
		shm_error("MV_SHM_Init failed !!!\n");
		goto err_SHM_Init;
	}

	/* create shm device proc file */
	shm_driver_procdir = proc_mkdir(SHM_DEVICE_NAME, NULL);
	if (!shm_driver_procdir) {
		shm_error(KERN_WARNING "Failed to mkdir /proc/%s\n", SHM_DEVICE_NAME);
		return 0;
	}
	proc_create("meminfo", 0, shm_driver_procdir, &meminfo_proc_fops);
	proc_create("baseinfo", 0, shm_driver_procdir, &baseinfo_proc_fops);

	pent = create_proc_entry("detail", 0, shm_driver_procdir);
	if (pent)
		pent->proc_fops = &detail_proc_ops;

	pstat = create_proc_entry("stat", 0, shm_driver_procdir);
	if (pstat)
		pstat->proc_fops = &shm_stat_file_ops;

	task_free_register(&shm_task_nb);
	shm_trace("shm_driver_init OK\n");

	return 0;

 err_SHM_Init:

	shm_trace("shm_driver_init Undo ...\n");

	shm_device_destroy(&shm_device);
	shm_device_destroy(&shm_device_noncache);

	/* del sysfs entries */
	for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) {
		device_destroy(shm_dev_class,
			       MKDEV(GALOIS_SHM_MAJOR,
				     shm_driver_dev_list[i].minor));
		shm_debug("delete device sysfs [%s]\n",
			  shm_driver_dev_list[i].name);
	}
	class_destroy(shm_dev_class);

 err_add_device:

	for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) {
		cdev_del(shm_driver_dev_list[i].cdev);
	}
	unregister_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0), GALOIS_SHM_MINORS);

err_reg_device:
	 of_node_put(np);
err_node:
	shm_trace("shm_driver_init failed !!! (%d)\n", res);

	return res;
}
static int __devinit xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_irq; 
	struct resource r_mem; 
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	
	if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}

	dev_set_drvdata(dev, drvdata);

	spin_lock_init(&drvdata->lock);
	drvdata->irq = r_irq.start;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio = &drvdata->serio;
	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	return 0;		

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return error;
}
示例#18
0
文件: xilinx_ps2.c 项目: 3null/linux
/**
 * xps2_of_probe - probe method for the PS/2 device.
 * @of_dev:	pointer to OF device structure
 * @match:	pointer to the structure used for matching a device
 *
 * This function probes the PS/2 device in the device tree.
 * It initializes the driver data structure and the hardware.
 * It returns 0, if the driver is bound to the PS/2 device, or a negative
 * value if there is an error.
 */
static int xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_mem; /* IO mem resources */
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	unsigned int irq;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	/* Get iospace for the device */
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	/* Get IRQ for the device */
	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
	if (!irq) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!drvdata || !serio) {
		error = -ENOMEM;
		goto failed1;
	}

	spin_lock_init(&drvdata->lock);
	drvdata->irq = irq;
	drvdata->serio = serio;
	drvdata->dev = dev;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	/* Fill in configuration data and add them to the list */
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	/* Disable all the interrupts, just in case */
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	/* Reset the PS2 device and abort any current transaction, to make sure
	 * we have the PS2 in a good state */
	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	platform_set_drvdata(ofdev, drvdata);
	return 0;		/* success */

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(serio);
	kfree(drvdata);

	return error;
}
示例#19
0
文件: cpm1.c 项目: 08opt/linux
unsigned int cpm_pic_init(void)
{
	struct device_node *np = NULL;
	struct resource res;
	unsigned int sirq = NO_IRQ, hwirq, eirq;
	int ret;

	pr_debug("cpm_pic_init\n");

	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic");
	if (np == NULL)
		np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
	if (np == NULL) {
		printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
		return sirq;
	}

	ret = of_address_to_resource(np, 0, &res);
	if (ret)
		goto end;

	cpic_reg = ioremap(res.start, resource_size(&res));
	if (cpic_reg == NULL)
		goto end;

	sirq = irq_of_parse_and_map(np, 0);
	if (sirq == NO_IRQ)
		goto end;

	/* Initialize the CPM interrupt controller. */
	hwirq = (unsigned int)virq_to_hw(sirq);
	out_be32(&cpic_reg->cpic_cicr,
	    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
		((hwirq/2) << 13) | CICR_HP_MASK);

	out_be32(&cpic_reg->cpic_cimr, 0);

	cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
				      64, &cpm_pic_host_ops, 64);
	if (cpm_pic_host == NULL) {
		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
		sirq = NO_IRQ;
		goto end;
	}

	/* Install our own error handler. */
	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
	if (np == NULL)
		np = of_find_node_by_type(NULL, "cpm");
	if (np == NULL) {
		printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
		goto end;
	}

	eirq = irq_of_parse_and_map(np, 0);
	if (eirq == NO_IRQ)
		goto end;

	if (setup_irq(eirq, &cpm_error_irqaction))
		printk(KERN_ERR "Could not allocate CPM error IRQ!");

	setbits32(&cpic_reg->cpic_cicr, CICR_IEN);

end:
	of_node_put(np);
	return sirq;
}
示例#20
0
文件: platform.c 项目: mhei/linux
static struct amba_device *of_amba_device_create(struct device_node *node,
        const char *bus_id,
        void *platform_data,
        struct device *parent)
{
    struct amba_device *dev;
    const void *prop;
    int i, ret;

    pr_debug("Creating amba device %s\n", node->full_name);

    if (!of_device_is_available(node) ||
            of_node_test_and_set_flag(node, OF_POPULATED))
        return NULL;

    dev = amba_device_alloc(NULL, 0, 0);
    if (!dev)
        goto err_clear_flag;

    /* setup generic device info */
    dev->dev.of_node = of_node_get(node);
    dev->dev.fwnode = &node->fwnode;
    dev->dev.parent = parent ? : &platform_bus;
    dev->dev.platform_data = platform_data;
    if (bus_id)
        dev_set_name(&dev->dev, "%s", bus_id);
    else
        of_device_make_bus_id(&dev->dev);
    of_dma_configure(&dev->dev, dev->dev.of_node);

    /* Allow the HW Peripheral ID to be overridden */
    prop = of_get_property(node, "arm,primecell-periphid", NULL);
    if (prop)
        dev->periphid = of_read_ulong(prop, 1);

    /* Decode the IRQs and address ranges */
    for (i = 0; i < AMBA_NR_IRQS; i++)
        dev->irq[i] = irq_of_parse_and_map(node, i);

    ret = of_address_to_resource(node, 0, &dev->res);
    if (ret) {
        pr_err("amba: of_address_to_resource() failed (%d) for %s\n",
               ret, node->full_name);
        goto err_free;
    }

    ret = amba_device_add(dev, &iomem_resource);
    if (ret) {
        pr_err("amba_device_add() failed (%d) for %s\n",
               ret, node->full_name);
        goto err_free;
    }

    return dev;

err_free:
    amba_device_put(dev);
err_clear_flag:
    of_node_clear_flag(node, OF_POPULATED);
    return NULL;
}
示例#21
0
static int __devinit
ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
{
	struct device_node *dn = op->node;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci = NULL;
	struct resource res;
	int irq;
	int rv;

	struct device_node *np;

	if (usb_disabled())
		return -ENODEV;

	dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");

	rv = of_address_to_resource(dn, 0, &res);
	if (rv)
		return rv;

	hcd = usb_create_hcd(&ehci_ppc_of_hc_driver, &op->dev, "PPC-OF USB");
	if (!hcd)
		return -ENOMEM;

	hcd->rsrc_start = res.start;
	hcd->rsrc_len = res.end - res.start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
		rv = -EBUSY;
		goto err_rmr;
	}

	irq = irq_of_parse_and_map(dn, 0);
	if (irq == NO_IRQ) {
		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
		rv = -EBUSY;
		goto err_irq;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_ERR __FILE__ ": ioremap failed\n");
		rv = -ENOMEM;
		goto err_ioremap;
	}

	ehci = hcd_to_ehci(hcd);
	np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
	if (np != NULL) {
		/* claim we really affected by usb23 erratum */
		if (!of_address_to_resource(np, 0, &res))
			ehci->ohci_hcctrl_reg = ioremap(res.start +
					OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN);
		else
			pr_debug(__FILE__ ": no ohci offset in fdt\n");
		if (!ehci->ohci_hcctrl_reg) {
			pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n");
		} else {
			ehci->has_amcc_usb23 = 1;
		}
	}

	if (of_get_property(dn, "big-endian", NULL)) {
		ehci->big_endian_mmio = 1;
		ehci->big_endian_desc = 1;
	}
	if (of_get_property(dn, "big-endian-regs", NULL))
		ehci->big_endian_mmio = 1;
	if (of_get_property(dn, "big-endian-desc", NULL))
		ehci->big_endian_desc = 1;

	ehci->caps = hcd->regs;
	ehci->regs = hcd->regs +
			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));

	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);

	if (of_device_is_compatible(dn, "ibm,usb-ehci-440epx")) {
		rv = ppc44x_enable_bmt(dn);
		ehci_dbg(ehci, "Break Memory Transfer (BMT) is %senabled!\n",
				rv ? "NOT ": "");
	}

	rv = usb_add_hcd(hcd, irq, 0);
	if (rv)
                goto err_ehci;
 
        return 0;
 
err_ehci:
        if (ehci->has_amcc_usb23)
                iounmap(ehci->ohci_hcctrl_reg);
	iounmap(hcd->regs);
err_ioremap:
	irq_dispose_mapping(irq);
err_irq:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_rmr:
	usb_put_hcd(hcd);

	return rv;
}
static int __init xilinx_spi_of_probe(struct of_device *ofdev,
					const struct of_device_id *match)
{
	struct spi_master *master;
	struct xilinx_spi *xspi;
	struct resource r_irq_struct;
	struct resource r_mem_struct;

	struct resource *r_irq = &r_irq_struct;
	struct resource *r_mem = &r_mem_struct;
	int rc = 0;
	const u32 *prop;
	int len;

	/* Get resources(memory, IRQ) associated with the device */
	master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi));

	if (master == NULL) {
		return -ENOMEM;
	}

	dev_set_drvdata(&ofdev->dev, master);

	rc = of_address_to_resource(ofdev->node, 0, r_mem);
	if (rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		goto put_master;
	}

	rc = of_irq_to_resource(ofdev->node, 0, r_irq);
	if (rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found\n");
		goto put_master;
	}

	xspi = spi_master_get_devdata(master);
	xspi->bitbang.master = spi_master_get(master);
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.master->setup = xilinx_spi_setup;
	init_completion(&xspi->done);

	xspi->irq = r_irq->start;

	if (!request_mem_region(r_mem->start,
			r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) {
		rc = -ENXIO;
		dev_warn(&ofdev->dev, "memory request failure\n");
		goto put_master;
	}

	xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
	if (xspi->regs == NULL) {
		rc = -ENOMEM;
		dev_warn(&ofdev->dev, "ioremap failure\n");
		goto put_master;
	}
	xspi->irq = r_irq->start;

	/* dynamic bus assignment */
	master->bus_num = -1;

	/* number of slave select bits is required */
	prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
	if (!prop || len < sizeof(*prop)) {
		dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
		goto put_master;
	}
	master->num_chipselect = *prop;

	/* SPI controller initializations */
	xspi_init_hw(xspi->regs);

	/* Register for SPI Interrupt */
	rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
	if (rc != 0) {
		dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq);
		goto unmap_io;
	}

	rc = spi_bitbang_start(&xspi->bitbang);
	if (rc != 0) {
		dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n");
		goto free_irq;
	}

	dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
			(unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq);

	/* Add any subnodes on the SPI bus */
	of_register_spi_devices(master, ofdev->node);

	return rc;

free_irq:
	free_irq(xspi->irq, xspi);
unmap_io:
	iounmap(xspi->regs);
put_master:
	spi_master_put(master);
	return rc;
}
示例#23
0
/*
 * Setup one port structure after probing, HW is down at this point,
 * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
 * register our console before uart_add_one_port() is called
 */
static int __init pmz_init_port(struct uart_pmac_port *uap)
{
	struct device_node *np = uap->node;
	const char *conn;
	const struct slot_names_prop {
		int	count;
		char	name[1];
	} *slots;
	int len;
	struct resource r_ports, r_rxdma, r_txdma;

	/*
	 * Request & map chip registers
	 */
	if (of_address_to_resource(np, 0, &r_ports))
		return -ENODEV;
	uap->port.mapbase = r_ports.start;
	uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
      
	uap->control_reg = uap->port.membase;
	uap->data_reg = uap->control_reg + 0x10;
	
	/*
	 * Request & map DBDMA registers
	 */
#ifdef HAS_DBDMA
	if (of_address_to_resource(np, 1, &r_txdma) == 0 &&
	    of_address_to_resource(np, 2, &r_rxdma) == 0)
		uap->flags |= PMACZILOG_FLAG_HAS_DMA;
#else
	memset(&r_txdma, 0, sizeof(struct resource));
	memset(&r_rxdma, 0, sizeof(struct resource));
#endif	
	if (ZS_HAS_DMA(uap)) {
		uap->tx_dma_regs = ioremap(r_txdma.start, 0x100);
		if (uap->tx_dma_regs == NULL) {	
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100);
		if (uap->rx_dma_regs == NULL) {	
			iounmap(uap->tx_dma_regs);
			uap->tx_dma_regs = NULL;
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
		uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
	}
no_dma:

	/*
	 * Detect port type
	 */
	if (device_is_compatible(np, "cobalt"))
		uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	conn = get_property(np, "AAPL,connector", &len);
	if (conn && (strcmp(conn, "infrared") == 0))
		uap->flags |= PMACZILOG_FLAG_IS_IRDA;
	uap->port_type = PMAC_SCC_ASYNC;
	/* 1999 Powerbook G3 has slot-names property instead */
	slots = get_property(np, "slot-names", &len);
	if (slots && slots->count > 0) {
		if (strcmp(slots->name, "IrDA") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_IRDA;
		else if (strcmp(slots->name, "Modem") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	}
	if (ZS_IS_IRDA(uap))
		uap->port_type = PMAC_SCC_IRDA;
	if (ZS_IS_INTMODEM(uap)) {
		struct device_node* i2c_modem = find_devices("i2c-modem");
		if (i2c_modem) {
			const char* mid =
				get_property(i2c_modem, "modem-id", NULL);
			if (mid) switch(*mid) {
			case 0x04 :
			case 0x05 :
			case 0x07 :
			case 0x08 :
			case 0x0b :
			case 0x0c :
				uap->port_type = PMAC_SCC_I2S1;
			}
			printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
				mid ? (*mid) : 0);
		} else {
			printk(KERN_INFO "pmac_zilog: serial modem detected\n");
		}
	}

	/*
	 * Init remaining bits of "port" structure
	 */
	uap->port.iotype = UPIO_MEM;
	uap->port.irq = irq_of_parse_and_map(np, 0);
	uap->port.uartclk = ZS_CLOCK;
	uap->port.fifosize = 1;
	uap->port.ops = &pmz_pops;
	uap->port.type = PORT_PMAC_ZILOG;
	uap->port.flags = 0;

	/* Setup some valid baud rate information in the register
	 * shadows so we don't write crap there before baud rate is
	 * first initialized.
	 */
	pmz_convert_to_zs(uap, CS8, 0, 9600);

	return 0;
}
示例#24
0
static int __devinit ehci_hcd_grlib_probe(struct platform_device *op)
{
	struct device_node *dn = op->dev.of_node;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci = NULL;
	struct resource res;
	u32 hc_capbase;
	int irq;
	int rv;

	if (usb_disabled())
		return -ENODEV;

	dev_dbg(&op->dev, "initializing GRUSBHC EHCI USB Controller\n");

	rv = of_address_to_resource(dn, 0, &res);
	if (rv)
		return rv;

	/* usb_create_hcd requires dma_mask != NULL */
	op->dev.dma_mask = &op->dev.coherent_dma_mask;
	hcd = usb_create_hcd(&ehci_grlib_hc_driver, &op->dev,
			"GRUSBHC EHCI USB");
	if (!hcd)
		return -ENOMEM;

	hcd->rsrc_start = res.start;
	hcd->rsrc_len = resource_size(&res);

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
		rv = -EBUSY;
		goto err_rmr;
	}

	irq = irq_of_parse_and_map(dn, 0);
	if (irq == NO_IRQ) {
		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
		rv = -EBUSY;
		goto err_irq;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
		rv = -ENOMEM;
		goto err_ioremap;
	}

	ehci = hcd_to_ehci(hcd);

	ehci->caps = hcd->regs;

	/* determine endianness of this implementation */
	hc_capbase = ehci_readl(ehci, &ehci->caps->hc_capbase);
	if (HC_VERSION(ehci, hc_capbase) != GRUSBHC_HCIVERSION) {
		ehci->big_endian_mmio = 1;
		ehci->big_endian_desc = 1;
		ehci->big_endian_capbase = 1;
	}

	ehci->regs = hcd->regs +
		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));

	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);

	rv = usb_add_hcd(hcd, irq, 0);
	if (rv)
		goto err_ehci;

	return 0;

err_ehci:
	iounmap(hcd->regs);
err_ioremap:
	irq_dispose_mapping(irq);
err_irq:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_rmr:
	usb_put_hcd(hcd);

	return rv;
}
示例#25
0
/*
 * Fill a struct uart_port for a given device node
 */
static int of_platform_serial_setup(struct platform_device *ofdev,
			int type, struct uart_port *port,
			struct of_serial_info *info)
{
	struct resource resource;
	struct device_node *np = ofdev->dev.of_node;
	u32 clk, spd, prop;
	int ret;

	memset(port, 0, sizeof *port);
	if (of_property_read_u32(np, "clock-frequency", &clk)) {

		/* Get clk rate through clk driver if present */
		info->clk = devm_clk_get(&ofdev->dev, NULL);
		if (IS_ERR(info->clk)) {
			dev_warn(&ofdev->dev,
				"clk or clock-frequency not defined\n");
			return PTR_ERR(info->clk);
		}

		ret = clk_prepare_enable(info->clk);
		if (ret < 0)
			return ret;

		clk = clk_get_rate(info->clk);
	}
	/* If current-speed was set, then try not to change it. */
	if (of_property_read_u32(np, "current-speed", &spd) == 0)
		port->custom_divisor = clk / (16 * spd);

	ret = of_address_to_resource(np, 0, &resource);
	if (ret) {
		dev_warn(&ofdev->dev, "invalid address\n");
		goto out;
	}

	spin_lock_init(&port->lock);
	port->mapbase = resource.start;
	port->mapsize = resource_size(&resource);

	/* Check for shifted address mapping */
	if (of_property_read_u32(np, "reg-offset", &prop) == 0)
		port->mapbase += prop;

	/* Check for registers offset within the devices address range */
	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
		port->regshift = prop;

	/* Check for fifo size */
	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
		port->fifosize = prop;

	/* Check for a fixed line number */
	ret = of_alias_get_id(np, "serial");
	if (ret >= 0)
		port->line = ret;

	port->irq = irq_of_parse_and_map(np, 0);
	port->iotype = UPIO_MEM;
	if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
		switch (prop) {
		case 1:
			port->iotype = UPIO_MEM;
			break;
		case 2:
			port->iotype = UPIO_MEM16;
			break;
		case 4:
			port->iotype = of_device_is_big_endian(np) ?
				       UPIO_MEM32BE : UPIO_MEM32;
			break;
		default:
			dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
				 prop);
			ret = -EINVAL;
			goto out;
		}
	}

	port->type = type;
	port->uartclk = clk;
	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
		| UPF_FIXED_PORT | UPF_FIXED_TYPE;

	if (of_find_property(np, "no-loopback-test", NULL))
		port->flags |= UPF_SKIP_TEST;

	port->dev = &ofdev->dev;

	switch (type) {
	case PORT_TEGRA:
		port->handle_break = tegra_serial_handle_break;
		break;

	case PORT_RT2880:
		port->iotype = UPIO_AU;
		break;
	}

	if (IS_ENABLED(CONFIG_SERIAL_8250_FSL) &&
	    (of_device_is_compatible(np, "fsl,ns16550") ||
	     of_device_is_compatible(np, "fsl,16550-FIFO64")))
		port->handle_irq = fsl8250_handle_irq;

	return 0;
out:
	if (info->clk)
		clk_disable_unprepare(info->clk);
	return ret;
}
示例#26
0
/* pasemi_dma_init - Initialize the PA Semi DMA library
 *
 * This function initializes the DMA library. It must be called before
 * any other function in the library.
 *
 * Returns 0 on success, errno on failure.
 */
int pasemi_dma_init(void)
{
	static DEFINE_SPINLOCK(init_lock);
	struct pci_dev *iob_pdev;
	struct pci_dev *pdev;
	struct resource res;
	struct device_node *dn;
	int i, intf, err = 0;
	unsigned long timeout;
	u32 tmp;

	if (!machine_is(pasemi))
		return -ENODEV;

	spin_lock(&init_lock);

	/* Make sure we haven't already initialized */
	if (dma_pdev)
		goto out;

	iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
	if (!iob_pdev) {
		BUG();
		printk(KERN_WARNING "Can't find I/O Bridge\n");
		err = -ENODEV;
		goto out;
	}
	iob_regs = map_onedev(iob_pdev, 0);

	dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
	if (!dma_pdev) {
		BUG();
		printk(KERN_WARNING "Can't find DMA controller\n");
		err = -ENODEV;
		goto out;
	}
	dma_regs = map_onedev(dma_pdev, 0);
	base_hw_irq = virq_to_hw(dma_pdev->irq);

	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp);
	num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S;

	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp);
	num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S;

	intf = 0;
	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL);
	     pdev;
	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev))
		mac_regs[intf++] = map_onedev(pdev, 0);

	pci_dev_put(pdev);

	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL);
	     pdev;
	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev))
		mac_regs[intf++] = map_onedev(pdev, 0);

	pci_dev_put(pdev);

	dn = pci_device_to_OF_node(iob_pdev);
	if (dn)
		err = of_address_to_resource(dn, 1, &res);
	if (!dn || err) {
		/* Fallback for old firmware */
		res.start = 0xfd800000;
		res.end = res.start + 0x1000;
	}
	dma_status = __ioremap(res.start, res.end-res.start, 0);
	pci_dev_put(iob_pdev);

	for (i = 0; i < MAX_TXCH; i++)
		__set_bit(i, txch_free);

	for (i = 0; i < MAX_RXCH; i++)
		__set_bit(i, rxch_free);

	timeout = jiffies + HZ;
	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
	while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) {
		if (time_after(jiffies, timeout)) {
			pr_warning("Warning: Could not disable RX section\n");
			break;
		}
	}

	timeout = jiffies + HZ;
	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
	while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) {
		if (time_after(jiffies, timeout)) {
			pr_warning("Warning: Could not disable TX section\n");
			break;
		}
	}

	/* setup resource allocations for the different DMA sections */
	tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG);
	pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000);

	/* enable tx section */
	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);

	/* enable rx section */
	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);

	for (i = 0; i < MAX_FLAGS; i++)
		__set_bit(i, flags_free);

	for (i = 0; i < MAX_FUN; i++)
		__set_bit(i, fun_free);

	/* clear all status flags */
	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);

	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
		"(%d tx, %d rx channels)\n", num_txch, num_rxch);

out:
	spin_unlock(&init_lock);
	return err;
}
示例#27
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
					  const struct of_device_id *match)
{
	struct edac_device_ctl_info *edac_dev;
	struct mpc85xx_l2_pdata *pdata;
	struct resource r;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
		return -ENOMEM;

	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
					      "cpu", 1, "L", 1, 2, NULL, 0,
					      edac_dev_idx);
	if (!edac_dev) {
		devres_release_group(&op->dev, mpc85xx_l2_err_probe);
		return -ENOMEM;
	}

	pdata = edac_dev->pvt_info;
	pdata->name = "mpc85xx_l2_err";
	pdata->irq = NO_IRQ;
	edac_dev->dev = &op->dev;
	dev_set_drvdata(edac_dev->dev, edac_dev);
	edac_dev->ctl_name = pdata->name;
	edac_dev->dev_name = pdata->name;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "L2 err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

	if (!devm_request_mem_region(&op->dev, r.start,
				     r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->l2_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
	if (!pdata->l2_vbase) {
		printk(KERN_ERR "%s: Unable to setup L2 err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);

	orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);

	/* clear the err_dis */
	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);

	edac_dev->mod_name = EDAC_MOD_STR;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		edac_dev->edac_check = mpc85xx_l2_check;

	mpc85xx_set_l2_sysfs_attributes(edac_dev);

	pdata->edac_idx = edac_dev_idx++;

	if (edac_device_add_device(edac_dev) > 0) {
		debugf3("%s(): failed edac_device_add_device()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_l2_isr, IRQF_DISABLED,
				       "[EDAC] L2 err", edac_dev);
		if (res < 0) {
			printk(KERN_ERR
			       "%s: Unable to requiest irq %d for "
			       "MPC85xx L2 err\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for L2 Err\n",
		       pdata->irq);

		edac_dev->op_state = OP_RUNNING_INTERRUPT;

		out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
	}

	devres_remove_group(&op->dev, mpc85xx_l2_err_probe);

	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");

	return 0;

err2:
	edac_device_del_device(&op->dev);
err:
	devres_release_group(&op->dev, mpc85xx_l2_err_probe);
	edac_device_free_ctl_info(edac_dev);
	return res;
}
static int __devinit
mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
{
	struct device_node *ofn_sram;
	struct resource res_bcom;

	int rv;

	/* Inform user we're ok so far */
	printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");

	/* Get the bestcomm node */
	of_node_get(op->dev.of_node);

	/* Prepare SRAM */
	ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids);
	if (!ofn_sram) {
		printk(KERN_ERR DRIVER_NAME ": "
			"No SRAM found in device tree\n");
		rv = -ENODEV;
		goto error_ofput;
	}
	rv = bcom_sram_init(ofn_sram, DRIVER_NAME);
	of_node_put(ofn_sram);

	if (rv) {
		printk(KERN_ERR DRIVER_NAME ": "
			"Error in SRAM init\n");
		goto error_ofput;
	}

	/* Get a clean struct */
	bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL);
	if (!bcom_eng) {
		printk(KERN_ERR DRIVER_NAME ": "
			"Can't allocate state structure\n");
		rv = -ENOMEM;
		goto error_sramclean;
	}

	/* Save the node */
	bcom_eng->ofnode = op->dev.of_node;

	/* Get, reserve & map io */
	if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) {
		printk(KERN_ERR DRIVER_NAME ": "
			"Can't get resource\n");
		rv = -EINVAL;
		goto error_sramclean;
	}

	if (!request_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma),
				DRIVER_NAME)) {
		printk(KERN_ERR DRIVER_NAME ": "
			"Can't request registers region\n");
		rv = -EBUSY;
		goto error_sramclean;
	}

	bcom_eng->regs_base = res_bcom.start;
	bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma));
	if (!bcom_eng->regs) {
		printk(KERN_ERR DRIVER_NAME ": "
			"Can't map registers\n");
		rv = -ENOMEM;
		goto error_release;
	}

	/* Now, do the real init */
	rv = bcom_engine_init();
	if (rv)
		goto error_unmap;

	/* Done ! */
	printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n",
		(long)bcom_eng->regs_base);

	return 0;

	/* Error path */
error_unmap:
	iounmap(bcom_eng->regs);
error_release:
	release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma));
error_sramclean:
	kfree(bcom_eng);
	bcom_sram_cleanup();
error_ofput:
	of_node_put(op->dev.of_node);

	printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n");

	return rv;
}
示例#29
0
static int __devinit pata_of_platform_probe(struct of_device *ofdev,
					    const struct of_device_id *match)
{
	int ret;
	struct device_node *dn = ofdev->dev.of_node;
	struct resource io_res;
	struct resource ctl_res;
	struct resource irq_res;
	unsigned int reg_shift = 0;
	int pio_mode = 0;
	int pio_mask;
	const u32 *prop;

	ret = of_address_to_resource(dn, 0, &io_res);
	if (ret) {
		dev_err(&ofdev->dev, "can't get IO address from "
			"device tree\n");
		return -EINVAL;
	}

	if (of_device_is_compatible(dn, "electra-ide")) {
		/* Altstatus is really at offset 0x3f6 from the primary window
		 * on electra-ide. Adjust ctl_res and io_res accordingly.
		 */
		ctl_res = io_res;
		ctl_res.start = ctl_res.start+0x3f6;
		io_res.end = ctl_res.start-1;
	} else {
		ret = of_address_to_resource(dn, 1, &ctl_res);
		if (ret) {
			dev_err(&ofdev->dev, "can't get CTL address from "
				"device tree\n");
			return -EINVAL;
		}
	}

	ret = of_irq_to_resource(dn, 0, &irq_res);
	if (ret == NO_IRQ)
		irq_res.start = irq_res.end = 0;
	else
		irq_res.flags = 0;

	prop = of_get_property(dn, "reg-shift", NULL);
	if (prop)
		reg_shift = *prop;

	prop = of_get_property(dn, "pio-mode", NULL);
	if (prop) {
		pio_mode = *prop;
		if (pio_mode > 6) {
			dev_err(&ofdev->dev, "invalid pio-mode\n");
			return -EINVAL;
		}
	} else {
		dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
	}

	pio_mask = 1 << pio_mode;
	pio_mask |= (1 << pio_mode) - 1;

	return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res,
				     reg_shift, pio_mask);
}
示例#30
0
void u8540_clk_init(void)
{
	struct clk *clk;
	struct device_node *np = NULL;
	u32 bases[CLKRST_MAX];
	int i;

	if (of_have_populated_dt())
		np = of_find_matching_node(NULL, u8540_clk_of_match);
	if (!np) {
		pr_err("Either DT or U8540 Clock node not found\n");
		return;
	}
	for (i = 0; i < ARRAY_SIZE(bases); i++) {
		struct resource r;

		if (of_address_to_resource(np, i, &r))
			/* Not much choice but to continue */
			pr_err("failed to get CLKRST %d base address\n",
			       i + 1);
		bases[i] = r.start;
	}

	/* Clock sources. */
	/* Fixed ClockGen */
	clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0,
				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
	clk_register_clkdev(clk, "soc0_pll", NULL);

	clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1,
				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
	clk_register_clkdev(clk, "soc1_pll", NULL);

	clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR,
				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
	clk_register_clkdev(clk, "ddr_pll", NULL);

	clk = clk_register_fixed_rate(NULL, "rtc32k", NULL,
				CLK_IS_ROOT|CLK_IGNORE_UNUSED,
				32768);
	clk_register_clkdev(clk, "clk32k", NULL);
	clk_register_clkdev(clk, "apb_pclk", "rtc-pl031");

	clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL,
				CLK_IS_ROOT|CLK_IGNORE_UNUSED,
				38400000);

	clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "UART");

	/* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */
	clk = clk_reg_prcmu_gate("msp02clk", "ab9540_sysclk12_b1",
			PRCMU_MSP02CLK, 0);
	clk_register_clkdev(clk, NULL, "MSP02");

	clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "MSP1");

	clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "I2C");

	clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "slim");

	clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH1");

	clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH2");

	clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH3");

	clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH5");

	clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH6");

	clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "PERIPH7");

	clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "lcd");
	clk_register_clkdev(clk, "lcd", "mcde");

	clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK,
				CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "bml");

	clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);

	clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);

	clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "hdmi");
	clk_register_clkdev(clk, "hdmi", "mcde");

	clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "apeat");

	clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK,
				CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "apetrace");

	clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "mcde");
	clk_register_clkdev(clk, "mcde", "mcde");
	clk_register_clkdev(clk, NULL, "dsilink.0");
	clk_register_clkdev(clk, NULL, "dsilink.1");
	clk_register_clkdev(clk, NULL, "dsilink.2");

	clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK,
				CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "ipi2");

	clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK,
				CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "dsialt");

	clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "dma40.0");

	clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "b2r2");
	clk_register_clkdev(clk, NULL, "b2r2_core");
	clk_register_clkdev(clk, NULL, "U8500-B2R2.0");
	clk_register_clkdev(clk, NULL, "b2r2_1_core");

	clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "tv");
	clk_register_clkdev(clk, "tv", "mcde");

	clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "SSP");

	clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "rngclk");

	clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "uicc");

	clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "mtu0");
	clk_register_clkdev(clk, NULL, "mtu1");

	clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL,
					PRCMU_SDMMCCLK, 100000000,
					CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdmmc");

	clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL,
					PRCMU_SDMMCHCLK, 400000000,
					CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdmmchclk");

	clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "hva");

	clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, CLK_IS_ROOT);
	clk_register_clkdev(clk, NULL, "g1");

	clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0,
				CLK_IS_ROOT|CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsilcd", "mcde");

	clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
				PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsihs2", "mcde");
	clk_register_clkdev(clk, "hs_clk", "dsilink.2");

	clk = clk_reg_prcmu_scalable("dsilcd_pll", "spare1clk",
				PRCMU_PLLDSI_LCD, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsilcd_pll", "mcde");

	clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll",
				PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsihs0", "mcde");

	clk = clk_reg_prcmu_scalable("dsi0lcdclk", "dsilcd_pll",
				PRCMU_DSI0CLK_LCD, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsihs0", "mcde");
	clk_register_clkdev(clk, "hs_clk", "dsilink.0");

	clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll",
				PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsihs1", "mcde");

	clk = clk_reg_prcmu_scalable("dsi1lcdclk", "dsilcd_pll",
				PRCMU_DSI1CLK_LCD, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "dsihs1", "mcde");
	clk_register_clkdev(clk, "hs_clk", "dsilink.1");

	clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk",
				PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "lp_clk", "dsilink.0");
	clk_register_clkdev(clk, "dsilp0", "mcde");

	clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk",
				PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "lp_clk", "dsilink.1");
	clk_register_clkdev(clk, "dsilp1", "mcde");

	clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk",
				PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, "lp_clk", "dsilink.2");
	clk_register_clkdev(clk, "dsilp2", "mcde");

	clk = clk_reg_prcmu_scalable_rate("armss", NULL,
				PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED);
	clk_register_clkdev(clk, "armss", NULL);

	clk = clk_register_fixed_factor(NULL, "smp_twd", "armss",
				CLK_IGNORE_UNUSED, 1, 2);
	clk_register_clkdev(clk, NULL, "smp_twd");

	/* PRCC P-clocks */
	/* Peripheral 1 : PRCC P-clocks */
	clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", bases[CLKRST1_INDEX],
				BIT(0), 0);
	clk_register_clkdev(clk, "apb_pclk", "uart0");

	clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", bases[CLKRST1_INDEX],
				BIT(1), 0);
	clk_register_clkdev(clk, "apb_pclk", "uart1");

	clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", bases[CLKRST1_INDEX],
				BIT(2), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1");

	clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", bases[CLKRST1_INDEX],
				BIT(3), 0);
	clk_register_clkdev(clk, "apb_pclk", "msp0");
	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.0");

	clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", bases[CLKRST1_INDEX],
				BIT(4), 0);
	clk_register_clkdev(clk, "apb_pclk", "msp1");
	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.1");

	clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", bases[CLKRST1_INDEX],
				BIT(5), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi0");

	clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", bases[CLKRST1_INDEX],
				BIT(6), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2");

	clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", bases[CLKRST1_INDEX],
				BIT(7), 0);
	clk_register_clkdev(clk, NULL, "spi3");

	clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", bases[CLKRST1_INDEX],
				BIT(8), 0);
	clk_register_clkdev(clk, "apb_pclk", "slimbus0");

	clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", bases[CLKRST1_INDEX],
				BIT(9), 0);
	clk_register_clkdev(clk, NULL, "gpio.0");
	clk_register_clkdev(clk, NULL, "gpio.1");
	clk_register_clkdev(clk, NULL, "gpioblock0");
	clk_register_clkdev(clk, "apb_pclk", "ab85xx-codec.0");

	clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", bases[CLKRST1_INDEX],
				BIT(10), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4");

	clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", bases[CLKRST1_INDEX],
				BIT(11), 0);
	clk_register_clkdev(clk, "apb_pclk", "msp3");
	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.3");

	/* Peripheral 2 : PRCC P-clocks */
	clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", bases[CLKRST2_INDEX],
				BIT(0), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3");

	clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", bases[CLKRST2_INDEX],
				BIT(1), 0);
	clk_register_clkdev(clk, NULL, "spi2");

	clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", bases[CLKRST2_INDEX],
				BIT(2), 0);
	clk_register_clkdev(clk, NULL, "spi1");

	clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", bases[CLKRST2_INDEX],
				BIT(3), 0);
	clk_register_clkdev(clk, NULL, "pwl");

	clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", bases[CLKRST2_INDEX],
				BIT(4), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi4");

	clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", bases[CLKRST2_INDEX],
				BIT(5), 0);
	clk_register_clkdev(clk, "apb_pclk", "msp2");
	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.2");

	clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", bases[CLKRST2_INDEX],
				BIT(6), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi1");

	clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", bases[CLKRST2_INDEX],
				BIT(7), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi3");

	clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", bases[CLKRST2_INDEX],
				BIT(8), 0);
	clk_register_clkdev(clk, NULL, "spi0");

	clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", bases[CLKRST2_INDEX],
				BIT(9), 0);
	clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0");

	clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", bases[CLKRST2_INDEX],
				BIT(10), 0);
	clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0");

	clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", bases[CLKRST2_INDEX],
				BIT(11), 0);
	clk_register_clkdev(clk, NULL, "gpio.6");
	clk_register_clkdev(clk, NULL, "gpio.7");
	clk_register_clkdev(clk, NULL, "gpioblock1");

	clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", bases[CLKRST2_INDEX],
				BIT(12), 0);
	clk_register_clkdev(clk, "msp4-pclk", "ab85xx-codec.0");

	/* Peripheral 3 : PRCC P-clocks */
	clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", bases[CLKRST3_INDEX],
				BIT(0), 0);
	clk_register_clkdev(clk, NULL, "fsmc");

	clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", bases[CLKRST3_INDEX],
				BIT(1), 0);
	clk_register_clkdev(clk, "apb_pclk", "ssp0");

	clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", bases[CLKRST3_INDEX],
				BIT(2), 0);
	clk_register_clkdev(clk, "apb_pclk", "ssp1");

	clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", bases[CLKRST3_INDEX],
				BIT(3), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0");

	clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", bases[CLKRST3_INDEX],
				BIT(4), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi2");

	clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", bases[CLKRST3_INDEX],
				BIT(5), 0);
	clk_register_clkdev(clk, "apb_pclk", "ske");
	clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad");

	clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", bases[CLKRST3_INDEX],
				BIT(6), 0);
	clk_register_clkdev(clk, "apb_pclk", "uart2");

	clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", bases[CLKRST3_INDEX],
				BIT(7), 0);
	clk_register_clkdev(clk, "apb_pclk", "sdi5");

	clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", bases[CLKRST3_INDEX],
				BIT(8), 0);
	clk_register_clkdev(clk, NULL, "gpio.2");
	clk_register_clkdev(clk, NULL, "gpio.3");
	clk_register_clkdev(clk, NULL, "gpio.4");
	clk_register_clkdev(clk, NULL, "gpio.5");
	clk_register_clkdev(clk, NULL, "gpioblock2");

	clk = clk_reg_prcc_pclk("p3_pclk9", "per3clk", bases[CLKRST3_INDEX],
				BIT(9), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.5");

	clk = clk_reg_prcc_pclk("p3_pclk10", "per3clk", bases[CLKRST3_INDEX],
				BIT(10), 0);
	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.6");

	clk = clk_reg_prcc_pclk("p3_pclk11", "per3clk", bases[CLKRST3_INDEX],
				BIT(11), 0);
	clk_register_clkdev(clk, "apb_pclk", "uart3");

	clk = clk_reg_prcc_pclk("p3_pclk12", "per3clk", bases[CLKRST3_INDEX],
				BIT(12), 0);
	clk_register_clkdev(clk, "apb_pclk", "uart4");

	/* Peripheral 5 : PRCC P-clocks */
	clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", bases[CLKRST5_INDEX],
				BIT(0), 0);
	clk_register_clkdev(clk, "usb", "musb-ux500.0");
	clk_register_clkdev(clk, "usbclk", "ab-iddet.0");

	clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", bases[CLKRST5_INDEX],
				BIT(1), 0);
	clk_register_clkdev(clk, NULL, "gpio.8");
	clk_register_clkdev(clk, NULL, "gpioblock3");

	/* Peripheral 6 : PRCC P-clocks */
	clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", bases[CLKRST6_INDEX],
				BIT(0), 0);
	clk_register_clkdev(clk, "apb_pclk", "rng");

	clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", bases[CLKRST6_INDEX],
				BIT(1), 0);
	clk_register_clkdev(clk, NULL, "cryp0");
	clk_register_clkdev(clk, NULL, "cryp1");

	clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", bases[CLKRST6_INDEX],
				BIT(2), 0);
	clk_register_clkdev(clk, NULL, "hash0");

	clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", bases[CLKRST6_INDEX],
				BIT(3), 0);
	clk_register_clkdev(clk, NULL, "pka");

	clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", bases[CLKRST6_INDEX],
				BIT(4), 0);
	clk_register_clkdev(clk, NULL, "db8540-hash1");

	clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", bases[CLKRST6_INDEX],
				BIT(5), 0);
	clk_register_clkdev(clk, NULL, "cfgreg");

	clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", bases[CLKRST6_INDEX],
				BIT(6), 0);
	clk_register_clkdev(clk, "apb_pclk", "mtu0");

	clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", bases[CLKRST6_INDEX],
				BIT(7), 0);
	clk_register_clkdev(clk, "apb_pclk", "mtu1");

	/*
	 * PRCC K-clocks  ==> see table PRCC_PCKEN/PRCC_KCKEN
	 * This differs from the internal implementation:
	 * We don't use the PERPIH[n| clock as parent, since those _should_
	 * only be used as parents for the P-clocks.
	 * TODO: "parentjoin" with corresponding P-clocks for all K-clocks.
	 */

	/* Peripheral 1 : PRCC K-clocks */
	clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk",
			bases[CLKRST1_INDEX], BIT(0), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "uart0");

	clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk",
			bases[CLKRST1_INDEX], BIT(1), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "uart1");

	clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
			bases[CLKRST1_INDEX], BIT(2), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.1");

	clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
			bases[CLKRST1_INDEX], BIT(3), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "msp0");
	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.0");

	clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
			bases[CLKRST1_INDEX], BIT(4), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "msp1");
	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.1");

	clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmchclk",
			bases[CLKRST1_INDEX], BIT(5), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi0");

	clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
			bases[CLKRST1_INDEX], BIT(6), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.2");

	clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
			bases[CLKRST1_INDEX], BIT(8), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "slimbus0");

	clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
			bases[CLKRST1_INDEX], BIT(9), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.4");

	clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
			bases[CLKRST1_INDEX], BIT(10), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "msp3");
	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.3");

	/* Peripheral 2 : PRCC K-clocks */
	clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
			bases[CLKRST2_INDEX], BIT(0), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.3");

	clk = clk_reg_prcc_kclk("p2_pwl_kclk", "rtc32k",
			bases[CLKRST2_INDEX], BIT(1), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "pwl");

	clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmchclk",
			bases[CLKRST2_INDEX], BIT(2), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi4");

	clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
			bases[CLKRST2_INDEX], BIT(3), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "msp2");
	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.2");

	clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmchclk",
			bases[CLKRST2_INDEX], BIT(4), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi1");

	clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk",
			bases[CLKRST2_INDEX], BIT(5), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi3");

	clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk",
			bases[CLKRST2_INDEX], BIT(6),
			CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
	clk_register_clkdev(clk, "hsir_hsirxclk", "ste_hsi.0");

	clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk",
			bases[CLKRST2_INDEX], BIT(7),
			CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
	clk_register_clkdev(clk, "hsit_hsitxclk", "ste_hsi.0");

	/* Should only be 9540, but might be added for 85xx as well */
	clk = clk_reg_prcc_kclk("p2_msp4_kclk", "msp02clk",
			bases[CLKRST2_INDEX], BIT(9), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "msp4");
	clk_register_clkdev(clk, "msp4", "ab85xx-codec.0");

	/* Peripheral 3 : PRCC K-clocks */
	clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
			bases[CLKRST3_INDEX], BIT(1), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "ssp0");

	clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
			bases[CLKRST3_INDEX], BIT(2), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "ssp1");

	clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
			bases[CLKRST3_INDEX], BIT(3), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.0");

	clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmchclk",
			bases[CLKRST3_INDEX], BIT(4), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi2");

	clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k",
			bases[CLKRST3_INDEX], BIT(5), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "ske");
	clk_register_clkdev(clk, NULL, "nmk-ske-keypad");

	clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk",
			bases[CLKRST3_INDEX], BIT(6), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "uart2");

	clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk",
			bases[CLKRST3_INDEX], BIT(7), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "sdi5");

	clk = clk_reg_prcc_kclk("p3_i2c5_kclk", "i2cclk",
			bases[CLKRST3_INDEX], BIT(8), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.5");

	clk = clk_reg_prcc_kclk("p3_i2c6_kclk", "i2cclk",
			bases[CLKRST3_INDEX], BIT(9), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "nmk-i2c.6");

	clk = clk_reg_prcc_kclk("p3_uart3_kclk", "uartclk",
			bases[CLKRST3_INDEX], BIT(10), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "uart3");

	clk = clk_reg_prcc_kclk("p3_uart4_kclk", "uartclk",
			bases[CLKRST3_INDEX], BIT(11), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "uart4");

	/* Peripheral 6 : PRCC K-clocks */
	clk = clk_reg_prcc_kclk("p6_rng_kclk", "rngclk",
			bases[CLKRST6_INDEX], BIT(0), CLK_SET_RATE_GATE);
	clk_register_clkdev(clk, NULL, "rng");
}