clk-scu.c (5392c5de096a1cad7cc06265a8cbf18de2da22c7) | clk-scu.c (5964012ce37e66d2588a9bc82f7184a008851cac) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* | 1// SPDX-License-Identifier: GPL-2.0+ 2/* |
3 * Copyright 2018 NXP | 3 * Copyright 2018-2021 NXP |
4 * Dong Aisheng <aisheng.dong@nxp.com> 5 */ 6 7#include <dt-bindings/firmware/imx/rsrc.h> 8#include <linux/arm-smccc.h> | 4 * Dong Aisheng <aisheng.dong@nxp.com> 5 */ 6 7#include <dt-bindings/firmware/imx/rsrc.h> 8#include <linux/arm-smccc.h> |
9#include <linux/bsearch.h> |
|
9#include <linux/clk-provider.h> 10#include <linux/err.h> 11#include <linux/of_platform.h> 12#include <linux/platform_device.h> 13#include <linux/pm_domain.h> 14#include <linux/pm_runtime.h> 15#include <linux/slab.h> 16 17#include "clk-scu.h" 18 19#define IMX_SIP_CPUFREQ 0xC2000001 20#define IMX_SIP_SET_CPUFREQ 0x00 21 22static struct imx_sc_ipc *ccm_ipc_handle; 23static struct device_node *pd_np; 24static struct platform_driver imx_clk_scu_driver; | 10#include <linux/clk-provider.h> 11#include <linux/err.h> 12#include <linux/of_platform.h> 13#include <linux/platform_device.h> 14#include <linux/pm_domain.h> 15#include <linux/pm_runtime.h> 16#include <linux/slab.h> 17 18#include "clk-scu.h" 19 20#define IMX_SIP_CPUFREQ 0xC2000001 21#define IMX_SIP_SET_CPUFREQ 0x00 22 23static struct imx_sc_ipc *ccm_ipc_handle; 24static struct device_node *pd_np; 25static struct platform_driver imx_clk_scu_driver; |
26static const struct imx_clk_scu_rsrc_table *rsrc_table; |
|
25 26struct imx_scu_clk_node { 27 const char *name; 28 u32 rsrc; 29 u8 clk_type; 30 const char * const *parents; 31 int num_parents; 32 --- 129 unchanged lines hidden (view full) --- 162 u8 autog; 163} __packed __aligned(4); 164 165static inline struct clk_scu *to_clk_scu(struct clk_hw *hw) 166{ 167 return container_of(hw, struct clk_scu, hw); 168} 169 | 27 28struct imx_scu_clk_node { 29 const char *name; 30 u32 rsrc; 31 u8 clk_type; 32 const char * const *parents; 33 int num_parents; 34 --- 129 unchanged lines hidden (view full) --- 164 u8 autog; 165} __packed __aligned(4); 166 167static inline struct clk_scu *to_clk_scu(struct clk_hw *hw) 168{ 169 return container_of(hw, struct clk_scu, hw); 170} 171 |
170int imx_clk_scu_init(struct device_node *np) | 172static inline int imx_scu_clk_search_cmp(const void *rsrc, const void *rsrc_p) |
171{ | 173{ |
174 return *(u32 *)rsrc - *(u32 *)rsrc_p; 175} 176 177static bool imx_scu_clk_is_valid(u32 rsrc_id) 178{ 179 void *p; 180 181 if (!rsrc_table) 182 return true; 183 184 p = bsearch(&rsrc_id, rsrc_table->rsrc, rsrc_table->num, 185 sizeof(rsrc_table->rsrc[0]), imx_scu_clk_search_cmp); 186 187 return p != NULL; 188} 189 190int imx_clk_scu_init(struct device_node *np, 191 const struct imx_clk_scu_rsrc_table *data) 192{ |
|
172 u32 clk_cells; 173 int ret, i; 174 175 ret = imx_scu_get_handle(&ccm_ipc_handle); 176 if (ret) 177 return ret; 178 179 of_property_read_u32(np, "#clock-cells", &clk_cells); 180 181 if (clk_cells == 2) { 182 for (i = 0; i < IMX_SC_R_LAST; i++) 183 INIT_LIST_HEAD(&imx_scu_clks[i]); 184 185 /* pd_np will be used to attach power domains later */ 186 pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd"); 187 if (!pd_np) 188 return -EINVAL; | 193 u32 clk_cells; 194 int ret, i; 195 196 ret = imx_scu_get_handle(&ccm_ipc_handle); 197 if (ret) 198 return ret; 199 200 of_property_read_u32(np, "#clock-cells", &clk_cells); 201 202 if (clk_cells == 2) { 203 for (i = 0; i < IMX_SC_R_LAST; i++) 204 INIT_LIST_HEAD(&imx_scu_clks[i]); 205 206 /* pd_np will be used to attach power domains later */ 207 pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd"); 208 if (!pd_np) 209 return -EINVAL; |
210 211 rsrc_table = data; |
|
189 } 190 191 return platform_driver_register(&imx_clk_scu_driver); 192} 193 194/* 195 * clk_scu_recalc_rate - Get clock rate for a SCU clock 196 * @hw: clock to get rate for --- 381 unchanged lines hidden (view full) --- 578 .rsrc = rsrc_id, 579 .clk_type = clk_type, 580 .parents = parents, 581 .num_parents = num_parents, 582 }; 583 struct platform_device *pdev; 584 int ret; 585 | 212 } 213 214 return platform_driver_register(&imx_clk_scu_driver); 215} 216 217/* 218 * clk_scu_recalc_rate - Get clock rate for a SCU clock 219 * @hw: clock to get rate for --- 381 unchanged lines hidden (view full) --- 601 .rsrc = rsrc_id, 602 .clk_type = clk_type, 603 .parents = parents, 604 .num_parents = num_parents, 605 }; 606 struct platform_device *pdev; 607 int ret; 608 |
609 if (!imx_scu_clk_is_valid(rsrc_id)) 610 return ERR_PTR(-EINVAL); 611 |
|
586 pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); 587 if (!pdev) { 588 pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n", 589 name, rsrc_id, clk_type); 590 return ERR_PTR(-ENOMEM); 591 } 592 593 ret = platform_device_add_data(pdev, &clk, sizeof(clk)); --- 151 unchanged lines hidden (view full) --- 745 746 if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) 747 return ERR_PTR(-EINVAL); 748 749 clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL); 750 if (!clk_node) 751 return ERR_PTR(-ENOMEM); 752 | 612 pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); 613 if (!pdev) { 614 pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n", 615 name, rsrc_id, clk_type); 616 return ERR_PTR(-ENOMEM); 617 } 618 619 ret = platform_device_add_data(pdev, &clk, sizeof(clk)); --- 151 unchanged lines hidden (view full) --- 771 772 if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) 773 return ERR_PTR(-EINVAL); 774 775 clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL); 776 if (!clk_node) 777 return ERR_PTR(-ENOMEM); 778 |
779 if (!imx_scu_clk_is_valid(rsrc_id)) 780 return ERR_PTR(-EINVAL); 781 |
|
753 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 754 if (!clk) { 755 kfree(clk_node); 756 return ERR_PTR(-ENOMEM); 757 } 758 759 clk->rsrc_id = rsrc_id; 760 clk->gpr_id = gpr_id; --- 33 unchanged lines hidden --- | 782 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 783 if (!clk) { 784 kfree(clk_node); 785 return ERR_PTR(-ENOMEM); 786 } 787 788 clk->rsrc_id = rsrc_id; 789 clk->gpr_id = gpr_id; --- 33 unchanged lines hidden --- |