Exemplo n.º 1
0
static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
				  struct device *dev)
{
	struct clk *clk;
	int i;
	int error;

	dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);

	error = pm_clk_create(dev);
	if (error) {
		dev_err(dev, "pm_clk_create failed %d\n", error);
		return error;
	}

	i = 0;
	while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
		dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
		error = pm_clk_add_clk(dev, clk);
		if (error) {
			dev_err(dev, "pm_clk_add_clk failed %d\n", error);
			clk_put(clk);
			pm_clk_destroy(dev);
			return error;
		}
	}

	return 0;
}
Exemplo n.º 2
0
static int tegra_aconnect_probe(struct platform_device *pdev)
{
	int ret;

	if (!pdev->dev.of_node)
		return -EINVAL;

	ret = pm_clk_create(&pdev->dev);
	if (ret)
		return ret;

	ret = tegra_aconnect_add_clock(&pdev->dev, "ape");
	if (ret)
		goto clk_destroy;

	ret = tegra_aconnect_add_clock(&pdev->dev, "apb2ape");
	if (ret)
		goto clk_destroy;

	pm_runtime_enable(&pdev->dev);

	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

	dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n");

	return 0;

clk_destroy:
	pm_clk_destroy(&pdev->dev);

	return ret;
}
Exemplo n.º 3
0
static int turingcc_probe(struct platform_device *pdev)
{
	int ret;

	pm_runtime_enable(&pdev->dev);
	ret = pm_clk_create(&pdev->dev);
	if (ret)
		goto disable_pm_runtime;

	ret = pm_clk_add(&pdev->dev, NULL);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to acquire iface clock\n");
		goto destroy_pm_clk;
	}

	ret = qcom_cc_probe(pdev, &turingcc_desc);
	if (ret < 0)
		goto destroy_pm_clk;

	return 0;

destroy_pm_clk:
	pm_clk_destroy(&pdev->dev);

disable_pm_runtime:
	pm_runtime_disable(&pdev->dev);

	return ret;
}
Exemplo n.º 4
0
static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
{
	int ret, i = 0, j = 0;
	struct gdsc *sc = domain_to_gdsc(domain);
	struct of_phandle_args clkspec;
	struct device_node *np = dev->of_node;

	if (!sc->clock_count)
		return 0;

	ret = pm_clk_create(dev);
	if (ret) {
		dev_dbg(dev, "pm_clk_create failed %d\n", ret);
		return ret;
	}

	sc->clks = devm_kcalloc(dev, sc->clock_count, sizeof(sc->clks),
				       GFP_KERNEL);
	if (!sc->clks)
		return -ENOMEM;

	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
					   &clkspec)) {
		if (match(clkspec.args[0], sc->clocks, sc->clock_count)) {
			sc->clks[j] = of_clk_get_from_provider(&clkspec);
			pm_clk_add_clk(dev, sc->clks[j]);
			j++;
		} else if (clkspec.args[0] == sc->root_clock)
			sc->root_clk = of_clk_get_from_provider(&clkspec);
		i++;
	}
	return 0;
};
Exemplo n.º 5
0
int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev)
{
    struct cpg_mssr_clk_domain *pd = cpg_mssr_clk_domain;
    struct device_node *np = dev->of_node;
    struct of_phandle_args clkspec;
    struct clk *clk;
    int i = 0;
    int error;

    if (!pd) {
        dev_dbg(dev, "CPG/MSSR clock domain not yet available\n");
        return -EPROBE_DEFER;
    }

    while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
                                       &clkspec)) {
        if (cpg_mssr_is_pm_clk(&clkspec, pd))
            goto found;

        of_node_put(clkspec.np);
        i++;
    }

    return 0;

found:
    clk = of_clk_get_from_provider(&clkspec);
    of_node_put(clkspec.np);

    if (IS_ERR(clk))
        return PTR_ERR(clk);

    error = pm_clk_create(dev);
    if (error) {
        dev_err(dev, "pm_clk_create failed %d\n", error);
        goto fail_put;
    }

    error = pm_clk_add_clk(dev, clk);
    if (error) {
        dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
        goto fail_destroy;
    }

    return 0;

fail_destroy:
    pm_clk_destroy(dev);
fail_put:
    clk_put(clk);
    return error;
}
Exemplo n.º 6
0
int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct of_phandle_args clkspec;
	struct clk *clk;
	int i = 0;
	int error;

	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
					   &clkspec)) {
		if (of_device_is_compatible(clkspec.np,
					    "renesas,cpg-mstp-clocks"))
			goto found;

		/* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */
		if (of_node_name_eq(clkspec.np, "zb_clk"))
			goto found;

		of_node_put(clkspec.np);
		i++;
	}

	return 0;

