MLK-16225: clk: imx8: Do not register clocks for unowned resources
Registering clocks for unowned resources can result in lots of pointless scfw errors and potential faults when attempting to use LPCG. Solve this by checking ownership via sc_rm_is_resource_owned and returning -ENODEV from clock registration functions. The top-level clock provider is also modified so that it accepts such errors silently. This is intended for xen but could also be useful for SCFW partitioning. Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> Reviewed-by: Ranjani Vaidyanathan <Ranjani.vaidyanathan@nxp.com>
This commit is contained in:
parent
87c8e7562e
commit
0bf9578916
|
@ -103,6 +103,11 @@ struct clk *imx_clk_divider_scu(const char *name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL);
|
||||
if (!div_clk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -130,6 +135,11 @@ struct clk *imx_clk_divider2_scu(const char *name, const char *parent_name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL);
|
||||
if (!div_clk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -212,6 +222,11 @@ struct clk *imx_clk_divider3_scu(const char *name, const char *parent_name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
div = kzalloc(sizeof(struct clk_divider3_scu), GFP_KERNEL);
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
|
|
@ -174,6 +174,11 @@ struct clk *clk_register_gate_scu(struct device *dev, const char *name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -409,6 +414,11 @@ struct clk *clk_register_gate3_scu(struct device *dev, const char *name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
|
|
@ -43,3 +43,27 @@ int imx8_clk_mu_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc)
|
||||
{
|
||||
/*
|
||||
* A-core resources are special. SCFW reports they are not "owned" by
|
||||
* current partition but linux can still adjust them for cpufreq.
|
||||
*
|
||||
* So force this to return false when running as a VM guest and always
|
||||
* true otherwise.
|
||||
*/
|
||||
if (rsrc == SC_R_A53 || rsrc == SC_R_A72 || rsrc == SC_R_A35) {
|
||||
if (xen_domain() && !xen_initial_domain())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ccm_ipc_handle) {
|
||||
pr_warn("%s: no ipc handle!\n", __func__);
|
||||
/* should have handled -EPROBE_DEFER from clk_mu_init earlier. */
|
||||
return false;
|
||||
}
|
||||
|
||||
return sc_rm_is_resource_owned(ccm_ipc_handle, rsrc);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ extern spinlock_t imx_ccm_lock;
|
|||
extern sc_ipc_t ccm_ipc_handle;
|
||||
|
||||
int imx8_clk_mu_init(void);
|
||||
bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc);
|
||||
|
||||
struct clk *imx_clk_divider_scu(const char *name,
|
||||
sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type);
|
||||
|
|
|
@ -885,7 +885,7 @@ static int imx8qm_clk_probe(struct platform_device *pdev)
|
|||
clks[IMX8QM_HSIO_SATA_EPCS_TX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_tx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 4, FUNCTION_NAME(PD_HSIO_SATA_0));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i]))
|
||||
if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -ENODEV)
|
||||
pr_err("i.MX8QM clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
|
||||
|
|
|
@ -335,6 +335,11 @@ struct clk *clk_register_mux_gpr_scu(struct device *dev, const char *name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
if (rsrc_id >= SC_R_LAST)
|
||||
return NULL;
|
||||
|
||||
|
@ -410,6 +415,11 @@ struct clk *clk_register_mux2_scu(struct device *dev, const char *name,
|
|||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
if (!imx8_clk_is_resource_owned(rsrc_id)) {
|
||||
pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
if (rsrc_id >= SC_R_LAST)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
|
|
Loading…
Reference in a new issue