mirror of
https://github.com/openwrt/openwrt.git
synced 2025-03-13 07:54:14 +00:00
Update patch with upstream version and automatically refresh with make target/linux/refresh. Also backport one additional fix patch for NAND patch and drop a patch merged upstream. Link: https://github.com/openwrt/openwrt/pull/17725 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
511 lines
14 KiB
Diff
511 lines
14 KiB
Diff
From f81715a4c87c3b75ca2640bb61b6c66506061a64 Mon Sep 17 00:00:00 2001
|
|
From: Luo Jie <quic_luoj@quicinc.com>
|
|
Date: Fri, 3 Jan 2025 15:31:35 +0800
|
|
Subject: [PATCH] clk: qcom: Add CMN PLL clock controller driver for IPQ SoC
|
|
|
|
The CMN PLL clock controller supplies clocks to the hardware
|
|
blocks that together make up the Ethernet function on Qualcomm
|
|
IPQ SoCs and to GCC. The driver is initially supported for
|
|
IPQ9574 SoC.
|
|
|
|
The CMN PLL clock controller expects a reference input clock
|
|
from the on-board Wi-Fi block acting as clock source. The input
|
|
reference clock needs to be configured to one of the supported
|
|
clock rates.
|
|
|
|
The controller supplies a number of fixed-rate output clocks.
|
|
For the IPQ9574, there is one output clock of 353 MHZ to PPE
|
|
(Packet Process Engine) hardware block, three 50 MHZ output
|
|
clocks and an additional 25 MHZ output clock supplied to the
|
|
connected Ethernet devices. The PLL also supplies a 24 MHZ
|
|
clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
|
|
MHZ clock to PCS.
|
|
|
|
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
|
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
|
Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-2-c89fb4d4849d@quicinc.com
|
|
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
|
---
|
|
drivers/clk/qcom/Kconfig | 9 +
|
|
drivers/clk/qcom/Makefile | 1 +
|
|
drivers/clk/qcom/ipq-cmn-pll.c | 435 +++++++++++++++++++++++++++++++++
|
|
3 files changed, 445 insertions(+)
|
|
create mode 100644 drivers/clk/qcom/ipq-cmn-pll.c
|
|
|
|
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
|
|
index 42c257e4c433..2daff198aeb3 100644
|
|
--- a/drivers/clk/qcom/Kconfig
|
|
+++ b/drivers/clk/qcom/Kconfig
|
|
@@ -199,6 +199,15 @@ config IPQ_APSS_6018
|
|
Say Y if you want to support CPU frequency scaling on
|
|
ipq based devices.
|
|
|
|
+config IPQ_CMN_PLL
|
|
+ tristate "IPQ CMN PLL Clock Controller"
|
|
+ help
|
|
+ Support for CMN PLL clock controller on IPQ platform. The
|
|
+ CMN PLL consumes the AHB/SYS clocks from GCC and supplies
|
|
+ the output clocks to the networking hardware and GCC blocks.
|
|
+ Say Y or M if you want to support CMN PLL clock on the IPQ
|
|
+ based devices.
|
|
+
|
|
config IPQ_GCC_4019
|
|
tristate "IPQ4019 Global Clock Controller"
|
|
help
|
|
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
|
|
index 1b749da9c13a..6665049cb8c8 100644
|
|
--- a/drivers/clk/qcom/Makefile
|
|
+++ b/drivers/clk/qcom/Makefile
|
|
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o
|
|
obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
|
|
obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
|
|
obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
|
|
+obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o
|
|
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
|
obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
|
|
obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
|
|
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
|
|
new file mode 100644
|
|
index 000000000000..432d4c4b7aa6
|
|
--- /dev/null
|
|
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
|
|
@@ -0,0 +1,435 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * CMN PLL block expects the reference clock from on-board Wi-Fi block,
|
|
+ * and supplies fixed rate clocks as output to the networking hardware
|
|
+ * blocks and to GCC. The networking related blocks include PPE (packet
|
|
+ * process engine), the externally connected PHY or switch devices, and
|
|
+ * the PCS.
|
|
+ *
|
|
+ * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
|
|
+ * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
|
|
+ * and one clock with 353 MHZ to PPE. The other fixed rate output clocks
|
|
+ * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
|
|
+ * with 31.25 MHZ.
|
|
+ *
|
|
+ * +---------+
|
|
+ * | GCC |
|
|
+ * +--+---+--+
|
|
+ * AHB CLK| |SYS CLK
|
|
+ * V V
|
|
+ * +-------+---+------+
|
|
+ * | +-------------> eth0-50mhz
|
|
+ * REF CLK | IPQ9574 |
|
|
+ * -------->+ +-------------> eth1-50mhz
|
|
+ * | CMN PLL block |
|
|
+ * | +-------------> eth2-50mhz
|
|
+ * | |
|
|
+ * +----+----+----+---+-------------> eth-25mhz
|
|
+ * | | |
|
|
+ * V V V
|
|
+ * GCC PCS NSS/PPE
|
|
+ */
|
|
+
|
|
+#include <linux/bitfield.h>
|
|
+#include <linux/clk-provider.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/err.h>
|
|
+#include <linux/mod_devicetable.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/pm_clock.h>
|
|
+#include <linux/pm_runtime.h>
|
|
+#include <linux/regmap.h>
|
|
+
|
|
+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
|
+
|
|
+#define CMN_PLL_REFCLK_SRC_SELECTION 0x28
|
|
+#define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8)
|
|
+
|
|
+#define CMN_PLL_LOCKED 0x64
|
|
+#define CMN_PLL_CLKS_LOCKED BIT(8)
|
|
+
|
|
+#define CMN_PLL_POWER_ON_AND_RESET 0x780
|
|
+#define CMN_ANA_EN_SW_RSTN BIT(6)
|
|
+
|
|
+#define CMN_PLL_REFCLK_CONFIG 0x784
|
|
+#define CMN_PLL_REFCLK_EXTERNAL BIT(9)
|
|
+#define CMN_PLL_REFCLK_DIV GENMASK(8, 4)
|
|
+#define CMN_PLL_REFCLK_INDEX GENMASK(3, 0)
|
|
+
|
|
+#define CMN_PLL_CTRL 0x78c
|
|
+#define CMN_PLL_CTRL_LOCK_DETECT_EN BIT(15)
|
|
+
|
|
+#define CMN_PLL_DIVIDER_CTRL 0x794
|
|
+#define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0)
|
|
+
|
|
+/**
|
|
+ * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
|
|
+ * @id: Clock specifier to be supplied
|
|
+ * @name: Clock name to be registered
|
|
+ * @rate: Clock rate
|
|
+ */
|
|
+struct cmn_pll_fixed_output_clk {
|
|
+ unsigned int id;
|
|
+ const char *name;
|
|
+ unsigned long rate;
|
|
+};
|
|
+
|
|
+/**
|
|
+ * struct clk_cmn_pll - CMN PLL hardware specific data
|
|
+ * @regmap: hardware regmap.
|
|
+ * @hw: handle between common and hardware-specific interfaces
|
|
+ */
|
|
+struct clk_cmn_pll {
|
|
+ struct regmap *regmap;
|
|
+ struct clk_hw hw;
|
|
+};
|
|
+
|
|
+#define CLK_PLL_OUTPUT(_id, _name, _rate) { \
|
|
+ .id = _id, \
|
|
+ .name = _name, \
|
|
+ .rate = _rate, \
|
|
+}
|
|
+
|
|
+#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
|
|
+
|
|
+static const struct regmap_config ipq_cmn_pll_regmap_config = {
|
|
+ .reg_bits = 32,
|
|
+ .reg_stride = 4,
|
|
+ .val_bits = 32,
|
|
+ .max_register = 0x7fc,
|
|
+ .fast_io = true,
|
|
+};
|
|
+
|
|
+static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
|
|
+ CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
|
|
+ CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
|
|
+ CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
|
|
+ CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
|
|
+ CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
|
|
+ CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
|
|
+ CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
|
|
+ CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
|
|
+ CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
|
|
+};
|
|
+
|
|
+/*
|
|
+ * CMN PLL has the single parent clock, which supports the several
|
|
+ * possible parent clock rates, each parent clock rate is reflected
|
|
+ * by the specific reference index value in the hardware.
|
|
+ */
|
|
+static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
|
|
+{
|
|
+ int index = -EINVAL;
|
|
+
|
|
+ switch (parent_rate) {
|
|
+ case 25000000:
|
|
+ index = 3;
|
|
+ break;
|
|
+ case 31250000:
|
|
+ index = 4;
|
|
+ break;
|
|
+ case 40000000:
|
|
+ index = 6;
|
|
+ break;
|
|
+ case 48000000:
|
|
+ case 96000000:
|
|
+ /*
|
|
+ * Parent clock rate 48 MHZ and 96 MHZ take the same value
|
|
+ * of reference clock index. 96 MHZ needs the source clock
|
|
+ * divider to be programmed as 2.
|
|
+ */
|
|
+ index = 7;
|
|
+ break;
|
|
+ case 50000000:
|
|
+ index = 8;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return index;
|
|
+}
|
|
+
|
|
+static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
|
|
+ unsigned long parent_rate)
|
|
+{
|
|
+ struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
|
+ u32 val, factor;
|
|
+
|
|
+ /*
|
|
+ * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
|
|
+ * by HW according to the parent clock rate.
|
|
+ */
|
|
+ regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
|
|
+ factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
|
|
+
|
|
+ return parent_rate * 2 * factor;
|
|
+}
|
|
+
|
|
+static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
|
|
+ struct clk_rate_request *req)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ /* Validate the rate of the single parent clock. */
|
|
+ ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
|
|
+
|
|
+ return ret < 0 ? ret : 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function is used to initialize the CMN PLL to enable the fixed
|
|
+ * rate output clocks. It is expected to be configured once.
|
|
+ */
|
|
+static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|
+ unsigned long parent_rate)
|
|
+{
|
|
+ struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
|
+ int ret, index;
|
|
+ u32 val;
|
|
+
|
|
+ /*
|
|
+ * Configure the reference input clock selection as per the given
|
|
+ * parent clock. The output clock rates are always of fixed value.
|
|
+ */
|
|
+ index = ipq_cmn_pll_find_freq_index(parent_rate);
|
|
+ if (index < 0)
|
|
+ return index;
|
|
+
|
|
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
|
+ CMN_PLL_REFCLK_INDEX,
|
|
+ FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /*
|
|
+ * Update the source clock rate selection and source clock
|
|
+ * divider as 2 when the parent clock rate is 96 MHZ.
|
|
+ */
|
|
+ if (parent_rate == 96000000) {
|
|
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
|
+ CMN_PLL_REFCLK_DIV,
|
|
+ FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
|
|
+ CMN_PLL_REFCLK_SRC_DIV,
|
|
+ FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ /* Enable PLL locked detect. */
|
|
+ ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
|
|
+ CMN_PLL_CTRL_LOCK_DETECT_EN);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /*
|
|
+ * Reset the CMN PLL block to ensure the updated configurations
|
|
+ * take effect.
|
|
+ */
|
|
+ ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
|
+ CMN_ANA_EN_SW_RSTN);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ usleep_range(1000, 1200);
|
|
+ ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
|
+ CMN_ANA_EN_SW_RSTN);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* Stability check of CMN PLL output clocks. */
|
|
+ return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
|
|
+ (val & CMN_PLL_CLKS_LOCKED),
|
|
+ 100, 100 * USEC_PER_MSEC);
|
|
+}
|
|
+
|
|
+static const struct clk_ops clk_cmn_pll_ops = {
|
|
+ .recalc_rate = clk_cmn_pll_recalc_rate,
|
|
+ .determine_rate = clk_cmn_pll_determine_rate,
|
|
+ .set_rate = clk_cmn_pll_set_rate,
|
|
+};
|
|
+
|
|
+static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
|
|
+{
|
|
+ struct clk_parent_data pdata = { .index = 0 };
|
|
+ struct device *dev = &pdev->dev;
|
|
+ struct clk_init_data init = {};
|
|
+ struct clk_cmn_pll *cmn_pll;
|
|
+ struct regmap *regmap;
|
|
+ void __iomem *base;
|
|
+ int ret;
|
|
+
|
|
+ base = devm_platform_ioremap_resource(pdev, 0);
|
|
+ if (IS_ERR(base))
|
|
+ return ERR_CAST(base);
|
|
+
|
|
+ regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
|
|
+ if (IS_ERR(regmap))
|
|
+ return ERR_CAST(regmap);
|
|
+
|
|
+ cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
|
|
+ if (!cmn_pll)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ init.name = "cmn_pll";
|
|
+ init.parent_data = &pdata;
|
|
+ init.num_parents = 1;
|
|
+ init.ops = &clk_cmn_pll_ops;
|
|
+
|
|
+ cmn_pll->hw.init = &init;
|
|
+ cmn_pll->regmap = regmap;
|
|
+
|
|
+ ret = devm_clk_hw_register(dev, &cmn_pll->hw);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
+ return &cmn_pll->hw;
|
|
+}
|
|
+
|
|
+static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
|
|
+{
|
|
+ const struct cmn_pll_fixed_output_clk *fixed_clk;
|
|
+ struct clk_hw_onecell_data *hw_data;
|
|
+ struct device *dev = &pdev->dev;
|
|
+ struct clk_hw *cmn_pll_hw;
|
|
+ unsigned int num_clks;
|
|
+ struct clk_hw *hw;
|
|
+ int ret, i;
|
|
+
|
|
+ fixed_clk = ipq9574_output_clks;
|
|
+ num_clks = ARRAY_SIZE(ipq9574_output_clks);
|
|
+
|
|
+ hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
|
|
+ GFP_KERNEL);
|
|
+ if (!hw_data)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ /*
|
|
+ * Register the CMN PLL clock, which is the parent clock of
|
|
+ * the fixed rate output clocks.
|
|
+ */
|
|
+ cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
|
|
+ if (IS_ERR(cmn_pll_hw))
|
|
+ return PTR_ERR(cmn_pll_hw);
|
|
+
|
|
+ /* Register the fixed rate output clocks. */
|
|
+ for (i = 0; i < num_clks; i++) {
|
|
+ hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
|
|
+ cmn_pll_hw, 0,
|
|
+ fixed_clk[i].rate);
|
|
+ if (IS_ERR(hw)) {
|
|
+ ret = PTR_ERR(hw);
|
|
+ goto unregister_fixed_clk;
|
|
+ }
|
|
+
|
|
+ hw_data->hws[fixed_clk[i].id] = hw;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Provide the CMN PLL clock. The clock rate of CMN PLL
|
|
+ * is configured to 12 GHZ by DT property assigned-clock-rates-u64.
|
|
+ */
|
|
+ hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
|
|
+ hw_data->num = num_clks + 1;
|
|
+
|
|
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
|
|
+ if (ret)
|
|
+ goto unregister_fixed_clk;
|
|
+
|
|
+ platform_set_drvdata(pdev, hw_data);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+unregister_fixed_clk:
|
|
+ while (i > 0)
|
|
+ clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
|
|
+{
|
|
+ struct device *dev = &pdev->dev;
|
|
+ int ret;
|
|
+
|
|
+ ret = devm_pm_runtime_enable(dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = devm_pm_clk_create(dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /*
|
|
+ * To access the CMN PLL registers, the GCC AHB & SYS clocks
|
|
+ * of CMN PLL block need to be enabled.
|
|
+ */
|
|
+ ret = pm_clk_add(dev, "ahb");
|
|
+ if (ret)
|
|
+ return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
|
|
+
|
|
+ ret = pm_clk_add(dev, "sys");
|
|
+ if (ret)
|
|
+ return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
|
|
+
|
|
+ ret = pm_runtime_resume_and_get(dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* Register CMN PLL clock and fixed rate output clocks. */
|
|
+ ret = ipq_cmn_pll_register_clks(pdev);
|
|
+ pm_runtime_put(dev);
|
|
+ if (ret)
|
|
+ return dev_err_probe(dev, ret,
|
|
+ "Fail to register CMN PLL clocks\n");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
|
|
+{
|
|
+ struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
|
|
+ int i;
|
|
+
|
|
+ /*
|
|
+ * The clock with index CMN_PLL_CLK is unregistered by
|
|
+ * device management.
|
|
+ */
|
|
+ for (i = 0; i < hw_data->num; i++) {
|
|
+ if (i != CMN_PLL_CLK)
|
|
+ clk_hw_unregister(hw_data->hws[i]);
|
|
+ }
|
|
+}
|
|
+
|
|
+static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
|
|
+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
|
+};
|
|
+
|
|
+static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
|
|
+ { .compatible = "qcom,ipq9574-cmn-pll", },
|
|
+ { }
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
|
|
+
|
|
+static struct platform_driver ipq_cmn_pll_clk_driver = {
|
|
+ .probe = ipq_cmn_pll_clk_probe,
|
|
+ .remove_new = ipq_cmn_pll_clk_remove,
|
|
+ .driver = {
|
|
+ .name = "ipq_cmn_pll",
|
|
+ .of_match_table = ipq_cmn_pll_clk_ids,
|
|
+ .pm = &ipq_cmn_pll_pm_ops,
|
|
+ },
|
|
+};
|
|
+module_platform_driver(ipq_cmn_pll_clk_driver);
|
|
+
|
|
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
|
|
+MODULE_LICENSE("GPL");
|
|
--
|
|
2.47.1
|
|
|