示例#1
0
文件: pm33xx.c 项目: krzk/linux
/*
 * Push the minimal suspend-resume code to SRAM
 */
static int am33xx_pm_alloc_sram(void)
{
	struct device_node *np;
	int ret = 0;

	np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
	if (!np) {
		np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
		if (!np) {
			dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n",
				__func__);
			return -ENODEV;
		}
	}

	sram_pool = of_gen_pool_get(np, "pm-sram", 0);
	if (!sram_pool) {
		dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n",
			__func__);
		ret = -ENODEV;
		goto mpu_put_node;
	}

	sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);
	if (!sram_pool_data) {
		dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n",
			__func__);
		ret = -ENODEV;
		goto mpu_put_node;
	}

	ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);
	if (!ocmcram_location) {
		dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n",
			__func__);
		ret = -ENOMEM;
		goto mpu_put_node;
	}

	ocmcram_location_data = gen_pool_alloc(sram_pool_data,
					       sizeof(struct emif_regs_amx3));
	if (!ocmcram_location_data) {
		dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n");
		gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
		ret = -ENOMEM;
	}

mpu_put_node:
	of_node_put(np);
	return ret;
}
static void *ocram_init_mem(size_t size, void **other)
{
	struct device_node *np;
	struct gen_pool *gp;
	void *sram_addr;
	const char *compat = "altr,ocram-edac";

	if (of_machine_is_compatible("altr,socfpga-arria10"))
		compat = "altr,a10-ocram-edac";

	np = of_find_compatible_node(NULL, NULL, compat);
	if (!np)
		return NULL;

	gp = of_gen_pool_get(np, "iram", 0);
	if (!gp)
		return NULL;
	*other = gp;

	sram_addr = (void *)gen_pool_alloc(gp, size);
	if (!sram_addr)
		return NULL;

	memset(sram_addr, 0, size);
	wmb();	/* Ensure data is written out */

	return sram_addr;
}
示例#3
0
static int mvneta_bm_get_sram(struct device_node *dn,
			      struct mvneta_bm *priv)
{
	priv->bppi_pool = of_gen_pool_get(dn, "internal-mem", 0);
	if (!priv->bppi_pool)
		return -ENOMEM;

	priv->bppi_virt_addr = gen_pool_dma_alloc(priv->bppi_pool,
						  MVNETA_BM_BPPI_SIZE,
						  &priv->bppi_phys_addr);
	if (!priv->bppi_virt_addr)
		return -ENOMEM;

	return 0;
}
示例#4
0
/**
 * snd_malloc_dev_iram - allocate memory from on-chip internal ram
 * @dmab: buffer allocation record to store the allocated data
 * @size: number of bytes to allocate from the iram
 *
 * This function requires iram phandle provided via of_node
 */