found:
	clk = of_clk_get_from_provider(&clkspec);
	of_node_put(clkspec.np);

	if (IS_ERR(clk))
		return PTR_ERR(clk);

	error = pm_clk_create(dev);
	if (error) {
		dev_err(dev, "pm_clk_create failed %d\n", error);
		goto fail_put;
	}

	error = pm_clk_add_clk(dev, clk);
	if (error) {
		dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
		goto fail_destroy;
	}

	return 0;

fail_destroy:
	pm_clk_destroy(dev);
fail_put:
	clk_put(clk);
	return error;
}
Exemplo n.º 7
0
static int gic_get_clocks(struct device *dev, const struct gic_clk_data *data)
{
	unsigned int i;
	int ret;

	if (!dev || !data)
		return -EINVAL;

	ret = pm_clk_create(dev);
	if (ret)
		return ret;

	for (i = 0; i < data->num_clocks; i++) {
		ret = of_pm_clk_add_clk(dev, data->clocks[i]);
		if (ret) {
			dev_err(dev, "failed to add clock %s\n",
				data->clocks[i]);
			pm_clk_destroy(dev);
			return ret;
		}
	}

	return 0;
}
Exemplo n.º 8
0
static int tegra_adma_probe(struct platform_device *pdev)
{
	const struct tegra_adma_chip_data *cdata;
	struct tegra_adma *tdma;
	struct resource	*res;
	struct clk *clk;
	int ret, i;

	cdata = of_device_get_match_data(&pdev->dev);
	if (!cdata) {
		dev_err(&pdev->dev, "device match data not found\n");
		return -ENODEV;
	}

	tdma = devm_kzalloc(&pdev->dev, sizeof(*tdma) + cdata->nr_channels *
			    sizeof(struct tegra_adma_chan), GFP_KERNEL);
	if (!tdma)
		return -ENOMEM;

	tdma->dev = &pdev->dev;
	tdma->nr_channels = cdata->nr_channels;
	platform_set_drvdata(pdev, tdma);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(tdma->base_addr))
		return PTR_ERR(tdma->base_addr);

	ret = pm_clk_create(&pdev->dev);
	if (ret)
		return ret;

	clk = clk_get(&pdev->dev, "d_audio");
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "ADMA clock not found\n");
		ret = PTR_ERR(clk);
		goto clk_destroy;
	}

	ret = pm_clk_add_clk(&pdev->dev, clk);
	if (ret) {
		clk_put(clk);
		goto clk_destroy;
	}

	pm_runtime_enable(&pdev->dev);

	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret < 0)
		goto rpm_disable;

	ret = tegra_adma_init(tdma);
	if (ret)
		goto rpm_put;

	INIT_LIST_HEAD(&tdma->dma_dev.channels);
	for (i = 0; i < tdma->nr_channels; i++) {
		struct tegra_adma_chan *tdc = &tdma->channels[i];

		tdc->chan_addr = tdma->base_addr + ADMA_CH_REG_OFFSET(i);

		tdc->irq = of_irq_get(pdev->dev.of_node, i);
		if (tdc->irq < 0) {
			ret = tdc->irq;
			goto irq_dispose;
		}

		vchan_init(&tdc->vc, &tdma->dma_dev);
		tdc->vc.desc_free = tegra_adma_desc_free;
		tdc->tdma = tdma;
	}

	dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask);
	dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask);
	dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask);

	tdma->dma_dev.dev = &pdev->dev;
	tdma->dma_dev.device_alloc_chan_resources =
					tegra_adma_alloc_chan_resources;
	tdma->dma_dev.device_free_chan_resources =
					tegra_adma_free_chan_resources;
	tdma->dma_dev.device_issue_pending = tegra_adma_issue_pending;
	tdma->dma_dev.device_prep_dma_cyclic = tegra_adma_prep_dma_cyclic;
	tdma->dma_dev.device_config = tegra_adma_slave_config;
	tdma->dma_dev.device_tx_status = tegra_adma_tx_status;
	tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all;
	tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
	tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
	tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
	tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;

	ret = dma_async_device_register(&tdma->dma_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret);
		goto irq_dispose;
	}

	ret = of_dma_controller_register(pdev->dev.of_node,
					 tegra_dma_of_xlate, tdma);
	if (ret < 0) {
		dev_err(&pdev->dev, "ADMA OF registration failed %d\n", ret);
		goto dma_remove;
	}

	pm_runtime_put(&pdev->dev);

	dev_info(&pdev->dev, "Tegra210 ADMA driver registered %d channels\n",
		 tdma->nr_channels);

	return 0;

dma_remove:
	dma_async_device_unregister(&tdma->dma_dev);
irq_dispose:
	while (--i >= 0)
		irq_dispose_mapping(tdma->channels[i].irq);
rpm_put:
	pm_runtime_put_sync(&pdev->dev);
rpm_disable:
	pm_runtime_disable(&pdev->dev);
clk_destroy:
	pm_clk_destroy(&pdev->dev);

	return ret;
}