Loading drivers/interconnect/qcom/holi.c +55 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ #include "icc-rpm.h" #include "rpm-ids.h" static LIST_HEAD(qnoc_probe_list); static DEFINE_MUTEX(probe_list_lock); static int probe_count; static const struct clk_bulk_data bus_clocks[] = { { .id = "bus" }, { .id = "bus_a" }, Loading Loading @@ -1232,6 +1237,9 @@ static int qnoc_probe(struct platform_device *pdev) provider->data = data; qp->dev = &pdev->dev; qp->init = true; qp->keepalive = of_property_read_bool(dev->of_node, "qcom,keepalive"); qp->regmap = qcom_icc_map(pdev, desc); if (IS_ERR(qp->regmap)) return PTR_ERR(qp->regmap); Loading Loading @@ -1269,6 +1277,11 @@ static int qnoc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qp); dev_info(dev, "Registered HOLI ICC\n"); mutex_lock(&probe_list_lock); list_add_tail(&qp->probe_list, &qnoc_probe_list); mutex_unlock(&probe_list_lock); return 0; err: list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) { Loading Loading @@ -1314,12 +1327,54 @@ static const struct of_device_id qnoc_of_match[] = { }; MODULE_DEVICE_TABLE(of, qnoc_of_match); static void qnoc_sync_state(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct qcom_icc_provider *qp = platform_get_drvdata(pdev); int ret, i; mutex_lock(&probe_list_lock); probe_count++; if (probe_count < ARRAY_SIZE(qnoc_of_match) - 1) { mutex_unlock(&probe_list_lock); return; } list_for_each_entry(qp, &qnoc_probe_list, probe_list) { qp->init = false; if (!qp->keepalive) continue; for (i = 0; i < RPM_NUM_CXT; i++) { if (i == RPM_ACTIVE_CXT) { if (qp->bus_clk_cur_rate[i] == 0) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MIN_LEVEL); else ret = clk_set_rate(qp->bus_clks[i].clk, qp->bus_clk_cur_rate[i]); } if (ret) pr_err("%s clk_set_rate error: %d\n", qp->bus_clks[i].id, ret); } } mutex_unlock(&probe_list_lock); pr_err("HOLI ICC Sync State done\n"); } static struct platform_driver qnoc_driver = { .probe = qnoc_probe, .remove = qnoc_remove, .driver = { .name = "qnoc-holi", .of_match_table = qnoc_of_match, .sync_state = qnoc_sync_state, }, }; Loading drivers/interconnect/qcom/icc-rpm.c +15 −2 Original line number Diff line number Diff line Loading @@ -130,8 +130,21 @@ int qcom_icc_rpm_set(struct icc_node *src, struct icc_node *dst) for (i = 0; i < RPM_NUM_CXT; i++) { if (qp->bus_clk_cur_rate[i] != bus_clk_rate[i]) { if (qp->keepalive && i == RPM_ACTIVE_CXT) { if (qp->init) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MAX_LEVEL); else if (bus_clk_rate[i] == 0) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MIN_LEVEL); else ret = clk_set_rate(qp->bus_clks[i].clk, bus_clk_rate[i]); } else { ret = clk_set_rate(qp->bus_clks[i].clk, bus_clk_rate[i]); } if (ret) { pr_err("%s clk_set_rate error: %d\n", qp->bus_clks[i].id, ret); Loading drivers/interconnect/qcom/icc-rpm.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #define RPM_SLEEP_SET MSM_RPM_CTX_SLEEP_SET #define RPM_ACTIVE_SET MSM_RPM_CTX_ACTIVE_SET #define RPM_CLK_MAX_LEVEL INT_MAX #define RPM_CLK_MIN_LEVEL 19200000 #define to_qcom_provider(_provider) \ container_of(_provider, struct qcom_icc_provider, provider) Loading Loading @@ -45,14 +47,19 @@ enum qcom_icc_rpm_context { * @bus_clks: the clk_bulk_data table of bus clocks * @num_clks: the total number of clk_bulk_data entries * @bus_clk_cur_rate: current frequency of bus clock * @keepalive: flag used to indicate whether a keepalive is required * @init: flag to determine when init has completed. */ struct qcom_icc_provider { struct icc_provider provider; struct device *dev; struct regmap *regmap; struct list_head probe_list; struct clk_bulk_data *bus_clks; int num_clks; u64 bus_clk_cur_rate[RPM_NUM_CXT]; bool keepalive; bool init; }; /** Loading Loading
drivers/interconnect/qcom/holi.c +55 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ #include "icc-rpm.h" #include "rpm-ids.h" static LIST_HEAD(qnoc_probe_list); static DEFINE_MUTEX(probe_list_lock); static int probe_count; static const struct clk_bulk_data bus_clocks[] = { { .id = "bus" }, { .id = "bus_a" }, Loading Loading @@ -1232,6 +1237,9 @@ static int qnoc_probe(struct platform_device *pdev) provider->data = data; qp->dev = &pdev->dev; qp->init = true; qp->keepalive = of_property_read_bool(dev->of_node, "qcom,keepalive"); qp->regmap = qcom_icc_map(pdev, desc); if (IS_ERR(qp->regmap)) return PTR_ERR(qp->regmap); Loading Loading @@ -1269,6 +1277,11 @@ static int qnoc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qp); dev_info(dev, "Registered HOLI ICC\n"); mutex_lock(&probe_list_lock); list_add_tail(&qp->probe_list, &qnoc_probe_list); mutex_unlock(&probe_list_lock); return 0; err: list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) { Loading Loading @@ -1314,12 +1327,54 @@ static const struct of_device_id qnoc_of_match[] = { }; MODULE_DEVICE_TABLE(of, qnoc_of_match); static void qnoc_sync_state(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct qcom_icc_provider *qp = platform_get_drvdata(pdev); int ret, i; mutex_lock(&probe_list_lock); probe_count++; if (probe_count < ARRAY_SIZE(qnoc_of_match) - 1) { mutex_unlock(&probe_list_lock); return; } list_for_each_entry(qp, &qnoc_probe_list, probe_list) { qp->init = false; if (!qp->keepalive) continue; for (i = 0; i < RPM_NUM_CXT; i++) { if (i == RPM_ACTIVE_CXT) { if (qp->bus_clk_cur_rate[i] == 0) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MIN_LEVEL); else ret = clk_set_rate(qp->bus_clks[i].clk, qp->bus_clk_cur_rate[i]); } if (ret) pr_err("%s clk_set_rate error: %d\n", qp->bus_clks[i].id, ret); } } mutex_unlock(&probe_list_lock); pr_err("HOLI ICC Sync State done\n"); } static struct platform_driver qnoc_driver = { .probe = qnoc_probe, .remove = qnoc_remove, .driver = { .name = "qnoc-holi", .of_match_table = qnoc_of_match, .sync_state = qnoc_sync_state, }, }; Loading
drivers/interconnect/qcom/icc-rpm.c +15 −2 Original line number Diff line number Diff line Loading @@ -130,8 +130,21 @@ int qcom_icc_rpm_set(struct icc_node *src, struct icc_node *dst) for (i = 0; i < RPM_NUM_CXT; i++) { if (qp->bus_clk_cur_rate[i] != bus_clk_rate[i]) { if (qp->keepalive && i == RPM_ACTIVE_CXT) { if (qp->init) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MAX_LEVEL); else if (bus_clk_rate[i] == 0) ret = clk_set_rate(qp->bus_clks[i].clk, RPM_CLK_MIN_LEVEL); else ret = clk_set_rate(qp->bus_clks[i].clk, bus_clk_rate[i]); } else { ret = clk_set_rate(qp->bus_clks[i].clk, bus_clk_rate[i]); } if (ret) { pr_err("%s clk_set_rate error: %d\n", qp->bus_clks[i].id, ret); Loading
drivers/interconnect/qcom/icc-rpm.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #define RPM_SLEEP_SET MSM_RPM_CTX_SLEEP_SET #define RPM_ACTIVE_SET MSM_RPM_CTX_ACTIVE_SET #define RPM_CLK_MAX_LEVEL INT_MAX #define RPM_CLK_MIN_LEVEL 19200000 #define to_qcom_provider(_provider) \ container_of(_provider, struct qcom_icc_provider, provider) Loading Loading @@ -45,14 +47,19 @@ enum qcom_icc_rpm_context { * @bus_clks: the clk_bulk_data table of bus clocks * @num_clks: the total number of clk_bulk_data entries * @bus_clk_cur_rate: current frequency of bus clock * @keepalive: flag used to indicate whether a keepalive is required * @init: flag to determine when init has completed. */ struct qcom_icc_provider { struct icc_provider provider; struct device *dev; struct regmap *regmap; struct list_head probe_list; struct clk_bulk_data *bus_clks; int num_clks; u64 bus_clk_cur_rate[RPM_NUM_CXT]; bool keepalive; bool init; }; /** Loading