static void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size)
{
	struct device *dev = dmab->dev.dev;
	struct gen_pool *pool = NULL;

	dmab->area = NULL;
	dmab->addr = 0;

	if (dev->of_node)
		pool = of_gen_pool_get(dev->of_node, "iram", 0);

	if (!pool)
		return;

	/* Assign the pool into private_data field */
	dmab->private_data = pool;

	dmab->area = gen_pool_dma_alloc(pool, size, &dmab->addr);
}
示例#5
0
static int ti_emif_push_sram(struct device *dev)
{
	struct device_node *np = dev->of_node;

	sram_pool = of_gen_pool_get(np, "sram", 0);

	if (!sram_pool) {
		dev_err(dev, "Unable to get sram pool for ocmcram\n");
		return -ENODEV;
	}

	ocmcram_location = gen_pool_alloc(sram_pool, ti_emif_sram_sz);
	if (!ocmcram_location) {
		dev_err(dev, "Unable to allocate memory from ocmcram\n");
		return -EINVAL;
	}

	/* Save physical address to calculate resume offset during pm init */
	ti_emif_sram_phys = gen_pool_virt_to_phys(sram_pool,
						  ocmcram_location);
	ti_emif_sram_virt = fncpy((void *)ocmcram_location,
				  &ti_emif_sram,
				  ti_emif_sram_sz);

	/*
	 * These functions are called during suspend path while MMU is
	 * still on so add virtual base to offset for absolute address
	 */
	ti_emif_pm.save_context = sram_suspend_address(ti_emif_pm.save_context);
	ti_emif_pm.enter_sr = sram_suspend_address(ti_emif_pm.enter_sr);
	ti_emif_pm.abort_sr = sram_suspend_address(ti_emif_pm.abort_sr);

	/*
	 * These are called during resume path when MMU is not enabled
	 * so physical address is used instead
	 */
	ti_emif_pm.restore_context =
		sram_resume_address(ti_emif_pm.restore_context);
	ti_emif_pm.exit_sr = sram_resume_address(ti_emif_pm.exit_sr);

	return 0;
}
示例#6
0
文件: mmp_tdma.c 项目: AK101111/linux
static int mmp_tdma_probe(struct platform_device *pdev)
{
	enum mmp_tdma_type type;
	const struct of_device_id *of_id;
	struct mmp_tdma_device *tdev;
	struct resource *iores;
	int i, ret;
	int irq = 0, irq_num = 0;
	int chan_num = TDMA_CHANNEL_NUM;
	struct gen_pool *pool = NULL;

	of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
	if (of_id)
		type = (enum mmp_tdma_type) of_id->data;
	else
		type = platform_get_device_id(pdev)->driver_data;

	/* always have couple channels */
	tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
	if (!tdev)
		return -ENOMEM;

	tdev->dev = &pdev->dev;

	for (i = 0; i < chan_num; i++) {
		if (platform_get_irq(pdev, i) > 0)
			irq_num++;
	}

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	tdev->base = devm_ioremap_resource(&pdev->dev, iores);
	if (IS_ERR(tdev->base))
		return PTR_ERR(tdev->base);

	INIT_LIST_HEAD(&tdev->device.channels);

	if (pdev->dev.of_node)
		pool = of_gen_pool_get(pdev->dev.of_node, "asram", 0);
	else
		pool = sram_get_gpool("asram");
	if (!pool) {
		dev_err(&pdev->dev, "asram pool not available\n");
		return -ENOMEM;
	}

	if (irq_num != chan_num) {
		irq = platform_get_irq(pdev, 0);
		ret = devm_request_irq(&pdev->dev, irq,
			mmp_tdma_int_handler, 0, "tdma", tdev);
		if (ret)
			return ret;
	}

	/* initialize channel parameters */
	for (i = 0; i < chan_num; i++) {
		irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
		ret = mmp_tdma_chan_init(tdev, i, irq, type, pool);
		if (ret)
			return ret;
	}

	dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
	dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
	tdev->device.dev = &pdev->dev;
	tdev->device.device_alloc_chan_resources =
					mmp_tdma_alloc_chan_resources;
	tdev->device.device_free_chan_resources =
					mmp_tdma_free_chan_resources;
	tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic;
	tdev->device.device_tx_status = mmp_tdma_tx_status;
	tdev->device.device_issue_pending = mmp_tdma_issue_pending;
	tdev->device.device_config = mmp_tdma_config;
	tdev->device.device_pause = mmp_tdma_pause_chan;
	tdev->device.device_resume = mmp_tdma_resume_chan;
	tdev->device.device_terminate_all = mmp_tdma_terminate_all;
	tdev->device.copy_align = DMAENGINE_ALIGN_8_BYTES;

	dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
	platform_set_drvdata(pdev, tdev);

	ret = dma_async_device_register(&tdev->device);
	if (ret) {
		dev_err(tdev->device.dev, "unable to register\n");
		return ret;
	}

	if (pdev->dev.of_node) {
		ret = of_dma_controller_register(pdev->dev.of_node,
							mmp_tdma_xlate, tdev);
		if (ret) {
			dev_err(tdev->device.dev,
				"failed to register controller\n");
			dma_async_device_unregister(&tdev->device);
		}
	}

	dev_info(tdev->device.dev, "initialized\n");
	return 0;
}
示例#7
0
void socfpga_init_ocram_ecc(void)
{
	struct device_node *np;
	const __be32 *prop;
	u32 ocr_edac_addr, iram_addr, len;
	void __iomem  *mapped_ocr_edac_addr;
	size_t size;
	struct gen_pool *gp;

	if (of_machine_is_compatible("altr,socfpga-arria10")) {
		if (socfpga_init_arria10_ocram_ecc() == 0)
			pr_alert("SOCFPGA: Success Initializing OCRAM ECC for Arria10");
		return;
	}

	np = of_find_compatible_node(NULL, NULL, "altr,ocram-edac");
	if (!np) {
		pr_err("SOCFPGA: Unable to find altr,ocram-edac in dtb\n");
		return;
	}

	prop = of_get_property(np, "reg", &size);
	ocr_edac_addr = be32_to_cpup(prop++);
	len = be32_to_cpup(prop);
	if (!prop || size < sizeof(*prop)) {
		pr_err("SOCFPGA: Unable to find OCRAM ECC mapping in dtb\n");
		return;
	}

	gp = of_gen_pool_get(np, "iram", 0);
	if (!gp) {
		pr_err("SOCFPGA: OCRAM cannot find gen pool\n");
		return;
	}

	np = of_find_compatible_node(NULL, NULL, "mmio-sram");
	if (!np) {
		pr_err("SOCFPGA: Unable to find mmio-sram in dtb\n");
		return;
	}
	/* Determine the OCRAM address and size */
	prop = of_get_property(np, "reg", &size);
	iram_addr = be32_to_cpup(prop++);
	len = be32_to_cpup(prop);

	if (!prop || size < sizeof(*prop)) {
		pr_err("SOCFPGA: Unable to find OCRAM mapping in dtb\n");
		return;
	}

	iram_addr = gen_pool_alloc(gp, len);
	if (iram_addr == 0) {
		pr_err("SOCFPGA: cannot alloc from gen pool\n");
		return;
	}

	memset((void *)iram_addr, 0, len);

	mapped_ocr_edac_addr = ioremap(ocr_edac_addr, 4);

	gen_pool_free(gp, iram_addr, len);

	/* Clear any pending OCRAM ECC interrupts, then enable ECC */
	writel(0x18, mapped_ocr_edac_addr);
	writel(0x19, mapped_ocr_edac_addr);

	iounmap(mapped_ocr_edac_addr);

	pr_alert("SOCFPGA: Success Initializing OCRAM");

	return;
}