mmrm: Adding support for api to check if mmrm is supported

Some of targets doesn't need MMRM but need binary compatibility
with targets which support MMRM.

A new api is added to support such scenarios & to ensure that
MMRM is disabled & MM clients can fall back to clk api.

Change-Id: I72514889bffc48174c18e1e764751d2f4595570e
Signed-off-by: Shivendra Kakrania <shiven@codeaurora.org>
This commit is contained in:
Shivendra Kakrania
2021-10-14 23:24:02 -07:00
committad av Gerrit - the friendly Code Review server
förälder 4758d42c05
incheckning 4b0b134192
3 ändrade filer med 86 tillägg och 7 borttagningar

Visa fil

@@ -35,6 +35,7 @@ struct mmrm_driver_data {
struct mmrm_platform_data *platform_data;
/* clk */
bool is_clk_scaling_supported;
struct mmrm_clk_platform_resources clk_res;
struct mmrm_clk_mgr *clk_mgr;
struct mmrm_clk_mgr_ops *clk_mgr_ops;
@@ -45,6 +46,8 @@ struct mmrm_driver_data {
struct mmrm_platform_data *mmrm_get_platform_data(struct device *dev);
int mmrm_count_clk_clients_frm_dt(struct platform_device *pdev);
int mmrm_read_platform_resources(
struct platform_device *pdev,
struct mmrm_driver_data *drv_data);

Visa fil

@@ -221,6 +221,18 @@ err_load_mmrm_rail_table:
return rc;
}
int mmrm_count_clk_clients_frm_dt(struct platform_device *pdev)
{
u32 size_clk_src = 0, num_clk_src = 0;
of_find_property(pdev->dev.of_node, "mmrm-client-info", &size_clk_src);
num_clk_src = size_clk_src / sizeof(struct nom_clk_src_info);
d_mpr_h("%s: found %d clk_srcs size %d\n",
__func__, num_clk_src, size_clk_src);
return num_clk_src;
}
int mmrm_read_platform_resources(struct platform_device *pdev,
struct mmrm_driver_data *drv_data)
{

Visa fil

@@ -29,6 +29,14 @@
drv_data = (void *) -EPROBE_DEFER; \
}
#define CHECK_SKIP_MMRM_CLK_RSRC(drv_data) \
{ \
if (!drv_data->is_clk_scaling_supported) { \
d_mpr_h("%s: mmrm clk rsrc not supported\n", __func__);\
goto skip_mmrm; \
} \
}
#define MMRM_SYSFS_ENTRY_MAX_LEN PAGE_SIZE
extern int msm_mmrm_debug;
@@ -37,12 +45,31 @@ extern u8 msm_mmrm_allow_multiple_register;
struct mmrm_driver_data *drv_data = (void *) -EPROBE_DEFER;
bool mmrm_client_check_scaling_supported(enum mmrm_client_type client_type, u32 client_domain)
{
if (drv_data == (void *)-EPROBE_DEFER) {
d_mpr_e("%s: mmrm probe_init not done\n", __func__);
goto err_exit;
}
if (client_type == MMRM_CLIENT_CLOCK) {
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
/* TODO: Check for individual domain */
}
return true;
err_exit:
d_mpr_e("%s: error exit\n", __func__);
skip_mmrm:
return false;
}
EXPORT_SYMBOL(mmrm_client_check_scaling_supported);
struct mmrm_client *mmrm_client_register(struct mmrm_client_desc *client_desc)
{
struct mmrm_client *client = NULL;
/* check for null input */
if (!client_desc) {
d_mpr_e("%s: null input descriptor\n", __func__);
@@ -56,6 +83,9 @@ struct mmrm_client *mmrm_client_register(struct mmrm_client_desc *client_desc)
/* check for client type, then register */
if (client_desc->client_type == MMRM_CLIENT_CLOCK) {
/* check for skip mmrm */
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
client = mmrm_clk_client_register(
drv_data->clk_mgr, client_desc);
if (!client) {
@@ -68,6 +98,7 @@ struct mmrm_client *mmrm_client_register(struct mmrm_client_desc *client_desc)
goto err_exit;
}
skip_mmrm:
return client;
err_exit:
@@ -80,7 +111,6 @@ int mmrm_client_deregister(struct mmrm_client *client)
{
int rc = 0;
/* check for null input */
if (!client) {
d_mpr_e("%s: invalid input client\n", __func__);
@@ -95,6 +125,9 @@ int mmrm_client_deregister(struct mmrm_client *client)
/* check for client type, then deregister */
if (client->client_type == MMRM_CLIENT_CLOCK) {
/* check for skip mmrm */
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
rc = mmrm_clk_client_deregister(drv_data->clk_mgr, client);
if (rc != 0) {
d_mpr_e("%s: failed to deregister client\n", __func__);
@@ -105,6 +138,7 @@ int mmrm_client_deregister(struct mmrm_client *client)
__func__, client->client_type);
}
skip_mmrm:
return rc;
err_exit:
@@ -133,6 +167,9 @@ int mmrm_client_set_value(struct mmrm_client *client,
/* check for client type, then set value */
if (client->client_type == MMRM_CLIENT_CLOCK) {
/* check for skip mmrm */
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
rc = mmrm_clk_client_setval(drv_data->clk_mgr, client,
client_data, val);
if (rc != 0) {
@@ -144,6 +181,7 @@ int mmrm_client_set_value(struct mmrm_client *client,
__func__, client->client_type);
}
skip_mmrm:
return rc;
err_exit:
@@ -174,6 +212,9 @@ int mmrm_client_set_value_in_range(struct mmrm_client *client,
/* check for client type, then set value */
if (client->client_type == MMRM_CLIENT_CLOCK) {
/* check for skip mmrm */
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
rc = mmrm_clk_client_setval_inrange(drv_data->clk_mgr,
client, client_data, val);
if (rc != 0) {
@@ -185,6 +226,7 @@ int mmrm_client_set_value_in_range(struct mmrm_client *client,
__func__, client->client_type);
}
skip_mmrm:
return rc;
err_exit:
@@ -213,6 +255,9 @@ int mmrm_client_get_value(struct mmrm_client *client,
/* check for client type, then get value */
if (client->client_type == MMRM_CLIENT_CLOCK) {
/* check for skip mmrm */
CHECK_SKIP_MMRM_CLK_RSRC(drv_data);
rc = mmrm_clk_client_getval(drv_data->clk_mgr,
client, val);
if (rc != 0) {
@@ -224,6 +269,7 @@ int mmrm_client_get_value(struct mmrm_client *client,
__func__, client->client_type);
}
skip_mmrm:
return rc;
err_exit:
@@ -363,6 +409,7 @@ static struct attribute_group mmrm_fs_attrs_group = {
static int msm_mmrm_probe_init(struct platform_device *pdev)
{
int rc = 0;
u32 clk_clients = 0;
drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
if (!drv_data) {
@@ -372,6 +419,19 @@ static int msm_mmrm_probe_init(struct platform_device *pdev)
goto err_no_mem;
}
/* check for clk clients needing admission control */
clk_clients = mmrm_count_clk_clients_frm_dt(pdev);
if (clk_clients) {
d_mpr_h("%s: %d clk clients managed for admission control\n",
__func__, clk_clients);
drv_data->is_clk_scaling_supported = true;
} else {
d_mpr_h("%s: no clk clients managed for admission control\n",
__func__);
drv_data->is_clk_scaling_supported = false;
goto skip_mmrm;
}
drv_data->platform_data = mmrm_get_platform_data(&pdev->dev);
if (!drv_data->platform_data) {
d_mpr_e("%s: unable to get platform data\n",
@@ -405,6 +465,7 @@ static int msm_mmrm_probe_init(struct platform_device *pdev)
__func__);
}
skip_mmrm:
return rc;
err_mmrm_init:
@@ -449,10 +510,13 @@ static int msm_mmrm_remove(struct platform_device *pdev)
return -EINVAL;
}
sysfs_remove_group(&pdev->dev.kobj, &mmrm_fs_attrs_group);
msm_mmrm_debugfs_deinit(drv_data->debugfs_root);
mmrm_deinit(drv_data);
mmrm_free_platform_resources(drv_data);
if (drv_data->is_clk_scaling_supported) {
sysfs_remove_group(&pdev->dev.kobj, &mmrm_fs_attrs_group);
msm_mmrm_debugfs_deinit(drv_data->debugfs_root);
mmrm_deinit(drv_data);
mmrm_free_platform_resources(drv_data);
}
dev_set_drvdata(&pdev->dev, NULL);
RESET_DRV_DATA(drv_data);