*/
 
 #include <linux/bitfield.h>
+#include <linux/clk-provider.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/interconnect.h>
        bool cancel_throttle;
        struct delayed_work throttle_work;
        struct cpufreq_policy *policy;
+       struct clk_hw cpu_clk;
 
        bool per_core_dcvs;
 
        .ready          = qcom_cpufreq_ready,
 };
 
+static unsigned long qcom_cpufreq_hw_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct qcom_cpufreq_data *data = container_of(hw, struct qcom_cpufreq_data, cpu_clk);
+
+       return qcom_lmh_get_throttle_freq(data);
+}
+
+static const struct clk_ops qcom_cpufreq_hw_clk_ops = {
+       .recalc_rate = qcom_cpufreq_hw_recalc_rate,
+};
+
 static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
 {
+       struct clk_hw_onecell_data *clk_data;
        struct device *dev = &pdev->dev;
        struct device *cpu_dev;
        struct clk *clk;
 
        qcom_cpufreq.soc_data = of_device_get_match_data(dev);
 
+       clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, num_domains), GFP_KERNEL);
+       if (!clk_data)
+               return -ENOMEM;
+
+       clk_data->num = num_domains;
+
        for (i = 0; i < num_domains; i++) {
                struct qcom_cpufreq_data *data = &qcom_cpufreq.data[i];
+               struct clk_init_data clk_init = {};
                struct resource *res;
                void __iomem *base;
 
 
                data->base = base;
                data->res = res;
+
+               /* Register CPU clock for each frequency domain */
+               clk_init.name = kasprintf(GFP_KERNEL, "qcom_cpufreq%d", i);
+               if (!clk_init.name)
+                       return -ENOMEM;
+
+               clk_init.flags = CLK_GET_RATE_NOCACHE;
+               clk_init.ops = &qcom_cpufreq_hw_clk_ops;
+               data->cpu_clk.init = &clk_init;
+
+               ret = devm_clk_hw_register(dev, &data->cpu_clk);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to register clock %d: %d\n", i, ret);
+                       kfree(clk_init.name);
+                       return ret;
+               }
+
+               clk_data->hws[i] = &data->cpu_clk;
+               kfree(clk_init.name);
+       }
+
+       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+       if (ret < 0) {
+               dev_err(dev, "Failed to add clock provider\n");
+               return ret;
        }
 
        ret = cpufreq_register_driver(&cpufreq_qcom_hw_driver);