/* * Set up a CCU. Call the provided ccu_clks_setup callback to * initialize the array of clocks provided by the CCU. */ void __init kona_dt_ccu_setup(struct ccu_data *ccu, struct device_node *node) { struct resource res = { 0 }; resource_size_t range; unsigned int i; int ret; ret = of_address_to_resource(node, 0, &res); if (ret) { pr_err("%s: no valid CCU registers found for %s\n", __func__, node->name); goto out_err; } range = resource_size(&res); if (range > (resource_size_t)U32_MAX) { pr_err("%s: address range too large for %s\n", __func__, node->name); goto out_err; } ccu->range = (u32)range; if (!ccu_data_valid(ccu)) { pr_err("%s: ccu data not valid for %s\n", __func__, node->name); goto out_err; } ccu->base = ioremap(res.start, ccu->range); if (!ccu->base) { pr_err("%s: unable to map CCU registers for %s\n", __func__, node->name); goto out_err; } ccu->node = of_node_get(node); /* * Set up each defined kona clock and save the result in * the clock framework clock array (in ccu->data). Then * register as a provider for these clocks. */ for (i = 0; i < ccu->clk_num; i++) { if (!ccu->kona_clks[i].ccu) continue; kona_clk_setup(&ccu->kona_clks[i]); } ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu); if (ret) { pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, node->name, ret); goto out_err; } if (!kona_ccu_init(ccu)) pr_err("Broadcom %s initialization had errors\n", node->name); return; out_err: kona_ccu_teardown(ccu); pr_err("Broadcom %s setup aborted\n", node->name); }
/* * Set up a CCU. Call the provided ccu_clks_setup callback to * initialize the array of clocks provided by the CCU. */ void __init kona_dt_ccu_setup(struct device_node *node, int (*ccu_clks_setup)(struct ccu_data *)) { struct ccu_data *ccu; struct resource res = { 0 }; resource_size_t range; int ret; ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); if (ccu) ccu->name = kstrdup(node->name, GFP_KERNEL); if (!ccu || !ccu->name) { pr_err("%s: unable to allocate CCU struct for %s\n", __func__, node->name); kfree(ccu); return; } ret = of_address_to_resource(node, 0, &res); if (ret) { pr_err("%s: no valid CCU registers found for %s\n", __func__, node->name); goto out_err; } range = resource_size(&res); if (range > (resource_size_t)U32_MAX) { pr_err("%s: address range too large for %s\n", __func__, node->name); goto out_err; } ccu->range = (u32)range; ccu->base = ioremap(res.start, ccu->range); if (!ccu->base) { pr_err("%s: unable to map CCU registers for %s\n", __func__, node->name); goto out_err; } spin_lock_init(&ccu->lock); INIT_LIST_HEAD(&ccu->links); ccu->node = of_node_get(node); list_add_tail(&ccu->links, &ccu_list); /* Set up clocks array (in ccu->data) */ if (ccu_clks_setup(ccu)) goto out_err; ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data); if (ret) { pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, node->name, ret); goto out_err; } if (!kona_ccu_init(ccu)) pr_err("Broadcom %s initialization had errors\n", node->name); return; out_err: kona_ccu_teardown(ccu); pr_err("Broadcom %s setup aborted\n", node->name); }