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; }
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; }
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; }
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; };
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; }
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; }
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; }
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; }