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:

committad av
Gerrit - the friendly Code Review server

förälder
4758d42c05
incheckning
4b0b134192
@@ -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);
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
Referens i nytt ärende
Block a user