diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c index 6c890e3b3b4f..fdb84b634254 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c @@ -514,6 +514,10 @@ static int msm_bus_disable_node_qos_clk(struct msm_bus_node_device_type *node) ret = -ENXIO; goto exit_disable_node_qos_clk; } + + for (i = 0; i < node->num_node_qos_clks; i++) + ret = disable_nodeclk(&node->node_qos_clks[i]); + bus_node = to_msm_bus_node(node->node_info->bus_device); for (i = 0; i < bus_node->num_node_qos_clks; i++) @@ -536,6 +540,28 @@ static int msm_bus_enable_node_qos_clk(struct msm_bus_node_device_type *node) } bus_node = to_msm_bus_node(node->node_info->bus_device); + for (i = 0; i < node->num_node_qos_clks; i++) { + if (!node->node_qos_clks[i].enable_only_clk) { + rounded_rate = + clk_round_rate( + node->node_qos_clks[i].clk, 1); + ret = setrate_nodeclk(&node->node_qos_clks[i], + rounded_rate); + if (ret) + MSM_BUS_DBG("%s: Failed set rate clk,node %d\n", + __func__, node->node_info->id); + } + ret = enable_nodeclk(&node->node_qos_clks[i], + node->node_info->bus_device); + if (ret) { + MSM_BUS_DBG("%s: Failed to set Qos Clks ret %d\n", + __func__, ret); + msm_bus_disable_node_qos_clk(node); + goto exit_enable_node_qos_clk; + } + + } + for (i = 0; i < bus_node->num_node_qos_clks; i++) { if (!bus_node->node_qos_clks[i].enable_only_clk) { rounded_rate = diff --git a/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c index 620da95d1be4..571ac98972c1 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -495,6 +495,7 @@ static int get_bus_node_device_data( { bool enable_only; bool setrate_only; + struct device_node *qos_clk_node; node_device->node_info = get_node_info_data(dev_node, pdev); if (IS_ERR_OR_NULL(node_device->node_info)) { @@ -505,7 +506,6 @@ static int get_bus_node_device_data( "qcom,ap-owned"); if (node_device->node_info->is_fab_dev) { - struct device_node *qos_clk_node; dev_dbg(&pdev->dev, "Dev %d\n", node_device->node_info->id); if (!node_device->node_info->virt_dev) { @@ -650,6 +650,21 @@ static int get_bus_node_device_data( setrate_only; } + qos_clk_node = of_get_child_by_name(dev_node, + "qcom,node-qos-clks"); + + if (qos_clk_node) { + if (msm_bus_of_parse_clk_array(qos_clk_node, dev_node, + pdev, + &node_device->node_qos_clks, + &node_device->num_node_qos_clks, + node_device->node_info->id)) { + dev_info(&pdev->dev, "Bypass QoS programming"); + node_device->fabdev->bypass_qos_prg = true; + } + of_node_put(qos_clk_node); + } + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node, "node_clk");