* [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
@ 2023-01-10 17:56 ` Konrad Dybcio
2023-01-10 18:54 ` Konrad Dybcio
2023-01-11 1:34 ` Rob Herring
2023-01-10 17:56 ` [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array Konrad Dybcio
` (3 subsequent siblings)
4 siblings, 2 replies; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 17:56 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno, Konrad Dybcio,
AngeloGioacchino Del Regno, Rob Herring, Rob Herring,
Krzysztof Kozlowski, devicetree, linux-kernel
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
Add the bindings for the CPR3 driver to the documentation.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
[Konrad: Add type reference to acc-syscon; update AGdR's email]
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
.../bindings/soc/qcom/qcom,cpr3.yaml | 242 ++++++++++++++++++
1 file changed, 242 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
new file mode 100644
index 000000000000..52e87061a04b
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
@@ -0,0 +1,242 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh)
+
+description: |
+ CPR (Core Power Reduction) is a technology to reduce core power on a CPU
+ or other device. Each OPP of a device corresponds to a "corner" that has
+ a range of valid voltages for a particular frequency. While the device is
+ running at a particular frequency, CPR monitors dynamic factors such as
+ temperature, etc. and suggests or, in the CPR-Hardened case performs,
+ adjustments to the voltage to save power and meet silicon characteristic
+ requirements.
+
+maintainers:
+ - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+properties:
+ compatible:
+ oneOf:
+ - description: CPRv3 controller
+ items:
+ - const: qcom,cpr3
+ - description: CPRv4 controller
+ items:
+ - const: qcom,cpr4
+ - description: CPRv4-Hardened controller
+ items:
+ - enum:
+ - qcom,msm8998-cprh
+ - qcom,sdm630-cprh
+ - const: qcom,cprh
+
+ reg:
+ description: Base address and size of the CPR controller(s)
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: "ref"
+
+ clocks:
+ items:
+ - description: CPR reference clock
+
+ vdd-supply:
+ description: Autonomous Phase Control (APC) or other power supply
+
+ '#power-domain-cells':
+ const: 1
+
+ acc-syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle to syscon for writing ACC settings
+
+ nvmem-cells:
+ description: Cells containing the fuse corners and revision data
+ minItems: 10
+ maxItems: 32
+
+ nvmem-cell-names:
+ minItems: 10
+ maxItems: 32
+
+ operating-points-v2: true
+
+required:
+ - compatible
+ - reg
+ - clock-names
+ - clocks
+ - "#power-domain-cells"
+ - nvmem-cells
+ - nvmem-cell-names
+ - operating-points-v2
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "qcom,kryo280";
+ device_type = "cpu";
+ reg = <0x0 0x0>;
+ operating-points-v2 = <&cpu_gold_opp_table>;
+ power-domains = <&apc_cprh 0>;
+ power-domain-names = "cprh";
+ };
+
+ cpu@100 {
+ compatible = "qcom,kryo280";
+ device_type = "cpu";
+ reg = <0x0 0x0>;
+ operating-points-v2 = <&cpu_silver_opp_table>;
+ power-domains = <&apc_cprh 1>;
+ power-domain-names = "cprh";
+ };
+ };
+
+ cpu_gold_opp_table: opp-table-gold {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ required-opps = <&cprh_opp3>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ required-opps = <&cprh_opp2>;
+ };
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&cprh_opp1>;
+ };
+ };
+
+ cpu_silver_opp_table: opp-table-silver {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1843200000 {
+ opp-hz = /bits/ 64 <1843200000>;
+ required-opps = <&cprh_opp3>;
+ };
+ opp-1094400000 {
+ opp-hz = /bits/ 64 <1094400000>;
+ required-opps = <&cprh_opp2>;
+ };
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&cprh_opp1>;
+ };
+ };
+
+ cprh_opp_table: opp-table-cprh {
+ compatible = "operating-points-v2-qcom-level";
+
+ cprh_opp1: opp1 {
+ opp-level = <1>;
+ qcom,opp-fuse-level = <1>;
+ };
+ cprh_opp2: opp2 {
+ opp-level = <2>;
+ qcom,opp-fuse-level = <2>;
+ };
+ cprh_opp3: opp3 {
+ opp-level = <3>;
+ qcom,opp-fuse-level = <2 3>;
+ };
+ };
+
+ apc_cprh: power-controller@179c8000 {
+ compatible = "qcom,msm8998-cprh", "qcom,cprh";
+ reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>;
+ clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
+ clock-names = "ref";
+
+ #power-domain-cells = <1>;
+ operating-points-v2 = <&cprh_opp_table>;
+
+ nvmem-cells = <&cpr_efuse_speedbin>,
+ <&cpr_fuse_revision>,
+ <&cpr_quot0_pwrcl>,
+ <&cpr_quot1_pwrcl>,
+ <&cpr_quot2_pwrcl>,
+ <&cpr_quot3_pwrcl>,
+ <&cpr_quot_offset1_pwrcl>,
+ <&cpr_quot_offset2_pwrcl>,
+ <&cpr_quot_offset3_pwrcl>,
+ <&cpr_init_voltage0_pwrcl>,
+ <&cpr_init_voltage1_pwrcl>,
+ <&cpr_init_voltage2_pwrcl>,
+ <&cpr_init_voltage3_pwrcl>,
+ <&cpr_ro_sel0_pwrcl>,
+ <&cpr_ro_sel1_pwrcl>,
+ <&cpr_ro_sel2_pwrcl>,
+ <&cpr_ro_sel3_pwrcl>,
+ <&cpr_quot0_perfcl>,
+ <&cpr_quot1_perfcl>,
+ <&cpr_quot2_perfcl>,
+ <&cpr_quot3_perfcl>,
+ <&cpr_quot_offset1_perfcl>,
+ <&cpr_quot_offset2_perfcl>,
+ <&cpr_quot_offset3_perfcl>,
+ <&cpr_init_voltage0_perfcl>,
+ <&cpr_init_voltage1_perfcl>,
+ <&cpr_init_voltage2_perfcl>,
+ <&cpr_init_voltage3_perfcl>,
+ <&cpr_ro_sel0_perfcl>,
+ <&cpr_ro_sel1_perfcl>,
+ <&cpr_ro_sel2_perfcl>,
+ <&cpr_ro_sel3_perfcl>;
+
+ nvmem-cell-names = "cpr_speed_bin",
+ "cpr_fuse_revision",
+ "cpr0_quotient1",
+ "cpr0_quotient2",
+ "cpr0_quotient3",
+ "cpr0_quotient4",
+ "cpr0_quotient_offset2",
+ "cpr0_quotient_offset3",
+ "cpr0_quotient_offset4",
+ "cpr0_init_voltage1",
+ "cpr0_init_voltage2",
+ "cpr0_init_voltage3",
+ "cpr0_init_voltage4",
+ "cpr0_ring_osc1",
+ "cpr0_ring_osc2",
+ "cpr0_ring_osc3",
+ "cpr0_ring_osc4",
+ "cpr1_quotient1",
+ "cpr1_quotient2",
+ "cpr1_quotient3",
+ "cpr1_quotient4",
+ "cpr1_quotient_offset2",
+ "cpr1_quotient_offset3",
+ "cpr1_quotient_offset4",
+ "cpr1_init_voltage1",
+ "cpr1_init_voltage2",
+ "cpr1_init_voltage3",
+ "cpr1_init_voltage4",
+ "cpr1_ring_osc1",
+ "cpr1_ring_osc2",
+ "cpr1_ring_osc3",
+ "cpr1_ring_osc4";
+ };
+...
--
2.39.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
2023-01-10 17:56 ` [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver Konrad Dybcio
@ 2023-01-10 17:56 ` Konrad Dybcio
2023-01-13 1:26 ` Rob Herring
2023-01-10 17:56 ` [PATCH v8 3/5] soc: qcom: cpr: Move common functions to new file Konrad Dybcio
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 17:56 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Niklas Cassel, linux-pm, devicetree,
linux-kernel
In some instances (particularly with CPRh) we might want to specifiy
more than one qcom,opp-fuse-level, as the same OPP subnodes may be
used by different "CPR threads". We need to make sure that
n = num_threads entries is legal and so far nobody seems to use more
than two, so let's allow that.
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml b/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml
index b9ce2e099ce9..a30ef93213c0 100644
--- a/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml
+++ b/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml
@@ -30,7 +30,9 @@ patternProperties:
this OPP node. Sometimes several corners/levels shares a certain fuse
corner/level. A fuse corner/level contains e.g. ref uV, min uV,
and max uV.
- $ref: /schemas/types.yaml#/definitions/uint32
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 2
required:
- opp-level
--
2.39.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v8 3/5] soc: qcom: cpr: Move common functions to new file
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
2023-01-10 17:56 ` [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver Konrad Dybcio
2023-01-10 17:56 ` [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array Konrad Dybcio
@ 2023-01-10 17:56 ` Konrad Dybcio
2023-01-10 17:56 ` [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened Konrad Dybcio
2023-01-10 17:56 ` [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh Konrad Dybcio
4 siblings, 0 replies; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 17:56 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno, Konrad Dybcio,
AngeloGioacchino Del Regno, Niklas Cassel, linux-kernel,
linux-pm
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
In preparation for implementing a new driver that will be handling
CPRv3, CPRv4 and CPR-Hardened, format out common functions to a new
file.
Update cpr_get_fuses in preparation for CPR3 implementation, change
parameters where necessary to not take cpr.c private data structures.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
[Konrad: rebase, apply review comments, don't break backwards compat, improve msg]
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
drivers/soc/qcom/Makefile | 2 +-
drivers/soc/qcom/cpr-common.c | 363 ++++++++++++++++++++++++++++++++
drivers/soc/qcom/cpr-common.h | 108 ++++++++++
drivers/soc/qcom/cpr.c | 386 ++--------------------------------
4 files changed, 494 insertions(+), 365 deletions(-)
create mode 100644 drivers/soc/qcom/cpr-common.c
create mode 100644 drivers/soc/qcom/cpr-common.h
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 3b92c6c8e0ec..ba2b55dd94ff 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -3,7 +3,7 @@ CFLAGS_rpmh-rsc.o := -I$(src)
obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
-obj-$(CONFIG_QCOM_CPR) += cpr.o
+obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
obj-$(CONFIG_QCOM_DCC) += dcc.o
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
diff --git a/drivers/soc/qcom/cpr-common.c b/drivers/soc/qcom/cpr-common.c
new file mode 100644
index 000000000000..7c877b263241
--- /dev/null
+++ b/drivers/soc/qcom/cpr-common.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "cpr-common.h"
+
+int cpr_populate_ring_osc_idx(struct device *dev,
+ struct fuse_corner *fuse_corner,
+ const struct cpr_fuse *cpr_fuse,
+ int num_fuse_corners)
+{
+ struct fuse_corner *end = fuse_corner + num_fuse_corners;
+ u32 data;
+ int ret;
+
+ for (; fuse_corner < end; fuse_corner++, cpr_fuse++) {
+ ret = nvmem_cell_read_variable_le_u32(dev, cpr_fuse->ring_osc, &data);
+ if (ret)
+ return ret;
+ fuse_corner->ring_osc_idx = data;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpr_populate_ring_osc_idx);
+
+static int cpr_read_fuse_uV(int init_v_width, int step_size_uV, int ref_uV,
+ int adj, int step_volt, const char *init_v_efuse,
+ struct device *dev)
+{
+ int steps, uV;
+ u32 bits = 0;
+ int ret;
+
+ ret = nvmem_cell_read_variable_le_u32(dev, init_v_efuse, &bits);
+ if (ret)
+ return ret;
+
+ steps = bits & (BIT(init_v_width - 1) - 1);
+ /* Not two's complement.. instead highest bit is sign bit */
+ if (bits & BIT(init_v_width - 1))
+ steps = -steps;
+
+ uV = ref_uV + steps * step_size_uV;
+
+ /* Apply open-loop fixed adjustments to fused values */
+ uV += adj;
+
+ return DIV_ROUND_UP(uV, step_volt) * step_volt;
+}
+
+const struct cpr_fuse *cpr_get_fuses(struct device *dev, int tid,
+ unsigned int num_fuse_corners)
+{
+ struct cpr_fuse *fuses;
+ unsigned int i;
+ char cpr_name[11]; /* length of "cpr" + length of UINT_MAX (7) + \0 */
+
+ fuses = devm_kcalloc(dev, num_fuse_corners, sizeof(*fuses), GFP_KERNEL);
+ if (!fuses)
+ return ERR_PTR(-ENOMEM);
+
+ /* Support legacy bindings */
+ if (tid == UINT_MAX)
+ snprintf(cpr_name, sizeof(cpr_name), "cpr");
+ else
+ snprintf(cpr_name, sizeof(cpr_name), "cpr%d", tid);
+
+ for (i = 0; i < num_fuse_corners; i++) {
+ char tbuf[50];
+
+ snprintf(tbuf, sizeof(tbuf), "%s_ring_osc%d", cpr_name, i + 1);
+ fuses[i].ring_osc = devm_kstrdup(dev, tbuf, GFP_KERNEL);
+ if (!fuses[i].ring_osc)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(tbuf, sizeof(tbuf), "%s_init_voltage%d", cpr_name, i + 1);
+ fuses[i].init_voltage = devm_kstrdup(dev, tbuf, GFP_KERNEL);
+ if (!fuses[i].init_voltage)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(tbuf, sizeof(tbuf), "%s_quotient%d", cpr_name, i + 1);
+ fuses[i].quotient = devm_kstrdup(dev, tbuf, GFP_KERNEL);
+ if (!fuses[i].quotient)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(tbuf, sizeof(tbuf), "%s_quotient_offset%d", cpr_name, i + 1);
+ fuses[i].quotient_offset = devm_kstrdup(dev, tbuf, GFP_KERNEL);
+ if (!fuses[i].quotient_offset)
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return fuses;
+}
+EXPORT_SYMBOL_GPL(cpr_get_fuses);
+
+int cpr_populate_fuse_common(struct device *dev,
+ struct fuse_corner_data *fdata,
+ const struct cpr_fuse *cpr_fuse,
+ struct fuse_corner *fuse_corner,
+ int step_volt, int init_v_width,
+ int init_v_step)
+{
+ int uV, ret;
+
+ /* Populate uV */
+ uV = cpr_read_fuse_uV(init_v_width, init_v_step,
+ fdata->ref_uV, fdata->volt_oloop_adjust,
+ step_volt, cpr_fuse->init_voltage, dev);
+ if (uV < 0)
+ return uV;
+
+ /*
+ * Update SoC voltages: platforms might choose a different
+ * regulators than the one used to characterize the algorithms
+ * (ie, init_voltage_step).
+ */
+ fdata->min_uV = roundup(fdata->min_uV, step_volt);
+ fdata->max_uV = roundup(fdata->max_uV, step_volt);
+
+ fuse_corner->min_uV = fdata->min_uV;
+ fuse_corner->max_uV = fdata->max_uV;
+ fuse_corner->uV = clamp(uV, fuse_corner->min_uV, fuse_corner->max_uV);
+
+ /* Populate target quotient by scaling */
+ ret = nvmem_cell_read_variable_le_u32(dev, cpr_fuse->quotient, &fuse_corner->quot);
+ if (ret)
+ return ret;
+
+ fuse_corner->quot *= fdata->quot_scale;
+ fuse_corner->quot += fdata->quot_offset;
+ fuse_corner->quot += fdata->quot_adjust;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpr_populate_fuse_common);
+
+int cpr_find_initial_corner(struct device *dev, struct clk *cpu_clk,
+ struct corner *corners, int num_corners)
+{
+ unsigned long rate;
+ struct corner *iter, *corner;
+ const struct corner *end;
+ unsigned int i = 0;
+
+ if (!cpu_clk) {
+ dev_err(dev, "cannot get rate from NULL clk\n");
+ return -EINVAL;
+ }
+
+ end = &corners[num_corners - 1];
+ rate = clk_get_rate(cpu_clk);
+
+ /*
+ * Some bootloaders set a CPU clock frequency that is not defined
+ * in the OPP table. When running at an unlisted frequency,
+ * cpufreq_online() will change to the OPP which has the lowest
+ * frequency, at or above the unlisted frequency.
+ * Since cpufreq_online() always "rounds up" in the case of an
+ * unlisted frequency, this function always "rounds down" in case
+ * of an unlisted frequency. That way, when cpufreq_online()
+ * triggers the first ever call to cpr_set_performance_state(),
+ * it will correctly determine the direction as UP.
+ */
+ for (iter = corners; iter <= end; iter++) {
+ if (iter->freq > rate)
+ break;
+ i++;
+ if (iter->freq == rate) {
+ corner = iter;
+ break;
+ }
+ if (iter->freq < rate)
+ corner = iter;
+ }
+
+ if (!corner) {
+ dev_err(dev, "boot up corner not found\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "boot up perf state: %u\n", i);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpr_find_initial_corner);
+
+unsigned int cpr_get_fuse_corner(struct dev_pm_opp *opp, u32 tid)
+{
+ struct device_node *np;
+ u32 fc;
+
+ np = dev_pm_opp_get_of_node(opp);
+ if (of_property_read_u32_index(np, "qcom,opp-fuse-level", tid, &fc)) {
+ pr_debug("%s: missing 'qcom,opp-fuse-level' property\n",
+ __func__);
+ fc = 0;
+ }
+
+ of_node_put(np);
+
+ return fc;
+}
+EXPORT_SYMBOL_GPL(cpr_get_fuse_corner);
+
+unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
+ struct device *cpu_dev)
+{
+ u64 rate = 0;
+ struct device_node *ref_np;
+ struct device_node *desc_np;
+ struct device_node *child_np = NULL;
+ struct device_node *child_req_np = NULL;
+
+ desc_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+ if (!desc_np)
+ return 0;
+
+ ref_np = dev_pm_opp_get_of_node(ref);
+ if (!ref_np)
+ goto out_ref;
+
+ for_each_available_child_of_node(desc_np, child_np) {
+ child_req_np = of_parse_phandle(child_np, "required-opps", 0);
+
+ if (child_np && child_req_np == ref_np) {
+ of_property_read_u64(child_np, "opp-hz", &rate);
+ goto out;
+ }
+ }
+
+out:
+ of_node_put(child_req_np);
+ of_node_put(child_np);
+ of_node_put(ref_np);
+out_ref:
+ of_node_put(desc_np);
+
+ return (unsigned long) rate;
+}
+EXPORT_SYMBOL_GPL(cpr_get_opp_hz_for_req);
+
+int cpr_calculate_scaling(struct device *dev,
+ const char *quot_offset,
+ const struct fuse_corner_data *fdata,
+ const struct corner *corner)
+{
+ const struct fuse_corner *fuse, *prev_fuse;
+ u64 freq_diff;
+ u32 quot_diff = 0;
+ int scaling, ret;
+
+ fuse = corner->fuse_corner;
+ prev_fuse = fuse - 1;
+
+ if (quot_offset) {
+ ret = nvmem_cell_read_variable_le_u32(dev, quot_offset, "_diff);
+ if (ret)
+ return ret;
+
+ quot_diff *= fdata->quot_offset_scale;
+ quot_diff += fdata->quot_offset_adjust;
+ } else {
+ quot_diff = fuse->quot - prev_fuse->quot;
+ }
+
+ freq_diff = fuse->max_freq - prev_fuse->max_freq;
+ freq_diff = div_u64(freq_diff, 1000000); /* Convert to MHz */
+ scaling = 1000 * quot_diff;
+ do_div(scaling, freq_diff);
+ return min(scaling, fdata->max_quot_scale);
+}
+EXPORT_SYMBOL_GPL(cpr_calculate_scaling);
+
+int cpr_interpolate(const struct corner *corner, int step_volt,
+ const struct fuse_corner_data *fdata)
+{
+ unsigned long f_high, f_low, f_diff;
+ int uV_high, uV_low, uV;
+ u64 temp, temp_limit;
+ const struct fuse_corner *fuse, *prev_fuse;
+
+ fuse = corner->fuse_corner;
+ prev_fuse = fuse - 1;
+
+ f_high = fuse->max_freq;
+ f_low = prev_fuse->max_freq;
+ uV_high = fuse->uV;
+ uV_low = prev_fuse->uV;
+ f_diff = fuse->max_freq - corner->freq;
+
+ /*
+ * Don't interpolate in the wrong direction. This could happen
+ * if the adjusted fuse voltage overlaps with the previous fuse's
+ * adjusted voltage.
+ */
+ if (f_high <= f_low || uV_high <= uV_low || f_high <= corner->freq)
+ return corner->uV;
+
+ temp = f_diff * (uV_high - uV_low);
+ temp = div64_ul(temp, f_high - f_low);
+
+ /*
+ * max_volt_scale has units of uV/MHz while freq values
+ * have units of Hz. Divide by 1000000 to convert to.
+ */
+ temp_limit = f_diff * fdata->max_volt_scale;
+ do_div(temp_limit, 1000000);
+
+ uV = uV_high - min(temp, temp_limit);
+ return roundup(uV, step_volt);
+}
+EXPORT_SYMBOL_GPL(cpr_interpolate);
+
+int cpr_check_vreg_constraints(struct device *dev, struct regulator *vreg,
+ struct fuse_corner *f)
+{
+ int ret;
+
+ ret = regulator_is_supported_voltage(vreg, f->min_uV, f->min_uV);
+ if (!ret) {
+ dev_err(dev, "min uV: %d not supported by regulator\n",
+ f->min_uV);
+ return -EINVAL;
+ }
+
+ ret = regulator_is_supported_voltage(vreg, f->max_uV, f->max_uV);
+ if (!ret) {
+ dev_err(dev, "max uV: %d not supported by regulator\n",
+ f->max_uV);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpr_check_vreg_constraints);
+
+MODULE_DESCRIPTION("Core Power Reduction (CPR) common");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
new file mode 100644
index 000000000000..2cd15f7eac90
--- /dev/null
+++ b/drivers/soc/qcom/cpr-common.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+
+enum voltage_change_dir {
+ NO_CHANGE,
+ DOWN,
+ UP,
+};
+
+struct fuse_corner_data {
+ int ref_uV;
+ int max_uV;
+ int min_uV;
+ int range_uV;
+ /* fuse volt: closed/open loop */
+ int volt_cloop_adjust;
+ int volt_oloop_adjust;
+ int max_volt_scale;
+ int max_quot_scale;
+ /* fuse quot */
+ int quot_offset;
+ int quot_scale;
+ int quot_adjust;
+ /* fuse quot_offset */
+ int quot_offset_scale;
+ int quot_offset_adjust;
+};
+
+struct cpr_fuse {
+ char *ring_osc;
+ char *init_voltage;
+ char *quotient;
+ char *quotient_offset;
+};
+
+struct fuse_corner {
+ int min_uV;
+ int max_uV;
+ int uV;
+ int quot;
+ int step_quot;
+ const struct reg_sequence *accs;
+ int num_accs;
+ unsigned long max_freq;
+ u8 ring_osc_idx;
+};
+
+struct corner {
+ int min_uV;
+ int max_uV;
+ int uV;
+ int last_uV;
+ int quot_adjust;
+ u32 save_ctl;
+ u32 save_irq;
+ unsigned long freq;
+ bool is_open_loop;
+ struct fuse_corner *fuse_corner;
+};
+
+struct corner_data {
+ unsigned int fuse_corner;
+ unsigned long freq;
+};
+
+struct acc_desc {
+ unsigned int enable_reg;
+ u32 enable_mask;
+
+ struct reg_sequence *config;
+ struct reg_sequence *settings;
+ int num_regs_per_fuse;
+};
+
+struct cpr_acc_desc {
+ const struct cpr_desc *cpr_desc;
+ const struct acc_desc *acc_desc;
+};
+
+int cpr_populate_ring_osc_idx(struct device *dev,
+ struct fuse_corner *fuse_corner,
+ const struct cpr_fuse *cpr_fuse,
+ int num_fuse_corners);
+const struct cpr_fuse *cpr_get_fuses(struct device *dev, int tid,
+ unsigned int num_fuse_corners);
+int cpr_populate_fuse_common(struct device *dev,
+ struct fuse_corner_data *fdata,
+ const struct cpr_fuse *cpr_fuse,
+ struct fuse_corner *fuse_corner,
+ int step_volt, int init_v_width,
+ int init_v_step);
+int cpr_find_initial_corner(struct device *dev, struct clk *cpu_clk,
+ struct corner *corners, int num_corners);
+u32 cpr_get_fuse_corner(struct dev_pm_opp *opp, u32 tid);
+unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
+ struct device *cpu_dev);
+int cpr_calculate_scaling(struct device *dev,
+ const char *quot_offset,
+ const struct fuse_corner_data *fdata,
+ const struct corner *corner);
+int cpr_interpolate(const struct corner *corner, int step_volt,
+ const struct fuse_corner_data *fdata);
+int cpr_check_vreg_constraints(struct device *dev, struct regulator *vreg,
+ struct fuse_corner *f);
\ No newline at end of file
diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c
index e9b854ed1bdf..ba53897fcd99 100644
--- a/drivers/soc/qcom/cpr.c
+++ b/drivers/soc/qcom/cpr.c
@@ -26,6 +26,8 @@
#include <linux/clk.h>
#include <linux/nvmem-consumer.h>
+#include "cpr-common.h"
+
/* Register Offsets for RB-CPR and Bit Definitions */
/* RBCPR Version Register */
@@ -124,45 +126,12 @@
#define FUSE_REVISION_UNKNOWN (-1)
-enum voltage_change_dir {
- NO_CHANGE,
- DOWN,
- UP,
-};
-
-struct cpr_fuse {
- char *ring_osc;
- char *init_voltage;
- char *quotient;
- char *quotient_offset;
-};
-
-struct fuse_corner_data {
- int ref_uV;
- int max_uV;
- int min_uV;
- int max_volt_scale;
- int max_quot_scale;
- /* fuse quot */
- int quot_offset;
- int quot_scale;
- int quot_adjust;
- /* fuse quot_offset */
- int quot_offset_scale;
- int quot_offset_adjust;
-};
-
struct cpr_fuses {
int init_voltage_step;
int init_voltage_width;
struct fuse_corner_data *fuse_corner_data;
};
-struct corner_data {
- unsigned int fuse_corner;
- unsigned long freq;
-};
-
struct cpr_desc {
unsigned int num_fuse_corners;
int min_diff_quot;
@@ -184,44 +153,6 @@ struct cpr_desc {
bool reduce_to_corner_uV;
};
-struct acc_desc {
- unsigned int enable_reg;
- u32 enable_mask;
-
- struct reg_sequence *config;
- struct reg_sequence *settings;
- int num_regs_per_fuse;
-};
-
-struct cpr_acc_desc {
- const struct cpr_desc *cpr_desc;
- const struct acc_desc *acc_desc;
-};
-
-struct fuse_corner {
- int min_uV;
- int max_uV;
- int uV;
- int quot;
- int step_quot;
- const struct reg_sequence *accs;
- int num_accs;
- unsigned long max_freq;
- u8 ring_osc_idx;
-};
-
-struct corner {
- int min_uV;
- int max_uV;
- int uV;
- int last_uV;
- int quot_adjust;
- u32 save_ctl;
- u32 save_irq;
- unsigned long freq;
- struct fuse_corner *fuse_corner;
-};
-
struct cpr_drv {
unsigned int num_corners;
unsigned int ref_clk_khz;
@@ -801,50 +732,6 @@ static int cpr_set_performance_state(struct generic_pm_domain *domain,
return ret;
}
-static int
-cpr_populate_ring_osc_idx(struct cpr_drv *drv)
-{
- struct fuse_corner *fuse = drv->fuse_corners;
- struct fuse_corner *end = fuse + drv->desc->num_fuse_corners;
- const struct cpr_fuse *fuses = drv->cpr_fuses;
- u32 data;
- int ret;
-
- for (; fuse < end; fuse++, fuses++) {
- ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->ring_osc, &data);
- if (ret)
- return ret;
- fuse->ring_osc_idx = data;
- }
-
- return 0;
-}
-
-static int cpr_read_fuse_uV(const struct cpr_desc *desc,
- const struct fuse_corner_data *fdata,
- const char *init_v_efuse,
- int step_volt,
- struct cpr_drv *drv)
-{
- int step_size_uV, steps, uV;
- u32 bits = 0;
- int ret;
-
- ret = nvmem_cell_read_variable_le_u32(drv->dev, init_v_efuse, &bits);
- if (ret)
- return ret;
-
- steps = bits & ~BIT(desc->cpr_fuses.init_voltage_width - 1);
- /* Not two's complement.. instead highest bit is sign bit */
- if (bits & BIT(desc->cpr_fuses.init_voltage_width - 1))
- steps = -steps;
-
- step_size_uV = desc->cpr_fuses.init_voltage_step;
-
- uV = fdata->ref_uV + steps * step_size_uV;
- return DIV_ROUND_UP(uV, step_volt) * step_volt;
-}
-
static int cpr_fuse_corner_init(struct cpr_drv *drv)
{
const struct cpr_desc *desc = drv->desc;
@@ -854,7 +741,6 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
unsigned int step_volt;
struct fuse_corner_data *fdata;
struct fuse_corner *fuse, *end;
- int uV;
const struct reg_sequence *accs;
int ret;
@@ -870,23 +756,15 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
fdata = desc->cpr_fuses.fuse_corner_data;
for (i = 0; fuse <= end; fuse++, fuses++, i++, fdata++) {
- /*
- * Update SoC voltages: platforms might choose a different
- * regulators than the one used to characterize the algorithms
- * (ie, init_voltage_step).
- */
- fdata->min_uV = roundup(fdata->min_uV, step_volt);
- fdata->max_uV = roundup(fdata->max_uV, step_volt);
+ ret = cpr_populate_fuse_common(drv->dev, fdata, fuses,
+ fuse, step_volt,
+ desc->cpr_fuses.init_voltage_width,
+ desc->cpr_fuses.init_voltage_step);
+ if (ret)
+ return ret;
- /* Populate uV */
- uV = cpr_read_fuse_uV(desc, fdata, fuses->init_voltage,
- step_volt, drv);
- if (uV < 0)
- return uV;
- fuse->min_uV = fdata->min_uV;
- fuse->max_uV = fdata->max_uV;
- fuse->uV = clamp(uV, fuse->min_uV, fuse->max_uV);
+ fuse->step_quot = desc->step_quot[fuse->ring_osc_idx];
if (fuse == end) {
/*
@@ -924,25 +802,9 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
else if (fuse->uV < fuse->min_uV)
fuse->uV = fuse->min_uV;
- ret = regulator_is_supported_voltage(drv->vdd_apc,
- fuse->min_uV,
- fuse->min_uV);
- if (!ret) {
- dev_err(drv->dev,
- "min uV: %d (fuse corner: %d) not supported by regulator\n",
- fuse->min_uV, i);
- return -EINVAL;
- }
-
- ret = regulator_is_supported_voltage(drv->vdd_apc,
- fuse->max_uV,
- fuse->max_uV);
- if (!ret) {
- dev_err(drv->dev,
- "max uV: %d (fuse corner: %d) not supported by regulator\n",
- fuse->max_uV, i);
- return -EINVAL;
- }
+ ret = cpr_check_vreg_constraints(drv->dev, drv->vdd_apc, fuse);
+ if (ret)
+ return ret;
dev_dbg(drv->dev,
"fuse corner %d: [%d %d %d] RO%hhu quot %d squot %d\n",
@@ -953,126 +815,6 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
return 0;
}
-static int cpr_calculate_scaling(const char *quot_offset,
- struct cpr_drv *drv,
- const struct fuse_corner_data *fdata,
- const struct corner *corner)
-{
- u32 quot_diff = 0;
- unsigned long freq_diff;
- int scaling;
- const struct fuse_corner *fuse, *prev_fuse;
- int ret;
-
- fuse = corner->fuse_corner;
- prev_fuse = fuse - 1;
-
- if (quot_offset) {
- ret = nvmem_cell_read_variable_le_u32(drv->dev, quot_offset, "_diff);
- if (ret)
- return ret;
-
- quot_diff *= fdata->quot_offset_scale;
- quot_diff += fdata->quot_offset_adjust;
- } else {
- quot_diff = fuse->quot - prev_fuse->quot;
- }
-
- freq_diff = fuse->max_freq - prev_fuse->max_freq;
- freq_diff /= 1000000; /* Convert to MHz */
- scaling = 1000 * quot_diff / freq_diff;
- return min(scaling, fdata->max_quot_scale);
-}
-
-static int cpr_interpolate(const struct corner *corner, int step_volt,
- const struct fuse_corner_data *fdata)
-{
- unsigned long f_high, f_low, f_diff;
- int uV_high, uV_low, uV;
- u64 temp, temp_limit;
- const struct fuse_corner *fuse, *prev_fuse;
-
- fuse = corner->fuse_corner;
- prev_fuse = fuse - 1;
-
- f_high = fuse->max_freq;
- f_low = prev_fuse->max_freq;
- uV_high = fuse->uV;
- uV_low = prev_fuse->uV;
- f_diff = fuse->max_freq - corner->freq;
-
- /*
- * Don't interpolate in the wrong direction. This could happen
- * if the adjusted fuse voltage overlaps with the previous fuse's
- * adjusted voltage.
- */
- if (f_high <= f_low || uV_high <= uV_low || f_high <= corner->freq)
- return corner->uV;
-
- temp = f_diff * (uV_high - uV_low);
- temp = div64_ul(temp, f_high - f_low);
-
- /*
- * max_volt_scale has units of uV/MHz while freq values
- * have units of Hz. Divide by 1000000 to convert to.
- */
- temp_limit = f_diff * fdata->max_volt_scale;
- do_div(temp_limit, 1000000);
-
- uV = uV_high - min(temp, temp_limit);
- return roundup(uV, step_volt);
-}
-
-static unsigned int cpr_get_fuse_corner(struct dev_pm_opp *opp)
-{
- struct device_node *np;
- unsigned int fuse_corner = 0;
-
- np = dev_pm_opp_get_of_node(opp);
- if (of_property_read_u32(np, "qcom,opp-fuse-level", &fuse_corner))
- pr_err("%s: missing 'qcom,opp-fuse-level' property\n",
- __func__);
-
- of_node_put(np);
-
- return fuse_corner;
-}
-
-static unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
- struct device *cpu_dev)
-{
- u64 rate = 0;
- struct device_node *ref_np;
- struct device_node *desc_np;
- struct device_node *child_np = NULL;
- struct device_node *child_req_np = NULL;
-
- desc_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
- if (!desc_np)
- return 0;
-
- ref_np = dev_pm_opp_get_of_node(ref);
- if (!ref_np)
- goto out_ref;
-
- do {
- of_node_put(child_req_np);
- child_np = of_get_next_available_child(desc_np, child_np);
- child_req_np = of_parse_phandle(child_np, "required-opps", 0);
- } while (child_np && child_req_np != ref_np);
-
- if (child_np && child_req_np == ref_np)
- of_property_read_u64(child_np, "opp-hz", &rate);
-
- of_node_put(child_req_np);
- of_node_put(child_np);
- of_node_put(ref_np);
-out_ref:
- of_node_put(desc_np);
-
- return (unsigned long) rate;
-}
-
static int cpr_corner_init(struct cpr_drv *drv)
{
const struct cpr_desc *desc = drv->desc;
@@ -1110,7 +852,7 @@ static int cpr_corner_init(struct cpr_drv *drv)
opp = dev_pm_opp_find_level_exact(&drv->pd.dev, level);
if (IS_ERR(opp))
return -EINVAL;
- fc = cpr_get_fuse_corner(opp);
+ fc = cpr_get_fuse_corner(opp, 0);
if (!fc) {
dev_pm_opp_put(opp);
return -EINVAL;
@@ -1186,7 +928,7 @@ static int cpr_corner_init(struct cpr_drv *drv)
corner->uV = fuse->uV;
if (prev_fuse && cdata[i - 1].freq == prev_fuse->max_freq) {
- scaling = cpr_calculate_scaling(quot_offset, drv,
+ scaling = cpr_calculate_scaling(drv->dev, quot_offset,
fdata, corner);
if (scaling < 0)
return scaling;
@@ -1224,47 +966,6 @@ static int cpr_corner_init(struct cpr_drv *drv)
return 0;
}
-static const struct cpr_fuse *cpr_get_fuses(struct cpr_drv *drv)
-{
- const struct cpr_desc *desc = drv->desc;
- struct cpr_fuse *fuses;
- int i;
-
- fuses = devm_kcalloc(drv->dev, desc->num_fuse_corners,
- sizeof(struct cpr_fuse),
- GFP_KERNEL);
- if (!fuses)
- return ERR_PTR(-ENOMEM);
-
- for (i = 0; i < desc->num_fuse_corners; i++) {
- char tbuf[32];
-
- snprintf(tbuf, 32, "cpr_ring_osc%d", i + 1);
- fuses[i].ring_osc = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL);
- if (!fuses[i].ring_osc)
- return ERR_PTR(-ENOMEM);
-
- snprintf(tbuf, 32, "cpr_init_voltage%d", i + 1);
- fuses[i].init_voltage = devm_kstrdup(drv->dev, tbuf,
- GFP_KERNEL);
- if (!fuses[i].init_voltage)
- return ERR_PTR(-ENOMEM);
-
- snprintf(tbuf, 32, "cpr_quotient%d", i + 1);
- fuses[i].quotient = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL);
- if (!fuses[i].quotient)
- return ERR_PTR(-ENOMEM);
-
- snprintf(tbuf, 32, "cpr_quotient_offset%d", i + 1);
- fuses[i].quotient_offset = devm_kstrdup(drv->dev, tbuf,
- GFP_KERNEL);
- if (!fuses[i].quotient_offset)
- return ERR_PTR(-ENOMEM);
- }
-
- return fuses;
-}
-
static void cpr_set_loop_allowed(struct cpr_drv *drv)
{
drv->loop_disabled = false;
@@ -1296,54 +997,6 @@ static int cpr_init_parameters(struct cpr_drv *drv)
return 0;
}
-static int cpr_find_initial_corner(struct cpr_drv *drv)
-{
- unsigned long rate;
- const struct corner *end;
- struct corner *iter;
- unsigned int i = 0;
-
- if (!drv->cpu_clk) {
- dev_err(drv->dev, "cannot get rate from NULL clk\n");
- return -EINVAL;
- }
-
- end = &drv->corners[drv->num_corners - 1];
- rate = clk_get_rate(drv->cpu_clk);
-
- /*
- * Some bootloaders set a CPU clock frequency that is not defined
- * in the OPP table. When running at an unlisted frequency,
- * cpufreq_online() will change to the OPP which has the lowest
- * frequency, at or above the unlisted frequency.
- * Since cpufreq_online() always "rounds up" in the case of an
- * unlisted frequency, this function always "rounds down" in case
- * of an unlisted frequency. That way, when cpufreq_online()
- * triggers the first ever call to cpr_set_performance_state(),
- * it will correctly determine the direction as UP.
- */
- for (iter = drv->corners; iter <= end; iter++) {
- if (iter->freq > rate)
- break;
- i++;
- if (iter->freq == rate) {
- drv->corner = iter;
- break;
- }
- if (iter->freq < rate)
- drv->corner = iter;
- }
-
- if (!drv->corner) {
- dev_err(drv->dev, "boot up corner not found\n");
- return -EINVAL;
- }
-
- dev_dbg(drv->dev, "boot up perf state: %u\n", i);
-
- return 0;
-}
-
static const struct cpr_desc qcs404_cpr_desc = {
.num_fuse_corners = 3,
.min_diff_quot = CPR_FUSE_MIN_QUOT_DIFF,
@@ -1531,7 +1184,8 @@ static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
if (ret)
goto unlock;
- ret = cpr_find_initial_corner(drv);
+ ret = cpr_find_initial_corner(drv->dev, drv->cpu_clk, drv->corners,
+ drv->num_corners);
if (ret)
goto unlock;
@@ -1616,6 +1270,7 @@ static int cpr_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct cpr_drv *drv;
+ const struct cpr_desc *desc;
int irq, ret;
const struct cpr_acc_desc *data;
struct device_node *np;
@@ -1631,6 +1286,7 @@ static int cpr_probe(struct platform_device *pdev)
drv->dev = dev;
drv->desc = data->cpr_desc;
drv->acc_desc = data->acc_desc;
+ desc = drv->desc;
drv->fuse_corners = devm_kcalloc(dev, drv->desc->num_fuse_corners,
sizeof(*drv->fuse_corners),
@@ -1670,11 +1326,13 @@ static int cpr_probe(struct platform_device *pdev)
if (ret)
return ret;
- drv->cpr_fuses = cpr_get_fuses(drv);
+ drv->cpr_fuses = cpr_get_fuses(drv->dev, UINT_MAX, desc->num_fuse_corners);
if (IS_ERR(drv->cpr_fuses))
return PTR_ERR(drv->cpr_fuses);
- ret = cpr_populate_ring_osc_idx(drv);
+ ret = cpr_populate_ring_osc_idx(drv->dev, drv->fuse_corners,
+ drv->cpr_fuses,
+ desc->num_fuse_corners);
if (ret)
return ret;
--
2.39.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
` (2 preceding siblings ...)
2023-01-10 17:56 ` [PATCH v8 3/5] soc: qcom: cpr: Move common functions to new file Konrad Dybcio
@ 2023-01-10 17:56 ` Konrad Dybcio
2023-01-10 18:27 ` Robert Marko
2023-01-11 20:43 ` kernel test robot
2023-01-10 17:56 ` [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh Konrad Dybcio
4 siblings, 2 replies; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 17:56 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno, Konrad Dybcio,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
linux-kernel
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
This commit introduces a new driver, based on the one for cpr v1,
to enable support for the newer Qualcomm Core Power Reduction
hardware, known downstream as CPR3, CPR4 and CPRh, and support
for MSM8998 and SDM630 CPU power reduction.
In these new versions of the hardware, support for various new
features was introduced, including voltage reduction for the GPU,
security hardening and a new way of controlling CPU DVFS,
consisting in internal communication between microcontrollers,
specifically the CPR-Hardened and the Operating State Manager.
The CPR v3, v4 and CPRh are present in a broad range of SoCs,
from the mid-range to the high end ones including, but not limited
to, MSM8953/8996/8998, SDM630/636/660/845.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
[Konrad: rebase, apply review comments]
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
drivers/soc/qcom/Kconfig | 21 +
drivers/soc/qcom/Makefile | 4 +-
drivers/soc/qcom/cpr-common.h | 2 +
drivers/soc/qcom/cpr3.c | 2923 +++++++++++++++++++++++++++++++++
4 files changed, 2949 insertions(+), 1 deletion(-)
create mode 100644 drivers/soc/qcom/cpr3.c
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 21c4ce2315ba..303e958d9432 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -29,6 +29,7 @@ config QCOM_COMMAND_DB
config QCOM_CPR
tristate "QCOM Core Power Reduction (CPR) support"
depends on ARCH_QCOM && HAS_IOMEM
+ select QCOM_CPR_COMMON
select PM_OPP
select REGMAP
help
@@ -42,6 +43,26 @@ config QCOM_CPR
To compile this driver as a module, choose M here: the module will
be called qcom-cpr
+config QCOM_CPR_COMMON
+ tristate
+
+config QCOM_CPR3
+ tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
+ depends on ARCH_QCOM && HAS_IOMEM
+ select PM_OPP
+ select REGMAP
+ help
+ Say Y here to enable support for the CPR hardware found on a broad
+ variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
+ SDM845 and others.
+
+ This driver populates OPP tables and makes adjustments to them
+ based on feedback from the CPR hardware. If you want to do CPU
+ and/or GPU frequency scaling say Y here.
+
+ To compile this driver as a module, choose M here: the module will
+ be called qcom-cpr3
+
config QCOM_GENI_SE
tristate "QCOM GENI Serial Engine Driver"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index ba2b55dd94ff..362e9b712a68 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -3,7 +3,9 @@ CFLAGS_rpmh-rsc.o := -I$(src)
obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
-obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
+obj-$(CONFIG_QCOM_CPR) += cpr.o
+obj-$(CONFIG_QCOM_CPR_COMMON) += cpr-common.o
+obj-$(CONFIG_QCOM_CPR3) += cpr3.o
obj-$(CONFIG_QCOM_DCC) += dcc.o
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
index 2cd15f7eac90..a90f6351d022 100644
--- a/drivers/soc/qcom/cpr-common.h
+++ b/drivers/soc/qcom/cpr-common.h
@@ -65,6 +65,8 @@ struct corner {
struct corner_data {
unsigned int fuse_corner;
unsigned long freq;
+ int oloop_vadj;
+ int cloop_vadj;
};
struct acc_desc {
diff --git a/drivers/soc/qcom/cpr3.c b/drivers/soc/qcom/cpr3.c
new file mode 100644
index 000000000000..14a1163d37eb
--- /dev/null
+++ b/drivers/soc/qcom/cpr3.c
@@ -0,0 +1,2923 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019 Linaro Limited
+ * Copyright (c) 2021, AngeloGioacchino Del Regno
+ * <angelogioacchino.delregno@somainline.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+#include <soc/qcom/cpr.h>
+
+#include "cpr-common.h"
+
+#define CPR3_RO_COUNT 16
+#define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0)
+
+/* CPR3 registers */
+#define CPR3_REG_CPR_VERSION 0x0
+#define CPRH_CPR_VERSION_4P5 0x40050000
+
+#define CPR3_REG_CPR_CTL 0x4
+#define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0)
+#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK GENMASK(5, 1)
+#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT 1
+#define CPR3_CPR_CTL_COUNT_MODE_MASK GENMASK(7, 6)
+#define CPR3_CPR_CTL_COUNT_MODE_SHIFT 6
+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN 0
+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX 1
+#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED 2
+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE 3
+#define CPR3_CPR_CTL_COUNT_REPEAT_MASK GENMASK(31, 9)
+#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT 9
+
+#define CPR3_REG_CPR_STATUS 0x8
+#define CPR3_CPR_STATUS_BUSY_MASK BIT(0)
+
+/*
+ * This register is not present on controllers that support HW closed-loop
+ * except CPR4 APSS controller.
+ */
+#define CPR3_REG_CPR_TIMER_AUTO_CONT 0xC
+
+#define CPR3_REG_CPR_STEP_QUOT 0x14
+#define CPR3_CPR_STEP_QUOT_MIN_MASK GENMASK(5, 0)
+#define CPR3_CPR_STEP_QUOT_MIN_SHIFT 0
+#define CPR3_CPR_STEP_QUOT_MAX_MASK GENMASK(11, 6)
+#define CPR3_CPR_STEP_QUOT_MAX_SHIFT 6
+#define CPRH_DELTA_QUOT_STEP_FACTOR 4
+
+#define CPR3_REG_GCNT(ro) (0xA0 + 0x4 * (ro))
+#define CPR3_REG_SENSOR_OWNER(sensor) (0x200 + 0x4 * (sensor))
+
+#define CPR3_REG_CONT_CMD 0x800
+#define CPR3_CONT_CMD_ACK 0x1
+#define CPR3_CONT_CMD_NACK 0x0
+
+#define CPR3_REG_THRESH(thread) (0x808 + 0x440 * (thread))
+#define CPR3_THRESH_CONS_DOWN_MASK GENMASK(3, 0)
+#define CPR3_THRESH_CONS_DOWN_SHIFT 0
+#define CPR3_THRESH_CONS_UP_MASK GENMASK(7, 4)
+#define CPR3_THRESH_CONS_UP_SHIFT 4
+#define CPR3_THRESH_DOWN_THRESH_MASK GENMASK(12, 8)
+#define CPR3_THRESH_DOWN_THRESH_SHIFT 8
+#define CPR3_THRESH_UP_THRESH_MASK GENMASK(17, 13)
+#define CPR3_THRESH_UP_THRESH_SHIFT 13
+
+#define CPR3_REG_RO_MASK(thread) (0x80C + 0x440 * (thread))
+
+#define CPR3_REG_RESULT0(thread) (0x810 + 0x440 * (thread))
+#define CPR3_RESULT0_BUSY_MASK BIT(0)
+#define CPR3_RESULT0_STEP_DN_MASK BIT(1)
+#define CPR3_RESULT0_STEP_UP_MASK BIT(2)
+#define CPR3_RESULT0_ERROR_STEPS_MASK GENMASK(7, 3)
+#define CPR3_RESULT0_ERROR_STEPS_SHIFT 3
+#define CPR3_RESULT0_ERROR_MASK GENMASK(19, 8)
+#define CPR3_RESULT0_ERROR_SHIFT 8
+
+#define CPR3_REG_RESULT1(thread) (0x814 + 0x440 * (thread))
+#define CPR3_RESULT1_QUOT_MIN_MASK GENMASK(11, 0)
+#define CPR3_RESULT1_QUOT_MIN_SHIFT 0
+#define CPR3_RESULT1_QUOT_MAX_MASK GENMASK(23, 12)
+#define CPR3_RESULT1_QUOT_MAX_SHIFT 12
+#define CPR3_RESULT1_RO_MIN_MASK GENMASK(27, 24)
+#define CPR3_RESULT1_RO_MIN_SHIFT 24
+#define CPR3_RESULT1_RO_MAX_MASK GENMASK(31, 28)
+#define CPR3_RESULT1_RO_MAX_SHIFT 28
+
+#define CPR3_REG_RESULT2(thread) (0x818 + 0x440 * (thread))
+#define CPR3_RESULT2_STEP_QUOT_MIN_MASK GENMASK(5, 0)
+#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT 0
+#define CPR3_RESULT2_STEP_QUOT_MAX_MASK GENMASK(11, 6)
+#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT 6
+#define CPR3_RESULT2_SENSOR_MIN_MASK GENMASK(23, 16)
+#define CPR3_RESULT2_SENSOR_MIN_SHIFT 16
+#define CPR3_RESULT2_SENSOR_MAX_MASK GENMASK(31, 24)
+#define CPR3_RESULT2_SENSOR_MAX_SHIFT 24
+
+#define CPR3_REG_IRQ_EN 0x81C
+#define CPR3_REG_IRQ_CLEAR 0x820
+#define CPR3_REG_IRQ_STATUS 0x824
+#define CPR3_IRQ_UP BIT(3)
+#define CPR3_IRQ_MID BIT(2)
+#define CPR3_IRQ_DOWN BIT(1)
+#define CPR3_IRQ_ALL (CPR3_IRQ_UP | CPR3_IRQ_MID | CPR3_IRQ_DOWN)
+
+#define CPR3_REG_TARGET_QUOT(thread, ro) (0x840 + 0x440 * (thread) + 0x4 * (ro))
+
+/* Registers found only on controllers that support HW closed-loop. */
+#define CPR3_REG_PD_THROTTLE 0xE8
+
+#define CPR3_REG_HW_CLOSED_LOOP_DISABLED 0x3000
+#define CPR3_REG_CPR_TIMER_MID_CONT 0x3004
+#define CPR3_REG_CPR_TIMER_UP_DN_CONT 0x3008
+
+/* CPR4 controller specific registers and bit definitions */
+#define CPR4_REG_CPR_TIMER_CLAMP 0x10
+#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27)
+
+#define CPR4_REG_MISC 0x700
+#define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2)
+#define CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN BIT(3)
+
+#define CPR4_REG_SAW_ERROR_STEP_LIMIT 0x7A4
+#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK GENMASK(4, 0)
+#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT 0
+#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK GENMASK(9, 5)
+#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT 5
+
+#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS 0x7A8
+#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK GENMASK(28, 18)
+#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT 18
+
+#define CPR4_REG_MARGIN_ADJ_CTL 0x7F8
+#define CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN BIT(4)
+#define CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN BIT(7)
+#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK GENMASK(16, 12)
+#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT 12
+#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_MASK GENMASK(31, 26)
+#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_SHIFT 26
+
+#define CPR4_REG_CPR_MASK_THREAD(thread) (0x80C + 0x440 * (thread))
+#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD BIT(31)
+#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0)
+
+/* CPRh controller specific registers and bit definitions */
+#define __CPRH_REG_CORNER(rbase, tbase, tid, cnum) (rbase + (tbase * tid) + (0x4 * cnum))
+#define CPRH_REG_CORNER(d, t, c) __CPRH_REG_CORNER(d->reg_corner, d->reg_corner_tid, t, c)
+
+#define CPRH_CTL_OSM_ENABLED BIT(0)
+#define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1)
+#define CPRH_CTL_BASE_VOLTAGE_SHIFT 1
+#define CPRH_CTL_MODE_SWITCH_DELAY_MASK GENMASK(24, 17)
+#define CPRH_CTL_MODE_SWITCH_DELAY_SHIFT 17
+#define CPRH_CTL_VOLTAGE_MULTIPLIER_MASK GENMASK(28, 25)
+#define CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT 25
+
+#define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0)
+#define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0
+#define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8)
+#define CPRH_CORNER_FLOOR_VOLTAGE_SHIFT 8
+#define CPRH_CORNER_QUOT_DELTA_MASK GENMASK(24, 16)
+#define CPRH_CORNER_QUOT_DELTA_SHIFT 16
+#define CPRH_CORNER_RO_SEL_MASK GENMASK(28, 25)
+#define CPRH_CORNER_RO_SEL_SHIFT 25
+#define CPRH_CORNER_CPR_CL_DISABLE BIT(29)
+
+#define CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE 255
+#define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255
+#define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511
+
+enum cpr_type {
+ CTRL_TYPE_CPR3,
+ CTRL_TYPE_CPR4,
+ CTRL_TYPE_CPRH,
+ CTRL_TYPE_MAX,
+};
+
+/*
+ * struct cpr_thread_desc - CPR Thread-specific parameters
+ *
+ * @controller_id: Identifier of the CPR controller expected by the HW
+ * @ro_scaling_factor: Scaling factor for each ring oscillator entry
+ * @hw_tid: Identifier of the CPR thread expected by the HW
+ * @init_voltage_step: Voltage in uV for number of steps read from fuse array
+ * @init_voltage_width: Bit-width of the voltage read from the fuse array
+ * @sensor_range_start: First sensor ID used by a thread
+ * @sensor_range_end: Last sensor ID used by a thread
+ * @num_fuse_corners: Number of valid entries in fuse_corner_data
+ * @step_quot_init_min: Minimum achievable step quotient for this corner
+ * @step_quot_init_max: Maximum achievable step quotient for this corner
+ * @fuse_corner_data: Parameters for calculation of each fuse corner
+ */
+struct cpr_thread_desc {
+ u8 controller_id;
+ u8 hw_tid;
+ const int (*ro_scaling_factor)[CPR3_RO_COUNT];
+ int ro_avail_corners;
+ int init_voltage_step;
+ int init_voltage_width;
+ u8 sensor_range_start;
+ u8 sensor_range_end;
+ u8 step_quot_init_min;
+ u8 step_quot_init_max;
+ unsigned int num_fuse_corners;
+ struct fuse_corner_data *fuse_corner_data;
+};
+
+/*
+ * struct cpr_desc - Driver instance-wide CPR parameters
+ *
+ * @cpr_type: Type (base version) of the CPR controller
+ * @num_threads: Max. number of threads supported by this controller
+ * @timer_delay_us: Loop delay time in uS
+ * @timer_updn_delay_us: Voltage after-up/before-down delay time in uS
+ * @timer_cons_up: Wait between consecutive up requests in uS
+ * @timer_cons_down: Wait between consecutive down requests in uS
+ * @up_threshold: Generic corner up threshold
+ * @down_threshold: Generic corner down threshold
+ * @idle_clocks: CPR Sensor: idle timer in cpr clocks unit
+ * @count_mode: CPR Sensor: counting mode
+ * @count_repeat: CPR Sensor: number of times to repeat reading
+ * @gcnt_us: CPR measurement interval in uS
+ * @vreg_step_fixed: Regulator voltage per step (if vreg unusable)
+ * @vreg_step_up_limit: Num. of steps up at once before re-measuring sensors
+ * @vreg_step_down_limit: Num. of steps dn at once before re-measuring sensors
+ * @vdd_settle_time_us: Settling timer to account for one VDD supply step
+ * @corner_settle_time_us: Settle time for corner switch request
+ * @mem_acc_threshold: Memory Accelerator (MEM-ACC) voltage threshold
+ * @apm_threshold: Array Power Mux (APM) voltage threshold
+ * @apm_crossover: Array Power Mux (APM) corner crossover voltage
+ * @apm_hysteresis: Hysteresis for APM V-threshold related calculations
+ * @cpr_base_voltage: Safety: Absolute minimum voltage (uV) on this CPR
+ * @cpr_max_voltage: Safety: Absolute maximum voltage (uV) on this CPR
+ * @pd_throttle_val: CPR Power Domain throttle during voltage switch
+ * @threads: Array containing "CPR Thread" specific parameters
+ * @reduce_to_fuse_uV: Reduce corner max volts (if higher) to fuse ceiling
+ * @reduce_to_corner_uV: Reduce corner max volts (if higher) to corner ceil.
+ * @hw_closed_loop_en: Enable CPR HW Closed-Loop voltage auto-adjustment
+ */
+struct cpr_desc {
+ enum cpr_type cpr_type;
+ unsigned int num_threads;
+ unsigned int timer_delay_us;
+ u8 timer_updn_delay_us;
+ u8 timer_cons_up;
+ u8 timer_cons_down;
+ u8 up_threshold;
+ u8 down_threshold;
+ u8 idle_clocks;
+ u8 count_mode;
+ u8 count_repeat;
+ u8 gcnt_us;
+ u16 vreg_step_fixed;
+ u8 vreg_step_up_limit;
+ u8 vreg_step_down_limit;
+ u8 vdd_settle_time_us;
+ u8 corner_settle_time_us;
+ int mem_acc_threshold;
+ int apm_threshold;
+ int apm_crossover;
+ int apm_hysteresis;
+ u32 cpr_base_voltage;
+ u32 cpr_max_voltage;
+ u32 pd_throttle_val;
+
+ const struct cpr_thread_desc **threads;
+ bool reduce_to_fuse_uV;
+ bool reduce_to_corner_uV;
+ bool hw_closed_loop_en;
+};
+
+struct cpr_drv;
+struct cpr_thread {
+ int num_corners;
+ int id;
+ bool enabled;
+ void __iomem *base;
+ struct clk *cpu_clk;
+ struct corner *corner;
+ struct corner *corners;
+ struct fuse_corner *fuse_corners;
+ struct cpr_drv *drv;
+ struct cpr_ext_data ext_data;
+ struct generic_pm_domain pd;
+ struct device *attached_cpu_dev;
+ struct work_struct restart_work;
+ bool restarting;
+
+ const struct cpr_fuse *cpr_fuses;
+ const struct cpr_thread_desc *desc;
+};
+
+struct cpr_drv {
+ int irq;
+ unsigned int ref_clk_khz;
+ struct device *dev;
+ struct mutex lock;
+ struct regulator *vreg;
+ struct regmap *tcsr;
+ u32 gcnt;
+ u32 speed_bin;
+ u32 fusing_rev;
+ u32 last_uV;
+ u32 cpr_hw_rev;
+ u32 reg_corner;
+ u32 reg_corner_tid;
+ u32 reg_ctl;
+ u32 reg_status;
+ int fuse_level_set;
+ int extra_corners;
+ unsigned int vreg_step;
+ bool enabled;
+
+ struct cpr_thread *threads;
+ struct genpd_onecell_data cell_data;
+
+ const struct cpr_desc *desc;
+ const struct acc_desc *acc_desc;
+ struct dentry *debugfs;
+};
+
+/**
+ * cpr_get_corner_post_vadj() - Get corner post-voltage adjustment values
+ * @opp: Pointer to the corresponding OPP struct
+ * @tid: CPR thread ID
+ * @open_loop: Pointer to the closed-loop adjustment value
+ * @closed_loop: Pointer to the open-loop adjustment value
+ */
+void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
+ s32 *open_loop, s32 *closed_loop)
+{
+ struct device_node *np;
+
+ /*
+ * There is no of_property_read_s32_index, so we just store the
+ * result into a s32 variable. After all, the OF API is doing
+ * the exact same for of_property_read_s32...
+ */
+ np = dev_pm_opp_get_of_node(opp);
+ if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid, open_loop))
+ *open_loop = 0;
+
+ if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid, closed_loop))
+ *closed_loop = 0;
+
+ of_node_put(np);
+}
+
+/**
+ * cpr_get_ro_factor() - Get fuse corner ring oscillator factor
+ * @tdesc: CPR Thread-specific parameters
+ * @fnum: Fuse corner
+ * @ro_idx: Ring Oscillator fuse number
+ *
+ * Not all threads have different scaling factors for each
+ * Fuse Corner: if the RO factors are the same for all corners,
+ * then only one is specified, instead of uselessly repeating
+ * the same array for FC-times.
+ * This function checks for the same and gives back the right
+ * factor for the requested ring oscillator.
+ *
+ * Return: Ring oscillator factor
+ */
+static int cpr_get_ro_factor(const struct cpr_thread_desc *tdesc,
+ int fnum, int ro_idx)
+{
+ int ro_fnum;
+
+ if (tdesc->ro_avail_corners == tdesc->num_fuse_corners)
+ ro_fnum = fnum;
+ else
+ ro_fnum = 0;
+
+ return tdesc->ro_scaling_factor[ro_fnum][ro_idx];
+}
+
+static void cpr_write(struct cpr_thread *thread, u32 offset, u32 value)
+{
+ writel(value, thread->base + offset);
+}
+
+static u32 cpr_read(struct cpr_thread *thread, u32 offset)
+{
+ return readl(thread->base + offset);
+}
+
+static void
+cpr_masked_write(struct cpr_thread *thread, u32 offset, u32 mask, u32 value)
+{
+ u32 val;
+
+ val = readl(thread->base + offset);
+ val &= ~mask;
+ val |= value & mask;
+ writel(val, thread->base + offset);
+}
+
+static void cpr_irq_clr(struct cpr_thread *thread)
+{
+ cpr_write(thread, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_ALL);
+}
+
+static void cpr_irq_clr_nack(struct cpr_thread *thread)
+{
+ cpr_irq_clr(thread);
+ cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
+}
+
+static void cpr_irq_clr_ack(struct cpr_thread *thread)
+{
+ cpr_irq_clr(thread);
+ cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_ACK);
+}
+
+static void cpr_irq_set(struct cpr_thread *thread, u32 int_bits)
+{
+ /* On CPR-hardened, interrupts are managed by and on firmware */
+ if (thread->drv->desc->cpr_type == CTRL_TYPE_CPRH)
+ return;
+
+ cpr_write(thread, CPR3_REG_IRQ_EN, int_bits);
+}
+
+/**
+ * cpr_ctl_enable() - Enable CPR thread
+ * @thread: Structure holding CPR thread-specific parameters
+ */
+static void cpr_ctl_enable(struct cpr_thread *thread)
+{
+ if (thread->drv->enabled && !thread->restarting) {
+ cpr_masked_write(thread, CPR3_REG_CPR_CTL,
+ CPR3_CPR_CTL_LOOP_EN_MASK,
+ CPR3_CPR_CTL_LOOP_EN_MASK);
+ }
+}
+
+/**
+ * cpr_ctl_disable() - Disable CPR thread
+ * @thread: Structure holding CPR thread-specific parameters
+ */
+static void cpr_ctl_disable(struct cpr_thread *thread)
+{
+ const struct cpr_desc *desc = thread->drv->desc;
+
+ if (desc->cpr_type != CTRL_TYPE_CPRH) {
+ cpr_irq_set(thread, 0);
+ cpr_irq_clr(thread);
+ }
+
+ cpr_masked_write(thread, CPR3_REG_CPR_CTL,
+ CPR3_CPR_CTL_LOOP_EN_MASK, 0);
+}
+
+/**
+ * cpr_ctl_is_enabled() - Check if thread is enabled
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Return: true if the CPR is enabled, false if it is disabled.
+ */
+static bool cpr_ctl_is_enabled(struct cpr_thread *thread)
+{
+ u32 reg_val;
+
+ reg_val = cpr_read(thread, CPR3_REG_CPR_CTL);
+ return reg_val & CPR3_CPR_CTL_LOOP_EN_MASK;
+}
+
+/**
+ * cpr_check_any_thread_busy() - Check if HW is done processing
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Return: true if the CPR is busy, false if it is ready.
+ */
+static bool cpr_check_any_thread_busy(struct cpr_thread *thread)
+{
+ int i;
+
+ for (i = 0; i < thread->drv->desc->num_threads; i++)
+ if (cpr_read(thread, CPR3_REG_RESULT0(i)) &
+ CPR3_RESULT0_BUSY_MASK)
+ return true;
+
+ return false;
+}
+
+static void cpr_restart_worker(struct work_struct *work)
+{
+ struct cpr_thread *thread = container_of(work, struct cpr_thread,
+ restart_work);
+ struct cpr_drv *drv = thread->drv;
+ int i;
+
+ mutex_lock(&drv->lock);
+
+ thread->restarting = true;
+ cpr_ctl_disable(thread);
+ disable_irq(drv->irq);
+
+ mutex_unlock(&drv->lock);
+
+ for (i = 0; i < 20; i++) {
+ u32 cpr_status = cpr_read(thread, CPR3_REG_CPR_STATUS);
+ u32 ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
+
+ if ((cpr_status & CPR3_CPR_STATUS_BUSY_MASK) &&
+ !(ctl & CPR3_CPR_CTL_LOOP_EN_MASK))
+ break;
+
+ udelay(10);
+ }
+
+ cpr_irq_clr(thread);
+
+ for (i = 0; i < 20; i++) {
+ u32 status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
+
+ if (!(status & CPR3_IRQ_ALL))
+ break;
+ udelay(10);
+ }
+
+ mutex_lock(&drv->lock);
+
+ thread->restarting = false;
+ enable_irq(drv->irq);
+ cpr_ctl_enable(thread);
+
+ mutex_unlock(&drv->lock);
+}
+
+/**
+ * cpr_corner_restore() - Restore saved corner level
+ * @thread: Structure holding CPR thread-specific parameters
+ * @corner: Structure holding the saved corner level
+ */
+static void cpr_corner_restore(struct cpr_thread *thread,
+ struct corner *corner)
+{
+ struct cpr_drv *drv = thread->drv;
+ struct fuse_corner *fuse = corner->fuse_corner;
+ const struct cpr_thread_desc *tdesc = thread->desc;
+ u32 ro_sel = fuse->ring_osc_idx;
+
+ cpr_write(thread, CPR3_REG_GCNT(ro_sel), drv->gcnt);
+
+ cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid),
+ CPR3_RO_MASK & ~BIT(ro_sel));
+
+ cpr_write(thread, CPR3_REG_TARGET_QUOT(tdesc->hw_tid, ro_sel),
+ fuse->quot - corner->quot_adjust);
+
+ if (drv->desc->cpr_type == CTRL_TYPE_CPR4)
+ cpr_masked_write(thread,
+ CPR4_REG_CPR_MASK_THREAD(tdesc->hw_tid),
+ CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
+ CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK, 0);
+
+ thread->corner = corner;
+ corner->last_uV = corner->uV;
+}
+
+/**
+ * cpr_set_acc() - Set fuse level to the mem-acc
+ * @drv: Main driver structure
+ * @f: Fuse level
+ */
+static void cpr_set_acc(struct cpr_drv *drv, int f)
+{
+ const struct acc_desc *desc = drv->acc_desc;
+ struct reg_sequence *s = desc->settings;
+ int n = desc->num_regs_per_fuse;
+
+ if (!s || f == drv->fuse_level_set)
+ return;
+
+ regmap_multi_reg_write(drv->tcsr, s + (n * f), n);
+ drv->fuse_level_set = f;
+}
+
+/**
+ * cpr_pre_voltage() - Actions to execute before setting voltage
+ * @thread: Structure holding CPR thread-specific parameters
+ * @dir: Enumeration for voltage change direction
+ * @fuse_level: Fuse corner for mem-acc, if supported.
+ *
+ * Return: Zero for success or negative number on errors.
+ */
+static int cpr_pre_voltage(struct cpr_thread *thread,
+ enum voltage_change_dir dir,
+ int fuse_level)
+{
+ struct cpr_drv *drv = thread->drv;
+
+ if (drv->desc->cpr_type == CTRL_TYPE_CPR3 &&
+ drv->desc->pd_throttle_val)
+ cpr_write(thread, CPR3_REG_PD_THROTTLE,
+ drv->desc->pd_throttle_val);
+
+ if (drv->tcsr && dir == DOWN)
+ cpr_set_acc(drv, fuse_level);
+
+ return 0;
+}
+
+/**
+ * cpr_post_voltage() - Actions to execute after setting voltage
+ * @thread: Structure holding CPR thread-specific parameters
+ * @dir: Enumeration for voltage change direction
+ * @fuse_level: Fuse corner for mem-acc, if supported.
+ *
+ * Return: Zero for success or negative number on errors.
+ */
+static int cpr_post_voltage(struct cpr_thread *thread,
+ enum voltage_change_dir dir,
+ int fuse_level)
+{
+ struct cpr_drv *drv = thread->drv;
+
+ if (drv->tcsr && dir == UP)
+ cpr_set_acc(drv, fuse_level);
+
+ if (drv->desc->cpr_type == CTRL_TYPE_CPR3)
+ cpr_write(thread, CPR3_REG_PD_THROTTLE, 0);
+
+ return 0;
+}
+
+/**
+ * cpr_commit_state() - Set the newly requested voltage
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
+ */
+static int cpr_commit_state(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ int min_uV = 0, max_uV = 0, new_uV = 0, fuse_level = 0;
+ enum voltage_change_dir dir;
+ u32 next_irqmask = 0;
+ int ret, i;
+
+ /* On CPRhardened, control states are managed in firmware */
+ if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
+ return 0;
+
+ for (i = 0; i < drv->desc->num_threads; i++) {
+ struct cpr_thread *thread = &drv->threads[i];
+
+ if (!thread->corner)
+ continue;
+
+ fuse_level = max(fuse_level,
+ (int) (thread->corner->fuse_corner -
+ &thread->fuse_corners[0]));
+
+ max_uV = max(max_uV, thread->corner->max_uV);
+ min_uV = max(min_uV, thread->corner->min_uV);
+ new_uV = max(new_uV, thread->corner->last_uV);
+ }
+ dev_vdbg(drv->dev, "%s: new uV: %d, last uV: %d\n",
+ __func__, new_uV, drv->last_uV);
+
+ /*
+ * Safety measure: if the voltage is out of the globally allowed
+ * range, then go out and warn the user.
+ * This should *never* happen.
+ */
+ if (new_uV > drv->desc->cpr_max_voltage ||
+ new_uV < drv->desc->cpr_base_voltage) {
+ dev_warn(drv->dev, "Voltage (%u uV) out of range.", new_uV);
+ return -EINVAL;
+ }
+
+ if (new_uV == drv->last_uV || fuse_level == drv->fuse_level_set)
+ goto out;
+
+ if (fuse_level > drv->fuse_level_set)
+ dir = UP;
+ else
+ dir = DOWN;
+
+ ret = cpr_pre_voltage(thread, fuse_level, dir);
+ if (ret)
+ return ret;
+
+ dev_vdbg(drv->dev, "setting voltage: %d\n", new_uV);
+
+ ret = regulator_set_voltage(drv->vreg, new_uV, new_uV);
+ if (ret) {
+ dev_err_ratelimited(drv->dev, "failed to set voltage %d: %d\n", new_uV, ret);
+ return ret;
+ }
+
+ ret = cpr_post_voltage(thread, fuse_level, dir);
+ if (ret)
+ return ret;
+
+ drv->last_uV = new_uV;
+out:
+ if (new_uV > min_uV)
+ next_irqmask |= CPR3_IRQ_DOWN;
+ if (new_uV < max_uV)
+ next_irqmask |= CPR3_IRQ_UP;
+
+ cpr_irq_set(thread, next_irqmask);
+
+ return 0;
+}
+
+static unsigned int cpr_get_cur_perf_state(struct cpr_thread *thread)
+{
+ return thread->corner ? thread->corner - thread->corners + 1 : 0;
+}
+
+/**
+ * cpr_scale() - Calculate new voltage for the received direction
+ * @thread: Structure holding CPR thread-specific parameters
+ * @dir: Enumeration for voltage change direction
+ *
+ * The CPR scales one by one: this function calculates the new
+ * voltage to set when a voltage-UP or voltage-DOWN request comes
+ * and stores it into the per-thread structure that gets passed.
+ */
+static void cpr_scale(struct cpr_thread *thread, enum voltage_change_dir dir)
+{
+ struct cpr_drv *drv = thread->drv;
+ const struct cpr_thread_desc *tdesc = thread->desc;
+ u32 val, error_steps;
+ int last_uV, new_uV;
+ struct corner *corner;
+
+ if (dir != UP && dir != DOWN)
+ return;
+
+ corner = thread->corner;
+ val = cpr_read(thread, CPR3_REG_RESULT0(tdesc->hw_tid));
+ error_steps = val >> CPR3_RESULT0_ERROR_STEPS_SHIFT;
+ error_steps &= CPR3_RESULT0_ERROR_STEPS_MASK;
+
+ last_uV = corner->last_uV;
+
+ if (dir == UP) {
+ if (!(val & CPR3_RESULT0_STEP_UP_MASK))
+ return;
+
+ /* Calculate new voltage */
+ new_uV = last_uV + drv->vreg_step;
+ new_uV = min(new_uV, corner->max_uV);
+
+ dev_vdbg(drv->dev, "[T%u] UP - new_uV=%d last_uV=%d p-state=%u st=%u\n",
+ thread->id, new_uV, last_uV,
+ cpr_get_cur_perf_state(thread), error_steps);
+ } else {
+ if (!(val & CPR3_RESULT0_STEP_DN_MASK))
+ return;
+
+ /* Calculate new voltage */
+ new_uV = last_uV - drv->vreg_step;
+ new_uV = max(new_uV, corner->min_uV);
+ dev_vdbg(drv->dev, "[T%u] DOWN - new_uV=%d last_uV=%d p-state=%u st=%u\n",
+ thread->id, new_uV, last_uV,
+ cpr_get_cur_perf_state(thread), error_steps);
+ }
+ corner->last_uV = new_uV;
+}
+
+/**
+ * cpr_irq_handler() - Handle CPR3/CPR4 status interrupts
+ * @irq: Number of the interrupt
+ * @dev: Pointer to the cpr_thread structure
+ *
+ * Handle the interrupts coming from non-hardened CPR HW as to get
+ * an ok to scale voltages immediately, or to pass error status to
+ * the hardware (either success/ACK or failure/NACK).
+ *
+ * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
+ */
+static irqreturn_t cpr_irq_handler(int irq, void *dev)
+{
+ struct cpr_thread *thread = dev;
+ struct cpr_drv *drv = thread->drv;
+ irqreturn_t ret = IRQ_HANDLED;
+ int i, rc;
+ enum voltage_change_dir dir = NO_CHANGE;
+ u32 val;
+
+ mutex_lock(&drv->lock);
+
+ val = cpr_read(thread, CPR3_REG_IRQ_STATUS);
+
+ dev_vdbg(drv->dev, "IRQ_STATUS = %#02x\n", val);
+
+ if (!cpr_ctl_is_enabled(thread)) {
+ dev_vdbg(drv->dev, "CPR is disabled\n");
+ ret = IRQ_NONE;
+ } else if (cpr_check_any_thread_busy(thread)) {
+ cpr_irq_clr_nack(thread);
+ dev_dbg(drv->dev, "CPR measurement is not ready\n");
+ } else {
+ /*
+ * Following sequence of handling is as per each IRQ's
+ * priority
+ */
+ if (val & CPR3_IRQ_UP)
+ dir = UP;
+ else if (val & CPR3_IRQ_DOWN)
+ dir = DOWN;
+
+ if (dir != NO_CHANGE) {
+ for (i = 0; i < drv->desc->num_threads; i++) {
+ thread = &drv->threads[i];
+ cpr_scale(thread, dir);
+ }
+
+ rc = cpr_commit_state(thread);
+ if (rc)
+ cpr_irq_clr_nack(thread);
+ else
+ cpr_irq_clr_ack(thread);
+ } else if (val & CPR3_IRQ_MID) {
+ dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n");
+ } else {
+ dev_warn(drv->dev, "IRQ occurred for unknown flag (%#08x)\n", val);
+ schedule_work(&thread->restart_work);
+ }
+ }
+
+ mutex_unlock(&drv->lock);
+
+ return ret;
+}
+
+static int cpr_switch(struct cpr_drv *drv)
+{
+ int i, ret;
+ bool enabled = false;
+
+ if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
+ return 0;
+
+ for (i = 0; i < drv->desc->num_threads && !enabled; i++)
+ enabled = drv->threads[i].enabled;
+
+ dev_vdbg(drv->dev, "%s: enabled = %d\n", __func__, enabled);
+
+ if (enabled == drv->enabled)
+ return 0;
+
+ if (enabled) {
+ ret = regulator_enable(drv->vreg);
+ if (ret)
+ return ret;
+
+ drv->enabled = enabled;
+
+ for (i = 0; i < drv->desc->num_threads; i++)
+ if (drv->threads[i].corner)
+ break;
+
+ if (i < drv->desc->num_threads) {
+ cpr_irq_clr(&drv->threads[i]);
+
+ cpr_commit_state(&drv->threads[i]);
+ cpr_ctl_enable(&drv->threads[i]);
+ }
+ } else {
+ for (i = 0; i < drv->desc->num_threads && !enabled; i++)
+ cpr_ctl_disable(&drv->threads[i]);
+
+ drv->enabled = enabled;
+
+ ret = regulator_disable(drv->vreg);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * cpr_enable() - Enables a CPR thread
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Return: Zero for success or negative number on errors.
+ */
+static int cpr_enable(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ int ret;
+
+ dev_dbg(drv->dev, "Enabling thread %d\n", thread->id);
+
+ mutex_lock(&drv->lock);
+
+ thread->enabled = true;
+ ret = cpr_switch(thread->drv);
+
+ mutex_unlock(&drv->lock);
+
+ return ret;
+}
+
+/**
+ * cpr_disable() - Disables a CPR thread
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Return: Zero for success or negative number on errors.
+ */
+static int cpr_disable(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ int ret;
+
+ dev_dbg(drv->dev, "Disabling thread %d\n", thread->id);
+
+ mutex_lock(&drv->lock);
+
+ thread->enabled = false;
+ ret = cpr_switch(thread->drv);
+
+ mutex_unlock(&drv->lock);
+
+ return ret;
+}
+
+/**
+ * cpr_configure() - Configure main HW parameters
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * This function configures the main CPR hardware parameters, such as
+ * internal timers (and delays), sensor ownerships, activates and/or
+ * deactivates cpr-threads and others, as one sequence for all of the
+ * versions supported in this driver. By design, the function may
+ * return a success earlier if the sequence for "a previous version"
+ * has ended.
+ *
+ * Context: The CPR must be clocked before calling this function!
+ *
+ * Return: Zero for success or negative number on errors.
+ */
+static int cpr_configure(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ const struct cpr_desc *desc = drv->desc;
+ const struct cpr_thread_desc *tdesc = thread->desc;
+ u32 val;
+ int i;
+
+ /* Disable interrupt and CPR */
+ cpr_irq_set(thread, 0);
+ cpr_write(thread, CPR3_REG_CPR_CTL, 0);
+
+ /* Init and save gcnt */
+ drv->gcnt = drv->ref_clk_khz * desc->gcnt_us;
+ do_div(drv->gcnt, 1000);
+
+ /* Program the delay count for the timer */
+ val = drv->ref_clk_khz * desc->timer_delay_us;
+ do_div(val, 1000);
+ if (desc->cpr_type == CTRL_TYPE_CPR3) {
+ cpr_write(thread, CPR3_REG_CPR_TIMER_MID_CONT, val);
+
+ val = drv->ref_clk_khz * desc->timer_updn_delay_us;
+ do_div(val, 1000);
+ cpr_write(thread, CPR3_REG_CPR_TIMER_UP_DN_CONT, val);
+ } else {
+ cpr_write(thread, CPR3_REG_CPR_TIMER_AUTO_CONT, val);
+ }
+ dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val,
+ desc->timer_delay_us);
+
+ /* Program the control register */
+ val = desc->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT;
+ val |= desc->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT;
+ val |= desc->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT;
+ cpr_write(thread, CPR3_REG_CPR_CTL, val);
+
+ /* Configure CPR default step quotients */
+ val = tdesc->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT;
+ val |= tdesc->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT;
+
+ cpr_write(thread, CPR3_REG_CPR_STEP_QUOT, val);
+
+ /*
+ * Configure the CPR sensor ownership always on thread 0
+ * TODO: SDM845 has different ownership for sensors!!
+ */
+ for (i = tdesc->sensor_range_start; i < tdesc->sensor_range_end; i++)
+ cpr_write(thread, CPR3_REG_SENSOR_OWNER(i), 0);
+
+ /* Program Consecutive Up & Down */
+ val = desc->timer_cons_up << CPR3_THRESH_CONS_UP_SHIFT;
+ val |= desc->timer_cons_down << CPR3_THRESH_CONS_DOWN_SHIFT;
+ val |= desc->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT;
+ val |= desc->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT;
+ cpr_write(thread, CPR3_REG_THRESH(tdesc->hw_tid), val);
+
+ /* Mask all ring oscillators for all threads initially */
+ cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), CPR3_RO_MASK);
+
+ /* HW Closed-loop control */
+ if (desc->cpr_type == CTRL_TYPE_CPR3) {
+ cpr_write(thread, CPR3_REG_HW_CLOSED_LOOP_DISABLED,
+ !desc->hw_closed_loop_en);
+ } else {
+ cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
+ CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN,
+ desc->hw_closed_loop_en ?
+ CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN : 0);
+ }
+
+ /* Additional configuration for CPR4 and beyond */
+ if (desc->cpr_type < CTRL_TYPE_CPR4)
+ return 0;
+
+ /* Disable threads initially only on non-hardened CPR4 */
+ if (desc->cpr_type == CTRL_TYPE_CPR4)
+ cpr_masked_write(thread, CPR4_REG_CPR_MASK_THREAD(1),
+ CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
+ CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
+ CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
+ CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
+
+ if (tdesc->hw_tid > 0)
+ cpr_masked_write(thread, CPR4_REG_MISC,
+ CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
+ CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN,
+ CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
+ CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN);
+
+ val = drv->vreg_step;
+ do_div(val, 1000);
+ cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
+ CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK,
+ val << CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT);
+
+ cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
+ CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
+ desc->vreg_step_down_limit <<
+ CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT);
+
+ cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
+ CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
+ desc->vreg_step_up_limit <<
+ CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT);
+
+ cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
+ CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN,
+ CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN);
+
+ if (tdesc->hw_tid > 0)
+ cpr_masked_write(thread, CPR4_REG_CPR_TIMER_CLAMP,
+ CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
+ CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
+
+ /* Settling timer to account for one VDD supply step */
+ if (desc->vdd_settle_time_us > 0) {
+ u32 m = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK;
+ u32 s = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT;
+
+ cpr_masked_write(thread, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
+ m, desc->vdd_settle_time_us << s);
+ }
+
+ /* Additional configuration for CPR-hardened */
+ if (desc->cpr_type < CTRL_TYPE_CPRH)
+ return 0;
+
+ /* Settling timer to account for one corner-switch request */
+ if (desc->corner_settle_time_us > 0)
+ cpr_masked_write(thread, drv->reg_ctl,
+ CPRH_CTL_MODE_SWITCH_DELAY_MASK,
+ desc->corner_settle_time_us <<
+ CPRH_CTL_MODE_SWITCH_DELAY_SHIFT);
+
+ /* Base voltage and multiplier values for CPRh internal calculations */
+ cpr_masked_write(thread, drv->reg_ctl,
+ CPRH_CTL_BASE_VOLTAGE_MASK,
+ (DIV_ROUND_UP(desc->cpr_base_voltage,
+ drv->vreg_step) <<
+ CPRH_CTL_BASE_VOLTAGE_SHIFT));
+
+ cpr_masked_write(thread, drv->reg_ctl,
+ CPRH_CTL_VOLTAGE_MULTIPLIER_MASK,
+ DIV_ROUND_UP(drv->vreg_step, 1000) <<
+ CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT);
+
+ return 0;
+}
+
+static int cprh_dummy_set_performance_state(struct generic_pm_domain *domain,
+ unsigned int state)
+{
+ return 0;
+}
+
+static int cpr_set_performance_state(struct generic_pm_domain *domain,
+ unsigned int state)
+{
+ struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
+ struct cpr_drv *drv = thread->drv;
+ struct corner *corner, *end;
+ int ret = 0;
+
+ mutex_lock(&drv->lock);
+
+ dev_dbg(drv->dev, "setting perf state: %u (prev state: %u thread: %u)\n",
+ state, cpr_get_cur_perf_state(thread), thread->id);
+
+ /*
+ * Determine new corner we're going to.
+ * Remove one since lowest performance state is 1.
+ */
+ corner = thread->corners + state - 1;
+ end = &thread->corners[thread->num_corners - 1];
+ if (corner > end || corner < thread->corners) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ cpr_ctl_disable(thread);
+
+ cpr_irq_clr(thread);
+ if (thread->corner != corner)
+ cpr_corner_restore(thread, corner);
+
+ ret = cpr_commit_state(thread);
+ if (ret)
+ goto unlock;
+
+ cpr_ctl_enable(thread);
+unlock:
+ mutex_unlock(&drv->lock);
+
+ dev_dbg(drv->dev, "set perf state %u on thread %u\n", state, thread->id);
+
+ return ret;
+}
+
+/**
+ * cpr3_adjust_quot - Adjust the closed-loop quotients
+ * @ring_osc_factor: Ring oscillator adjustment factor
+ * @volt_closed_loop: Closed-loop voltage adjustment factor
+ *
+ * Calculates the quotient adjustment factor based on closed-loop
+ * quotients and ring oscillator factor.
+ *
+ * Return: Adjusted quotient
+ */
+static int cpr3_adjust_quot(int ring_osc_factor, int volt_closed_loop)
+{
+ s64 temp;
+
+ if (ring_osc_factor == 0 || volt_closed_loop == 0)
+ return 0;
+
+ temp = (s64)(ring_osc_factor * volt_closed_loop);
+ return (int)div_s64(temp, 1000000);
+}
+
+/**
+ * cpr_fuse_corner_init() - Calculate fuse corner table
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * This function populates the fuse corners table by reading the
+ * values from the fuses, eventually adjusting them with a fixed
+ * per-corner offset and doing basic checks about them being
+ * supported by the regulator that is assigned to this CPR - if
+ * it is available (on CPR-Hardened, there is no usable vreg, as
+ * that is protected by the hypervisor).
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr_fuse_corner_init(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ const struct cpr_thread_desc *desc = thread->desc;
+ const struct cpr_fuse *cpr_fuse = thread->cpr_fuses;
+ struct fuse_corner_data *fdata;
+ struct fuse_corner *fuse, *prev_fuse, *end;
+ int i, ret;
+
+ /* Populate fuse_corner members */
+ fuse = thread->fuse_corners;
+ prev_fuse = &fuse[0];
+ end = &fuse[desc->num_fuse_corners - 1];
+ fdata = desc->fuse_corner_data;
+
+ for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
+ int factor = cpr_get_ro_factor(desc, i, fuse->ring_osc_idx);
+
+ ret = cpr_populate_fuse_common(drv->dev, fdata, cpr_fuse,
+ fuse, drv->vreg_step,
+ desc->init_voltage_width,
+ desc->init_voltage_step);
+ if (ret)
+ return ret;
+
+ /*
+ * Adjust the fuse quot with per-fuse-corner closed-loop
+ * voltage adjustment parameters.
+ */
+ fuse->quot += cpr3_adjust_quot(factor, fdata->volt_cloop_adjust);
+
+ /* CPRh: no regulator access... */
+ if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
+ goto skip_pvs_restrict;
+
+ /* Re-check if corner voltage range is supported by regulator */
+ ret = cpr_check_vreg_constraints(drv->dev, drv->vreg, fuse);
+ if (ret)
+ return ret;
+
+skip_pvs_restrict:
+ if (fuse->uV < prev_fuse->uV)
+ fuse->uV = prev_fuse->uV;
+ prev_fuse = fuse;
+ dev_dbg(drv->dev, "fuse corner %d: [%d %d %d] RO%hhu quot %d\n",
+ i, fuse->min_uV, fuse->uV, fuse->max_uV,
+ fuse->ring_osc_idx, fuse->quot);
+
+ /* Check if constraints are valid */
+ if (fuse->uV < fuse->min_uV || fuse->uV > fuse->max_uV) {
+ dev_err(drv->dev, "fuse corner %d: Bad voltage range.\n", i);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void cpr3_restrict_corner(struct corner *corner, int threshold,
+ int hysteresis, int step)
+{
+ if (threshold > corner->min_uV && threshold <= corner->max_uV) {
+ if (corner->uV >= threshold) {
+ corner->min_uV = max(corner->min_uV,
+ threshold - hysteresis);
+ if (corner->min_uV > corner->uV)
+ corner->uV = corner->min_uV;
+ } else {
+ corner->max_uV = threshold;
+ corner->max_uV -= step;
+ }
+ }
+}
+
+/*
+ * cprh_corner_adjust_opps() - Set voltage on each CPU OPP table entry
+ *
+ * On CPR-Hardened, the voltage level is controlled internally through
+ * the OSM hardware: in order to initialize the latter, we have to
+ * communicate the voltage to its driver, so that it will be able to
+ * write the right parameters (as they have to be set both on the CPRh
+ * and on the OSM) on it.
+ * This function is called only for CPRh.
+ *
+ * Return: Zero for success, negative number for error.
+ */
+static int cprh_corner_adjust_opps(struct cpr_thread *thread)
+{
+ struct corner *corner = thread->corners;
+ struct cpr_drv *drv = thread->drv;
+ int i, ret;
+
+ for (i = 0; i < thread->num_corners; i++) {
+ ret = dev_pm_opp_adjust_voltage(thread->attached_cpu_dev,
+ corner[i].freq,
+ corner[i].uV,
+ corner[i].min_uV,
+ corner[i].max_uV);
+ if (ret)
+ break;
+
+ dev_dbg(drv->dev, "OPP voltage adjusted for %lu kHz, %d uV\n",
+ corner[i].freq, corner[i].uV);
+ }
+
+ /* If we couldn't adjust voltage for all corners, something went wrong */
+ if (i < thread->num_corners)
+ return -EINVAL;
+
+ return ret;
+}
+
+/**
+ * cpr3_corner_init() - Calculate and set-up corners for the CPR HW
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * This function calculates all the corner parameters by comparing
+ * and interpolating the values read from the various set-points
+ * read from the fuses (also called "fuse corners") to generate and
+ * program to the CPR a lookup table that describes each voltage
+ * step, mapped to a performance level (or corner number).
+ *
+ * It also programs other essential parameters on the CPR and - if
+ * we are dealing with CPR-Hardened, it will also enable the internal
+ * interface between the Operating State Manager (OSM) and the CPRh
+ * in order to achieve CPU DVFS.
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr3_corner_init(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ const struct cpr_desc *desc = drv->desc;
+ const struct cpr_thread_desc *tdesc = thread->desc;
+ const struct cpr_fuse *fuses = thread->cpr_fuses;
+ int i, ret, total_corners, extra_corners, level, scaling = 0;
+ unsigned int fnum, fc;
+ const char *quot_offset;
+ const struct fuse_corner_data *fdata;
+ struct fuse_corner *fuse, *prev_fuse;
+ struct corner *corner, *prev_corner, *end;
+ struct corner_data *cdata;
+ struct dev_pm_opp *opp;
+ unsigned long freq;
+ u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
+
+ corner = thread->corners;
+ prev_corner = &thread->corners[0];
+ end = &corner[thread->num_corners - 1];
+
+ cdata = devm_kcalloc(drv->dev, thread->num_corners + drv->extra_corners,
+ sizeof(struct corner_data), GFP_KERNEL);
+ if (!cdata)
+ return -ENOMEM;
+
+ for (level = 1; level <= thread->num_corners; level++) {
+ opp = dev_pm_opp_find_level_exact(&thread->pd.dev, level);
+ if (IS_ERR(opp))
+ return -EINVAL;
+
+ /*
+ * If there is only one specified qcom,opp-fuse-level, then
+ * it is assumed that this only one is global and valid for
+ * all IDs, so try to get the specific one but, on failure,
+ * go for the global one.
+ */
+ fc = cpr_get_fuse_corner(opp, thread->id);
+ if (fc == 0) {
+ fc = cpr_get_fuse_corner(opp, 0);
+ if (fc == 0) {
+ dev_err(drv->dev, "qcom,opp-fuse-level is missing!\n");
+ dev_pm_opp_put(opp);
+ return -EINVAL;
+ }
+ }
+ fnum = fc - 1;
+
+ freq = cpr_get_opp_hz_for_req(opp, thread->attached_cpu_dev);
+ if (!freq) {
+ thread->num_corners = max(level - 1, 0);
+ end = &thread->corners[thread->num_corners - 1];
+ break;
+ }
+
+ /*
+ * If any post-vadj (open/closed loop) is not specified, then
+ * it's zero, meaning that it is not required for this corner.
+ */
+ cpr_get_corner_post_vadj(opp, thread->id,
+ &cdata[level - 1].oloop_vadj,
+ &cdata[level - 1].cloop_vadj);
+ cdata[level - 1].fuse_corner = fnum;
+ cdata[level - 1].freq = freq;
+
+ fuse = &thread->fuse_corners[fnum];
+ dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n",
+ freq, dev_pm_opp_get_level(opp) - 1, fnum);
+ if (freq > fuse->max_freq)
+ fuse->max_freq = freq;
+ dev_pm_opp_put(opp);
+
+ /*
+ * Make sure that the frequencies in the table are in ascending
+ * order, as this is critical for the algorithm to work.
+ */
+ if (cdata[level - 2].freq > freq) {
+ dev_err(drv->dev, "Frequency table not in ascending order.\n");
+ return -EINVAL;
+ }
+ }
+
+ if (thread->num_corners < 2) {
+ dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Get the quotient adjustment scaling factor, according to:
+ *
+ * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
+ * / (freq(corner_N) - freq(corner_N-1)), max_factor)
+ *
+ * QUOT(corner_N): quotient read from fuse for fuse corner N
+ * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1)
+ * freq(corner_N): max frequency in MHz supported by fuse corner N
+ * freq(corner_N-1): max frequency in MHz supported by fuse corner
+ * (N - 1)
+ *
+ * Then walk through the corners mapped to each fuse corner
+ * and calculate the quotient adjustment for each one using the
+ * following formula:
+ *
+ * quot_adjust = (freq_max - freq_corner) * scaling / 1000
+ *
+ * freq_max: max frequency in MHz supported by the fuse corner
+ * freq_corner: frequency in MHz corresponding to the corner
+ * scaling: calculated from above equation
+ *
+ *
+ * + +
+ * | v |
+ * q | f c o | f c
+ * u | c l | c
+ * o | f t | f
+ * t | c a | c
+ * | c f g | c f
+ * | e |
+ * +--------------- +----------------
+ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
+ * corner corner
+ *
+ * c = corner
+ * f = fuse corner
+ *
+ */
+ for (i = 0; corner <= end; corner++, i++) {
+ unsigned long freq_diff_mhz;
+ int ro_fac, vadj, prev_quot;
+
+ fnum = cdata[i].fuse_corner;
+ fdata = &tdesc->fuse_corner_data[fnum];
+ quot_offset = fuses[fnum].quotient_offset;
+ fuse = &thread->fuse_corners[fnum];
+ ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
+ if (fnum)
+ prev_fuse = &thread->fuse_corners[fnum - 1];
+ else
+ prev_fuse = NULL;
+
+ corner->fuse_corner = fuse;
+ corner->freq = cdata[i].freq;
+ corner->uV = fuse->uV;
+
+ if (prev_fuse) {
+ if (prev_fuse->ring_osc_idx == fuse->ring_osc_idx)
+ quot_offset = NULL;
+
+ scaling = cpr_calculate_scaling(drv->dev, quot_offset,
+ fdata, corner);
+ if (scaling < 0)
+ return scaling;
+
+ freq_diff_mhz = fuse->max_freq - corner->freq;
+ do_div(freq_diff_mhz, 1000000); /* now in MHz */
+
+ corner->quot_adjust = scaling * freq_diff_mhz;
+ do_div(corner->quot_adjust, 1000);
+
+ /* Fine-tune QUOT (closed-loop) based on fixed values */
+ ro_fac = cpr_get_ro_factor(tdesc, fnum, fuse->ring_osc_idx);
+ vadj = cdata[i].cloop_vadj;
+ corner->quot_adjust -= cpr3_adjust_quot(ro_fac, vadj);
+ dev_vdbg(drv->dev, "Quot fine-tuning to %d for post-vadj=%d\n",
+ corner->quot_adjust, vadj);
+
+ /*
+ * Make sure that we scale (up) monotonically.
+ * P.S.: Fuse quots can never be descending.
+ */
+ prev_quot = prev_corner->fuse_corner->quot;
+ prev_quot -= prev_corner->quot_adjust;
+ if (fuse->quot - corner->quot_adjust < prev_quot) {
+ int new_adj = prev_corner->fuse_corner->quot;
+
+ new_adj -= fuse->quot;
+ dev_vdbg(drv->dev, "Monotonic increase forced: %d->%d\n",
+ corner->quot_adjust, new_adj);
+ corner->quot_adjust = new_adj;
+ }
+
+ corner->uV = cpr_interpolate(corner,
+ drv->vreg_step, fdata);
+ }
+ /* Negative fuse quotients are nonsense. */
+ if (fuse->quot < corner->quot_adjust)
+ return -EINVAL;
+
+ min_quotient = min(min_quotient,
+ (u32)(fuse->quot - corner->quot_adjust));
+
+ /* Fine-tune voltages (open-loop) based on fixed values */
+ corner->uV += cdata[i].oloop_vadj;
+ dev_dbg(drv->dev, "Voltage fine-tuning to %d for post-vadj=%d\n",
+ corner->uV, cdata[i].oloop_vadj);
+
+ corner->max_uV = fuse->max_uV;
+ corner->min_uV = fuse->min_uV;
+ corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV);
+ dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d %d]\n",
+ corner->min_uV, corner->uV, corner->max_uV);
+
+ /* Make sure that we scale monotonically here, too. */
+ if (corner->uV < prev_corner->uV)
+ corner->uV = prev_corner->uV;
+
+ corner->last_uV = corner->uV;
+
+ /* Reduce the ceiling voltage if needed */
+ if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV)
+ corner->max_uV = corner->uV;
+ else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV)
+ corner->max_uV = max(corner->min_uV, fuse->uV);
+
+ corner->min_uV = max(corner->max_uV - fdata->range_uV,
+ corner->min_uV);
+
+ /*
+ * Adjust per-corner floor and ceiling voltages so that
+ * they do not overlap the memory Array Power Mux (APM)
+ * nor the Memory Accelerator (MEM-ACC) threshold voltages.
+ */
+ if (desc->apm_threshold)
+ cpr3_restrict_corner(corner, desc->apm_threshold,
+ desc->apm_hysteresis,
+ drv->vreg_step);
+ if (desc->mem_acc_threshold)
+ cpr3_restrict_corner(corner, desc->mem_acc_threshold,
+ 0, drv->vreg_step);
+
+ prev_corner = corner;
+ dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d quot %d\n", i,
+ corner->min_uV, corner->uV, corner->max_uV, scaling,
+ fuse->quot - corner->quot_adjust);
+ }
+
+ /* Additional setup for CPRh only */
+ if (desc->cpr_type < CTRL_TYPE_CPRH)
+ return 0;
+
+ /* If the OPPs can't be adjusted, programming the CPRh is useless */
+ ret = cprh_corner_adjust_opps(thread);
+ if (ret) {
+ dev_err(drv->dev, "Cannot adjust CPU OPP voltages: %d\n", ret);
+ return ret;
+ }
+
+ total_corners = thread->num_corners;
+ extra_corners = drv->extra_corners;
+
+ /* If the APM extra corner exists, add it now. */
+ if (desc->apm_crossover && desc->apm_threshold && extra_corners) {
+ /* Program the APM crossover corner on the CPR-Hardened */
+ thread->corners[total_corners].uV = desc->apm_crossover;
+ thread->corners[total_corners].min_uV = desc->apm_crossover;
+ thread->corners[total_corners].max_uV = desc->apm_crossover;
+ thread->corners[total_corners].is_open_loop = true;
+
+ /*
+ * We have calculated the APM parameters for this clock plan:
+ * make the APM *threshold* available to external callers.
+ * The crossover is used only internally in the CPR.
+ */
+ thread->ext_data.apm_threshold_uV = desc->apm_threshold;
+
+ dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] Open-Loop\n",
+ total_corners, desc->apm_crossover,
+ desc->apm_crossover, desc->apm_crossover);
+
+ total_corners++;
+ extra_corners--;
+ }
+
+ if (desc->mem_acc_threshold && extra_corners) {
+ /* Program the Memory Accelerator threshold corner to CPRh */
+ thread->corners[total_corners].uV = desc->mem_acc_threshold;
+ thread->corners[total_corners].min_uV = desc->mem_acc_threshold;
+ thread->corners[total_corners].max_uV = desc->mem_acc_threshold;
+ thread->corners[total_corners].is_open_loop = true;
+
+ /*
+ * We have calculated a mem-acc threshold for this clock plan:
+ * make it available to external callers.
+ */
+ thread->ext_data.mem_acc_threshold_uV = desc->mem_acc_threshold;
+
+ dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] Open-Loop\n",
+ total_corners, desc->mem_acc_threshold,
+ desc->mem_acc_threshold, desc->mem_acc_threshold);
+
+ total_corners++;
+ extra_corners--;
+ }
+
+ /*
+ * If there are any extra corners left, it means that even though we
+ * expect to fill in both APM and MEM-ACC crossovers, one couldn't
+ * satisfy requirements, which means that the specified parameters
+ * are wrong: in this case, inform the user and bail out, otherwise
+ * if we go on writing the (invalid) table to the CPR-Hardened, the
+ * hardware (in this case, the CPU) will surely freeze and crash.
+ */
+ if (unlikely(extra_corners)) {
+ dev_err(drv->dev, "APM/MEM-ACC corners: bad parameters.\n");
+ return -EINVAL;
+ }
+ /* Reassign extra_corners, as we have to exclude delta_quot for them */
+ extra_corners = drv->extra_corners;
+
+ /* Disable the interface between OSM and CPRh */
+ cpr_masked_write(thread, drv->reg_ctl,
+ CPRH_CTL_OSM_ENABLED, 0);
+
+ /* Program the GCNT before unmasking ring oscillator(s) */
+ for (i = 0; i < CPR3_RO_COUNT; i++) {
+ if (!(ring_osc_mask & BIT(i))) {
+ cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
+ dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, drv->gcnt);
+ }
+ }
+
+ /*
+ * Unmask the ring oscillator(s) that we're going to use: it seems
+ * to be mandatory to do this *before* sending the rest of the
+ * CPRhardened specific configuration.
+ */
+ dev_dbg(drv->dev, "Unmasking ring oscillators with mask 0x%x\n", ring_osc_mask);
+ cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), ring_osc_mask);
+
+ /* Setup minimum quotients for ring oscillators */
+ for (i = 0; i < CPR3_RO_COUNT; i++) {
+ u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, i);
+ u32 tgt_quot_val = 0;
+
+ if (!(ring_osc_mask & BIT(i)))
+ tgt_quot_val = min_quotient;
+
+ cpr_write(thread, tgt_quot_reg, tgt_quot_val);
+ dev_vdbg(drv->dev, "Programmed min quotient %u for Ring Oscillator %d\n",
+ tgt_quot_val, tgt_quot_reg);
+ }
+
+ for (i = 0; i < total_corners; i++) {
+ int volt_oloop_steps, volt_floor_steps, delta_quot_steps;
+ int ring_osc;
+ u32 val;
+
+ fnum = cdata[i].fuse_corner;
+ fuse = &thread->fuse_corners[fnum];
+
+ val = thread->corners[i].uV - desc->cpr_base_voltage;
+ volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
+
+ val = thread->corners[i].min_uV - desc->cpr_base_voltage;
+ volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
+
+ /*
+ * If we are accessing corners that are not used as
+ * an active DCVS set-point, then always select RO 0
+ * and zero out the delta quotient.
+ */
+ if (i >= thread->num_corners) {
+ ring_osc = 0;
+ delta_quot_steps = 0;
+ } else {
+ ring_osc = fuse->ring_osc_idx;
+ val = fuse->quot - thread->corners[i].quot_adjust;
+ val -= min_quotient;
+ delta_quot_steps = DIV_ROUND_UP(val,
+ CPRH_DELTA_QUOT_STEP_FACTOR);
+ }
+
+ if (volt_oloop_steps > CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE ||
+ volt_floor_steps > CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
+ delta_quot_steps > CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
+ dev_err(drv->dev, "Invalid cfg: oloop=%d, floor=%d, delta=%d\n",
+ volt_oloop_steps, volt_floor_steps,
+ delta_quot_steps);
+ return -EINVAL;
+ }
+ /* Green light: Go, Go, Go! */
+
+ /* Set number of open-loop steps */
+ val = volt_oloop_steps << CPRH_CORNER_INIT_VOLTAGE_SHIFT;
+ val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
+
+ /* Set number of floor voltage steps */
+ val |= (volt_floor_steps << CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
+ CPRH_CORNER_FLOOR_VOLTAGE_MASK;
+
+ /* Set number of target quotient delta steps */
+ val |= (delta_quot_steps << CPRH_CORNER_QUOT_DELTA_SHIFT) &
+ CPRH_CORNER_QUOT_DELTA_MASK;
+
+ /* Select ring oscillator for this corner */
+ val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
+ CPRH_CORNER_RO_SEL_MASK;
+
+ /* Open loop corner is usually APM/ACC crossover */
+ if (thread->corners[i].is_open_loop) {
+ dev_dbg(drv->dev, "Disabling Closed-Loop on corner %d\n", i);
+ val |= CPRH_CORNER_CPR_CL_DISABLE;
+ }
+ cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, i), val);
+
+ dev_dbg(drv->dev, "steps [%d]: open-loop %d, floor %d, delta_quot %d\n",
+ i, volt_oloop_steps, volt_floor_steps,
+ delta_quot_steps);
+ }
+
+ /* YAY! Setup is done! Enable the internal loop to start CPR. */
+ cpr_masked_write(thread, CPR3_REG_CPR_CTL,
+ CPR3_CPR_CTL_LOOP_EN_MASK,
+ CPR3_CPR_CTL_LOOP_EN_MASK);
+
+ /*
+ * All the writes are going through before enabling internal
+ * communication between the OSM and the CPRh controllers
+ * because we are never using relaxed accessors, but should
+ * we use them, it would be critical to issue a barrier here,
+ * otherwise there is a high risk of hardware lockups due to
+ * under-voltage for the selected CPU clock.
+ *
+ * Please note that the CPR-hardened gets set-up in Linux but
+ * then gets actually used in firmware (and only by the OSM);
+ * after handing it off we will have no more control on it.
+ */
+
+ /* Enable the interface between OSM and CPRh */
+ cpr_masked_write(thread, drv->reg_ctl,
+ CPRH_CTL_OSM_ENABLED,
+ CPRH_CTL_OSM_ENABLED);
+
+ /* On success, free cdata manually */
+ devm_kfree(drv->dev, cdata);
+ return 0;
+}
+
+/**
+ * cpr3_init_parameters() - Initialize CPR global parameters
+ * @drv: Main driver structure
+ *
+ * Initial "integrity" checks and setup for the thread-independent parameters.
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr3_init_parameters(struct cpr_drv *drv)
+{
+ const struct cpr_desc *desc = drv->desc;
+ struct clk *clk;
+
+ clk = devm_clk_get(drv->dev, "ref");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ drv->ref_clk_khz = clk_get_rate(clk);
+ do_div(drv->ref_clk_khz, 1000);
+
+ /* On CPRh this clock is not always-on... */
+ if (desc->cpr_type == CTRL_TYPE_CPRH)
+ clk_prepare_enable(clk);
+ else
+ devm_clk_put(drv->dev, clk);
+
+ if (desc->timer_cons_up > CPR3_THRESH_CONS_UP_MASK ||
+ desc->timer_cons_down > CPR3_THRESH_CONS_DOWN_MASK ||
+ desc->up_threshold > CPR3_THRESH_UP_THRESH_MASK ||
+ desc->down_threshold > CPR3_THRESH_DOWN_THRESH_MASK ||
+ desc->idle_clocks > CPR3_CPR_CTL_IDLE_CLOCKS_MASK ||
+ desc->count_mode > CPR3_CPR_CTL_COUNT_MODE_MASK ||
+ desc->count_repeat > CPR3_CPR_CTL_COUNT_REPEAT_MASK)
+ return -EINVAL;
+
+ /*
+ * Read the CPR version register only from CPR3 onwards:
+ * this is needed to get the additional register offsets.
+ *
+ * Note: When threaded, even if multi-controller, there
+ * is no chance to have different versions at the
+ * same time in the same domain, so it is safe to
+ * check this only on the first controller/thread.
+ */
+ drv->cpr_hw_rev = cpr_read(&drv->threads[0],
+ CPR3_REG_CPR_VERSION);
+ dev_dbg(drv->dev, "CPR hardware revision: 0x%x\n", drv->cpr_hw_rev);
+
+ if (drv->cpr_hw_rev >= CPRH_CPR_VERSION_4P5) {
+ drv->reg_corner = 0x3500;
+ drv->reg_corner_tid = 0xa0;
+ drv->reg_ctl = 0x3a80;
+ drv->reg_status = 0x3a84;
+ } else {
+ drv->reg_corner = 0x3a00;
+ drv->reg_corner_tid = 0;
+ drv->reg_ctl = 0x3aa0;
+ drv->reg_status = 0x3aa4;
+ }
+
+ dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n",
+ desc->up_threshold, desc->down_threshold);
+
+ return 0;
+}
+
+/**
+ * cpr3_find_initial_corner() - Finds boot-up p-state and enables CPR
+ * @thread: Structure holding CPR thread-specific parameters
+ *
+ * Differently from CPRv1, from CPRv3 onwards when we successfully find
+ * the target boot-up performance state, we must refresh the HW
+ * immediately to guarantee system stability and to avoid overheating
+ * during the boot process, thing that would more likely happen without
+ * this driver doing its job.
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr3_find_initial_corner(struct cpr_thread *thread)
+{
+ struct cpr_drv *drv = thread->drv;
+ struct corner *corner;
+ int uV, idx;
+
+ idx = cpr_find_initial_corner(drv->dev, thread->cpu_clk,
+ thread->corners,
+ thread->num_corners);
+ if (idx < 0)
+ return idx;
+
+ cpr_ctl_disable(thread);
+
+ corner = &thread->corners[idx];
+ cpr_corner_restore(thread, corner);
+
+ uV = regulator_get_voltage(drv->vreg);
+ uV = clamp(uV, corner->min_uV, corner->max_uV);
+
+ corner->last_uV = uV;
+ if (!drv->last_uV)
+ drv->last_uV = uV;
+
+ cpr_commit_state(thread);
+ thread->enabled = true;
+ cpr_switch(drv);
+
+ return 0;
+}
+
+static const int msm8998_gold_scaling_factor[][CPR3_RO_COUNT] = {
+ /* Fuse Corner 0 */
+ {
+ 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
+ 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
+ },
+ /* Fuse Corner 1 */
+ {
+ 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
+ 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
+ },
+ /* Fuse Corner 2 */
+ {
+ 2603, 2755, 2676, 2777, 2573, 2685, 2465, 2610,
+ 2312, 2423, 2243, 3104, 3022, 3036, 2740, 2303
+ },
+ /* Fuse Corner 3 */
+ {
+ 1901, 2016, 2096, 2228, 2034, 2161, 2077, 2188,
+ 1565, 1870, 1925, 2235, 2205, 2413, 1762, 1478
+ }
+};
+
+static const int msm8998_silver_scaling_factor[][CPR3_RO_COUNT] = {
+ /* Fuse Corner 0 */
+ {
+ 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
+ 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
+ },
+ /* Fuse Corner 1 */
+ {
+ 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
+ 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
+ },
+ /* Fuse Corner 2 */
+ {
+ 2391, 2550, 2483, 2638, 2382, 2564, 2259, 2555,
+ 2766, 3041, 2988, 2935, 2873, 2688, 2013, 2784
+ },
+ /* Fuse Corner 3 */
+ {
+ 2066, 2153, 2300, 2434, 2220, 2386, 2288, 2465,
+ 2028, 2511, 2487, 2734, 2554, 2117, 1892, 2377
+ }
+};
+
+static const struct cpr_thread_desc msm8998_thread_gold = {
+ .controller_id = 1,
+ .hw_tid = 0,
+ .ro_scaling_factor = msm8998_gold_scaling_factor,
+ .ro_avail_corners = ARRAY_SIZE(msm8998_gold_scaling_factor),
+ .sensor_range_start = 0,
+ .sensor_range_end = 9,
+ .init_voltage_step = 10000,
+ .init_voltage_width = 6,
+ .step_quot_init_min = 9,
+ .step_quot_init_max = 14,
+ .num_fuse_corners = 4,
+ .fuse_corner_data = (struct fuse_corner_data[]){
+ /* fuse corner 0 */
+ {
+ .ref_uV = 756000,
+ .max_uV = 828000,
+ .min_uV = 568000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 0,
+ .volt_oloop_adjust = 8000,
+ .max_volt_scale = 4,
+ .max_quot_scale = 10,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 1 */
+ {
+ .ref_uV = 756000,
+ .max_uV = 900000,
+ .min_uV = 624000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 0,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 320,
+ .max_quot_scale = 350,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 2 */
+ {
+ .ref_uV = 828000,
+ .max_uV = 952000,
+ .min_uV = 632000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 12000,
+ .volt_oloop_adjust = 12000,
+ .max_volt_scale = 620,
+ .max_quot_scale = 750,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 3 */
+ {
+ .ref_uV = 1056000,
+ .max_uV = 1136000,
+ .min_uV = 772000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = 50000,
+ .volt_oloop_adjust = 52000,
+ .max_volt_scale = 580,
+ .max_quot_scale = 1040,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ },
+};
+
+static const struct cpr_thread_desc msm8998_thread_silver = {
+ .controller_id = 0,
+ .hw_tid = 0,
+ .ro_scaling_factor = msm8998_silver_scaling_factor,
+ .ro_avail_corners = ARRAY_SIZE(msm8998_silver_scaling_factor),
+ .sensor_range_start = 0,
+ .sensor_range_end = 6,
+ .init_voltage_step = 10000,
+ .init_voltage_width = 6,
+ .step_quot_init_min = 11,
+ .step_quot_init_max = 12,
+ .num_fuse_corners = 4,
+ .fuse_corner_data = (struct fuse_corner_data[]){
+ /* fuse corner 0 */
+ {
+ .ref_uV = 688000,
+ .max_uV = 828000,
+ .min_uV = 568000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 20000,
+ .volt_oloop_adjust = 40000,
+ .max_volt_scale = 4,
+ .max_quot_scale = 10,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 1 */
+ {
+ .ref_uV = 756000,
+ .max_uV = 900000,
+ .min_uV = 632000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 26000,
+ .volt_oloop_adjust = 24000,
+ .max_volt_scale = 500,
+ .max_quot_scale = 800,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 2 */
+ {
+ .ref_uV = 828000,
+ .max_uV = 952000,
+ .min_uV = 664000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = 12000,
+ .volt_oloop_adjust = 12000,
+ .max_volt_scale = 280,
+ .max_quot_scale = 650,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+
+ },
+ /* fuse corner 3 */
+ {
+ .ref_uV = 1056000,
+ .max_uV = 1056000,
+ .min_uV = 772000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = 30000,
+ .volt_oloop_adjust = 30000,
+ .max_volt_scale = 430,
+ .max_quot_scale = 800,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ },
+};
+
+static const struct cpr_desc msm8998_cpr_desc = {
+ .cpr_type = CTRL_TYPE_CPRH,
+ .num_threads = 2,
+ .mem_acc_threshold = 852000,
+ .apm_threshold = 800000,
+ .apm_crossover = 880000,
+ .apm_hysteresis = 0,
+ .cpr_base_voltage = 352000,
+ .cpr_max_voltage = 1200000,
+ .timer_delay_us = 5000,
+ .timer_cons_up = 0,
+ .timer_cons_down = 2,
+ .up_threshold = 2,
+ .down_threshold = 2,
+ .idle_clocks = 15,
+ .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
+ .count_repeat = 14,
+ .gcnt_us = 1,
+ .vreg_step_fixed = 4000,
+ .vreg_step_up_limit = 1,
+ .vreg_step_down_limit = 1,
+ .vdd_settle_time_us = 34,
+ .corner_settle_time_us = 6,
+ .reduce_to_corner_uV = true,
+ .hw_closed_loop_en = true,
+ .threads = (const struct cpr_thread_desc *[]) {
+ &msm8998_thread_silver,
+ &msm8998_thread_gold,
+ },
+};
+
+static const struct cpr_acc_desc msm8998_cpr_acc_desc = {
+ .cpr_desc = &msm8998_cpr_desc,
+};
+
+static const int sdm630_gold_scaling_factor[][CPR3_RO_COUNT] = {
+ /* Same RO factors for all fuse corners */
+ {
+ 4040, 3230, 0, 2210, 2560, 2450, 2230, 2220,
+ 2410, 2300, 2560, 2470, 1600, 3120, 2620, 2280
+ }
+};
+
+static const int sdm630_silver_scaling_factor[][CPR3_RO_COUNT] = {
+ /* Same RO factors for all fuse corners */
+ {
+ 3600, 3600, 3830, 2430, 2520, 2700, 1790, 1760,
+ 1970, 1880, 2110, 2010, 2510, 4900, 4370, 4780,
+ }
+};
+
+static const struct cpr_thread_desc sdm630_thread_gold = {
+ .controller_id = 0,
+ .hw_tid = 0,
+ .ro_scaling_factor = sdm630_gold_scaling_factor,
+ .ro_avail_corners = ARRAY_SIZE(sdm630_gold_scaling_factor),
+ .sensor_range_start = 0,
+ .sensor_range_end = 6,
+ .init_voltage_step = 10000,
+ .init_voltage_width = 6,
+ .step_quot_init_min = 12,
+ .step_quot_init_max = 14,
+ .num_fuse_corners = 5,
+ .fuse_corner_data = (struct fuse_corner_data[]){
+ /* fuse corner 0 */
+ {
+ .ref_uV = 644000,
+ .max_uV = 724000,
+ .min_uV = 588000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 15000,
+ .max_volt_scale = 10,
+ .max_quot_scale = 300,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 1 */
+ {
+ .ref_uV = 788000,
+ .max_uV = 788000,
+ .min_uV = 652000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 5000,
+ .max_volt_scale = 320,
+ .max_quot_scale = 275,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 2 */
+ {
+ .ref_uV = 868000,
+ .max_uV = 868000,
+ .min_uV = 712000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 5000,
+ .max_volt_scale = 350,
+ .max_quot_scale = 800,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 3 */
+ {
+ .ref_uV = 988000,
+ .max_uV = 988000,
+ .min_uV = 784000,
+ .range_uV = 66000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 868,
+ .max_quot_scale = 980,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 4 */
+ {
+ .ref_uV = 1068000,
+ .max_uV = 1068000,
+ .min_uV = 844000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 868,
+ .max_quot_scale = 980,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ },
+};
+
+static const struct cpr_thread_desc sdm630_thread_silver = {
+ .controller_id = 1,
+ .hw_tid = 0,
+ .ro_scaling_factor = sdm630_silver_scaling_factor,
+ .ro_avail_corners = ARRAY_SIZE(sdm630_silver_scaling_factor),
+ .sensor_range_start = 0,
+ .sensor_range_end = 6,
+ .init_voltage_step = 10000,
+ .init_voltage_width = 6,
+ .step_quot_init_min = 12,
+ .step_quot_init_max = 14,
+ .num_fuse_corners = 3,
+ .fuse_corner_data = (struct fuse_corner_data[]){
+ /* fuse corner 0 */
+ {
+ .ref_uV = 644000,
+ .max_uV = 724000,
+ .min_uV = 588000,
+ .range_uV = 32000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 10,
+ .max_quot_scale = 360,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 1 */
+ {
+ .ref_uV = 788000,
+ .max_uV = 788000,
+ .min_uV = 652000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 500,
+ .max_quot_scale = 550,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ /* fuse corner 2 */
+ {
+ .ref_uV = 1068000,
+ .max_uV = 1068000,
+ .min_uV = 800000,
+ .range_uV = 40000,
+ .volt_cloop_adjust = -30000,
+ .volt_oloop_adjust = 0,
+ .max_volt_scale = 2370,
+ .max_quot_scale = 550,
+ .quot_offset = 0,
+ .quot_scale = 1,
+ .quot_adjust = 0,
+ .quot_offset_scale = 5,
+ .quot_offset_adjust = 0,
+ },
+ },
+};
+
+static const struct cpr_desc sdm630_cpr_desc = {
+ .cpr_type = CTRL_TYPE_CPRH,
+ .num_threads = 2,
+ .apm_threshold = 872000,
+ .apm_crossover = 872000,
+ .apm_hysteresis = 20000,
+ .cpr_base_voltage = 400000,
+ .cpr_max_voltage = 1300000,
+ .timer_delay_us = 5000,
+ .timer_cons_up = 0,
+ .timer_cons_down = 2,
+ .up_threshold = 2,
+ .down_threshold = 2,
+ .idle_clocks = 15,
+ .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
+ .count_repeat = 14,
+ .gcnt_us = 1,
+ .vreg_step_fixed = 4000,
+ .vreg_step_up_limit = 1,
+ .vreg_step_down_limit = 1,
+ .vdd_settle_time_us = 34,
+ .corner_settle_time_us = 5,
+ .reduce_to_corner_uV = true,
+ .hw_closed_loop_en = true,
+ .threads = (const struct cpr_thread_desc *[]) {
+ &sdm630_thread_gold,
+ &sdm630_thread_silver,
+ },
+};
+
+static const struct cpr_acc_desc sdm630_cpr_acc_desc = {
+ .cpr_desc = &sdm630_cpr_desc,
+};
+
+static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
+ struct dev_pm_opp *opp)
+{
+ return dev_pm_opp_get_level(opp);
+}
+
+static int cpr_power_off(struct generic_pm_domain *domain)
+{
+ struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
+
+ return cpr_disable(thread);
+}
+
+static int cpr_power_on(struct generic_pm_domain *domain)
+{
+ struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
+
+ return cpr_enable(thread);
+}
+
+static void cpr_pd_detach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
+ struct cpr_drv *drv = thread->drv;
+
+ mutex_lock(&drv->lock);
+
+ dev_dbg(drv->dev, "detach callback for: %s\n", dev_name(dev));
+ thread->attached_cpu_dev = NULL;
+
+ mutex_unlock(&drv->lock);
+}
+
+static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
+ struct cpr_drv *drv = thread->drv;
+ const struct acc_desc *acc_desc = drv->acc_desc;
+ bool cprh_opp_remove_table = false;
+ int ret = 0;
+
+ mutex_lock(&drv->lock);
+
+ dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev));
+
+ /*
+ * This driver only supports scaling voltage for a CPU cluster
+ * where all CPUs in the cluster share a single regulator.
+ * Therefore, save the struct device pointer only for the first
+ * CPU device that gets attached. There is no need to do any
+ * additional initialization when further CPUs get attached.
+ * This is not an error condition.
+ */
+ if (thread->attached_cpu_dev)
+ goto unlock;
+
+ /*
+ * cpr_scale_voltage() requires the direction (if we are changing
+ * to a higher or lower OPP). The first time
+ * cpr_set_performance_state() is called, there is no previous
+ * performance state defined. Therefore, we call
+ * cpr_find_initial_corner() that gets the CPU clock frequency
+ * set by the bootloader, so that we can determine the direction
+ * the first time cpr_set_performance_state() is called.
+ */
+ thread->cpu_clk = devm_clk_get(dev, NULL);
+ if (drv->desc->cpr_type < CTRL_TYPE_CPRH && IS_ERR(thread->cpu_clk)) {
+ ret = PTR_ERR(thread->cpu_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(drv->dev, "could not get cpu clk: %d\n", ret);
+ goto unlock;
+ }
+ thread->attached_cpu_dev = dev;
+
+ /*
+ * We are exporting the APM and MEM-ACC thresholds to the caller;
+ * while APM is necessary in the CPU CPR case, MEM-ACC may not be,
+ * depending on the SoC and on fuses.
+ * Initialize both to an invalid value, so that the caller can check
+ * if they got calculated or read from fuses in this driver.
+ */
+ thread->ext_data.apm_threshold_uV = -1;
+ thread->ext_data.mem_acc_threshold_uV = -1;
+ dev_set_drvdata(thread->attached_cpu_dev, &thread->ext_data);
+
+ dev_dbg(drv->dev, "using cpu clk from: %s\n",
+ dev_name(thread->attached_cpu_dev));
+
+ /*
+ * Everything related to (virtual) corners has to be initialized
+ * here, when attaching to the power domain, since we need to know
+ * the maximum frequency for each fuse corner, and this is only
+ * available after the cpufreq driver has attached to us.
+ * The reason for this is that we need to know the highest
+ * frequency associated with each fuse corner.
+ */
+ ret = dev_pm_opp_get_opp_count(&thread->pd.dev);
+ if (ret < 0) {
+ dev_err(drv->dev, "could not get OPP count\n");
+ thread->attached_cpu_dev = NULL;
+ goto unlock;
+ }
+ thread->num_corners = ret;
+
+ thread->corners = devm_kcalloc(drv->dev,
+ thread->num_corners +
+ drv->extra_corners,
+ sizeof(*thread->corners),
+ GFP_KERNEL);
+ if (!thread->corners) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ /*
+ * If we are on CPR-Hardened we have to make sure that the attached
+ * device has a OPP table installed, as we're going to modify it here
+ * with our calculations based on qfprom values.
+ */
+ if (drv->desc->cpr_type == CTRL_TYPE_CPRH) {
+ ret = dev_pm_opp_of_add_table(dev);
+ if (ret && ret != -EEXIST) {
+ dev_err(drv->dev, "Cannot add table: %d\n", ret);
+ goto unlock;
+ }
+ cprh_opp_remove_table = true;
+ }
+
+ ret = cpr3_corner_init(thread);
+ if (ret)
+ goto exit;
+
+ if (drv->desc->cpr_type < CTRL_TYPE_CPRH) {
+ ret = cpr3_find_initial_corner(thread);
+ if (ret)
+ goto exit;
+
+ if (acc_desc->config)
+ regmap_multi_reg_write(drv->tcsr, acc_desc->config,
+ acc_desc->num_regs_per_fuse);
+
+ /* Enable ACC if required */
+ if (acc_desc->enable_mask)
+ regmap_update_bits(drv->tcsr, acc_desc->enable_reg,
+ acc_desc->enable_mask,
+ acc_desc->enable_mask);
+ }
+ dev_info(drv->dev, "thread %d initialized with %u OPPs\n",
+ thread->id, thread->num_corners);
+exit:
+ /*
+ * If we are on CPRh and we reached an error condition, we installed
+ * the OPP table but we haven't done any setup on it, nor we ever will.
+ * In order to leave a clean state, remove the table.
+ */
+ if (ret && cprh_opp_remove_table)
+ dev_pm_opp_of_remove_table(thread->attached_cpu_dev);
+unlock:
+ mutex_unlock(&drv->lock);
+
+ return ret;
+}
+
+static int cpr3_debug_info_show(struct seq_file *s, void *unused)
+{
+ u32 ro_sel, ctl, irq_status, reg, quot;
+ struct cpr_thread *thread = s->private;
+ struct corner *corner = thread->corners;
+ struct fuse_corner *fuse = thread->fuse_corners;
+ unsigned int i;
+
+ const struct {
+ const char *name;
+ uint32_t mask;
+ uint8_t shift;
+ } result0_fields[] = {
+ { "busy", 1, 0 },
+ { "step_dn", 1, 1 },
+ { "step_up", 1, 2 },
+ { "error_steps", CPR3_RESULT0_ERROR_STEPS_MASK,
+ CPR3_RESULT0_ERROR_STEPS_SHIFT },
+ { "error", CPR3_RESULT0_ERROR_MASK, CPR3_RESULT0_ERROR_SHIFT },
+ { "negative", 1, 20 },
+ }, result1_fields[] = {
+ { "quot_min", CPR3_RESULT1_QUOT_MIN_MASK,
+ CPR3_RESULT1_QUOT_MIN_SHIFT },
+ { "quot_max", CPR3_RESULT1_QUOT_MAX_MASK,
+ CPR3_RESULT1_QUOT_MAX_SHIFT },
+ { "ro_min", CPR3_RESULT1_RO_MIN_MASK,
+ CPR3_RESULT1_RO_MIN_SHIFT },
+ { "ro_max", CPR3_RESULT1_RO_MAX_MASK,
+ CPR3_RESULT1_RO_MAX_SHIFT },
+ }, result2_fields[] = {
+ { "qout_step_min", CPR3_RESULT2_STEP_QUOT_MIN_MASK,
+ CPR3_RESULT2_STEP_QUOT_MIN_SHIFT },
+ { "qout_step_max", CPR3_RESULT2_STEP_QUOT_MAX_MASK,
+ CPR3_RESULT2_STEP_QUOT_MAX_SHIFT },
+ { "sensor_min", CPR3_RESULT2_SENSOR_MIN_MASK,
+ CPR3_RESULT2_SENSOR_MIN_SHIFT },
+ { "sensor_max", CPR3_RESULT2_SENSOR_MAX_MASK,
+ CPR3_RESULT2_SENSOR_MAX_SHIFT },
+ };
+
+ if (thread->drv->desc->cpr_type < CTRL_TYPE_CPRH)
+ seq_printf(s, "current_volt = %d uV\n", thread->drv->last_uV);
+
+ irq_status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
+ seq_printf(s, "irq_status = %#02X\n", irq_status);
+
+ ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
+ seq_printf(s, "cpr_ctl = %#02X\n", ctl);
+
+ seq_printf(s, "thread %d - hw tid: %u - enabled: %d:\n",
+ thread->id, thread->desc->hw_tid, thread->enabled);
+ seq_printf(s, "%d corners, derived from %d fuse corners\n",
+ thread->num_corners, thread->desc->num_fuse_corners);
+
+ for (i = 0; i < thread->num_corners; i++, corner++)
+ seq_printf(s, "corner %d - uV=[%d %d %d] quot=%d freq=%lu\n",
+ i, corner->min_uV, corner->uV, corner->max_uV,
+ corner->quot_adjust, corner->freq);
+
+ for (i = 0; i < thread->desc->num_fuse_corners; i++, fuse++)
+ seq_printf(s, "fuse %d - uV=[%d %d %d] quot=%d freq=%lu\n",
+ i, fuse->min_uV, fuse->uV, fuse->max_uV,
+ fuse->quot, corner->freq);
+
+ seq_printf(s, "requested voltage: %d uV\n", thread->corner->last_uV);
+
+ ro_sel = corner->fuse_corner->ring_osc_idx;
+ quot = cpr_read(thread, CPR3_REG_TARGET_QUOT(i, ro_sel));
+ seq_printf(s, "quot_target (%u) = %#02X\n", ro_sel, quot);
+
+ reg = cpr_read(thread, CPR3_REG_RESULT0(i));
+ seq_printf(s, "cpr_result_0 = %#02X\n [", reg);
+ for (i = 0; i < ARRAY_SIZE(result0_fields); i++)
+ seq_printf(s, "%s%s = %u",
+ i ? ", " : "",
+ result0_fields[i].name,
+ (reg >> result0_fields[i].shift) &
+ result0_fields[i].mask);
+ seq_puts(s, "]\n");
+ reg = cpr_read(thread, CPR3_REG_RESULT1(i));
+ seq_printf(s, "cpr_result_1 = %#02X\n [", reg);
+ for (i = 0; i < ARRAY_SIZE(result1_fields); i++)
+ seq_printf(s, "%s%s = %u",
+ i ? ", " : "",
+ result1_fields[i].name,
+ (reg >> result1_fields[i].shift) &
+ result1_fields[i].mask);
+ seq_puts(s, "]\n");
+ reg = cpr_read(thread, CPR3_REG_RESULT2(i));
+ seq_printf(s, "cpr_result_2 = %#02X\n [", reg);
+ for (i = 0; i < ARRAY_SIZE(result2_fields); i++)
+ seq_printf(s, "%s%s = %u",
+ i ? ", " : "",
+ result2_fields[i].name,
+ (reg >> result2_fields[i].shift) &
+ result2_fields[i].mask);
+ seq_puts(s, "]\n");
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(cpr3_debug_info);
+
+static void cpr3_debugfs_init(struct cpr_drv *drv)
+{
+ int i;
+
+ drv->debugfs = debugfs_create_dir("qcom_cpr3", NULL);
+
+ for (i = 0; i < drv->desc->num_threads; i++) {
+ char buf[50];
+
+ snprintf(buf, sizeof(buf), "thread%d", i);
+
+ debugfs_create_file(buf, 0444, drv->debugfs, &drv->threads[i],
+ &cpr3_debug_info_fops);
+ }
+}
+
+/**
+ * cpr_thread_init() - Initialize CPR thread related parameters
+ * @drv: Main driver structure
+ * @tid: Thread ID
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr_thread_init(struct cpr_drv *drv, int tid)
+{
+ const struct cpr_desc *desc = drv->desc;
+ const struct cpr_thread_desc *tdesc = desc->threads[tid];
+ struct cpr_thread *thread = &drv->threads[tid];
+ int ret;
+
+ if (tdesc->step_quot_init_min > CPR3_CPR_STEP_QUOT_MIN_MASK ||
+ tdesc->step_quot_init_max > CPR3_CPR_STEP_QUOT_MAX_MASK)
+ return -EINVAL;
+
+ thread->id = tid;
+ thread->drv = drv;
+ thread->desc = tdesc;
+ thread->fuse_corners = devm_kcalloc(drv->dev,
+ tdesc->num_fuse_corners +
+ drv->extra_corners,
+ sizeof(*thread->fuse_corners),
+ GFP_KERNEL);
+ if (!thread->fuse_corners)
+ return -ENOMEM;
+
+ thread->cpr_fuses = cpr_get_fuses(drv->dev, tid,
+ tdesc->num_fuse_corners);
+ if (IS_ERR(thread->cpr_fuses))
+ return PTR_ERR(thread->cpr_fuses);
+
+ ret = cpr_populate_ring_osc_idx(thread->drv->dev, thread->fuse_corners,
+ thread->cpr_fuses,
+ tdesc->num_fuse_corners);
+ if (ret)
+ return ret;
+
+ ret = cpr_fuse_corner_init(thread);
+ if (ret)
+ return ret;
+
+ thread->pd.name = devm_kasprintf(drv->dev, GFP_KERNEL,
+ "%s_thread%d",
+ drv->dev->of_node->full_name,
+ thread->id);
+ if (!thread->pd.name)
+ return -EINVAL;
+
+ thread->pd.power_off = cpr_power_off;
+ thread->pd.power_on = cpr_power_on;
+ thread->pd.opp_to_performance_state = cpr_get_performance_state;
+ thread->pd.attach_dev = cpr_pd_attach_dev;
+ thread->pd.detach_dev = cpr_pd_detach_dev;
+
+ /* CPR-Hardened performance states are managed in firmware */
+ if (desc->cpr_type == CTRL_TYPE_CPRH)
+ thread->pd.set_performance_state = cprh_dummy_set_performance_state;
+ else
+ thread->pd.set_performance_state = cpr_set_performance_state;
+
+ /* Anything later than CPR1 must be always-on for now */
+ thread->pd.flags = GENPD_FLAG_ALWAYS_ON;
+
+ drv->cell_data.domains[tid] = &thread->pd;
+
+ ret = pm_genpd_init(&thread->pd, NULL, false);
+ if (ret)
+ return ret;
+
+ /* On CPRhardened, the interrupts are managed in firmware */
+ if (desc->cpr_type < CTRL_TYPE_CPRH) {
+ INIT_WORK(&thread->restart_work, cpr_restart_worker);
+
+ ret = devm_request_threaded_irq(drv->dev, drv->irq,
+ NULL, cpr_irq_handler,
+ IRQF_ONESHOT |
+ IRQF_TRIGGER_RISING,
+ "cpr", drv);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * cpr3_resources_init() - Initialize resources used by this driver
+ * @pdev: Platform device
+ * @drv: Main driver structure
+ *
+ * Return: Zero for success, negative number on error
+ */
+static int cpr3_resources_init(struct platform_device *pdev,
+ struct cpr_drv *drv)
+{
+ const struct cpr_desc *desc = drv->desc;
+ struct cpr_thread *threads = drv->threads;
+ unsigned int i;
+ u8 cid_mask = 0;
+
+ /*
+ * Here, we are accounting for the following usecases:
+ * - One controller
+ * - One or multiple threads on the same iospace
+ *
+ * - Multiple controllers
+ * - Each controller has its own iospace and each
+ * may have one or multiple threads in their
+ * parent controller's iospace
+ *
+ * Then, to avoid complicating the code for no reason,
+ * this also needs a mandatory order in the list of
+ * threads which implies that all of them from the same
+ * controllers are specified sequentially. As an example:
+ *
+ * C0-T0, C0-T1...C0-Tn, C1-T0, C1-T1...C1-Tn
+ */
+ for (i = 0; i < desc->num_threads; i++) {
+ u8 cid = desc->threads[i]->controller_id;
+
+ if (cid_mask & BIT(cid)) {
+ if (desc->threads[i - 1]->controller_id != cid) {
+ dev_err(drv->dev, "Bad threads order. Please fix!\n");
+ return -EINVAL;
+ }
+ threads[i].base = threads[i - 1].base;
+ continue;
+ }
+ threads[i].base = devm_platform_ioremap_resource(pdev, cid);
+ if (IS_ERR(threads[i].base))
+ return PTR_ERR(threads[i].base);
+ cid_mask |= BIT(cid);
+ }
+ return 0;
+}
+
+static int cpr_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct cpr_drv *drv;
+ const struct cpr_desc *desc;
+ const struct cpr_acc_desc *data;
+ struct device_node *np;
+ unsigned int i;
+ int ret;
+
+ data = of_device_get_match_data(dev);
+ if (!data || !data->cpr_desc)
+ return -EINVAL;
+
+ desc = data->cpr_desc;
+
+ /* CPRh disallows MEM-ACC access from the HLOS */
+ if (!data->acc_desc && desc->cpr_type < CTRL_TYPE_CPRH)
+ return -EINVAL;
+
+ drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
+ if (!drv)
+ return -ENOMEM;
+
+ drv->dev = dev;
+ drv->desc = desc;
+ drv->threads = devm_kcalloc(dev, desc->num_threads,
+ sizeof(*drv->threads), GFP_KERNEL);
+ if (!drv->threads)
+ return -ENOMEM;
+
+ drv->cell_data.num_domains = desc->num_threads;
+ drv->cell_data.domains = devm_kcalloc(drv->dev,
+ drv->cell_data.num_domains,
+ sizeof(*drv->cell_data.domains),
+ GFP_KERNEL);
+ if (!drv->cell_data.domains)
+ return -ENOMEM;
+
+ if (data->acc_desc)
+ drv->acc_desc = data->acc_desc;
+
+ mutex_init(&drv->lock);
+
+ if (desc->cpr_type < CTRL_TYPE_CPRH) {
+ np = of_parse_phandle(dev->of_node, "acc-syscon", 0);
+ if (!np)
+ return -ENODEV;
+
+ drv->tcsr = syscon_node_to_regmap(np);
+ of_node_put(np);
+ if (IS_ERR(drv->tcsr))
+ return PTR_ERR(drv->tcsr);
+ }
+
+ ret = cpr3_resources_init(pdev, drv);
+ if (ret)
+ return ret;
+
+ drv->irq = platform_get_irq_optional(pdev, 0);
+ if (desc->cpr_type != CTRL_TYPE_CPRH && drv->irq < 0)
+ return -EINVAL;
+
+ /* On CPRhardened, vreg access it not allowed */
+ drv->vreg = devm_regulator_get_optional(dev, "vdd");
+ if (desc->cpr_type != CTRL_TYPE_CPRH && IS_ERR(drv->vreg))
+ return PTR_ERR(drv->vreg);
+
+ /*
+ * On at least CPRhardened, vreg is unaccessible and there is no
+ * way to read linear step from that regulator, hence it is hardcoded
+ * in the driver;
+ * When the vreg_step is not declared in the cpr data (or is zero),
+ * then having access to the vreg regulator is mandatory, as this
+ * will be retrieved through the regulator API.
+ */
+ if (desc->vreg_step_fixed)
+ drv->vreg_step = desc->vreg_step_fixed;
+ else
+ drv->vreg_step = regulator_get_linear_step(drv->vreg);
+
+ if (!drv->vreg_step)
+ return -EINVAL;
+
+ /*
+ * Initialize fuse corners, since it simply depends
+ * on data in efuses.
+ * Everything related to (virtual) corners has to be
+ * initialized after attaching to the power domain,
+ * since it depends on the CPU's OPP table.
+ */
+ ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &drv->fusing_rev);
+ if (ret)
+ return ret;
+
+ ret = nvmem_cell_read_variable_le_u32(dev, "cpr_speed_bin", &drv->speed_bin);
+ if (ret)
+ return ret;
+
+ /*
+ * Some SoCs require extra corners for MEM-ACC or APM: if
+ * the related parameters have been specified, then reserve
+ * a corner for the APM and/or MEM-ACC crossover, used by
+ * OSM and CPRh HW to set the supply voltage during the APM
+ * and/or MEM-ACC switch routine.
+ */
+ if (desc->cpr_type == CTRL_TYPE_CPRH) {
+ if (desc->apm_crossover && desc->apm_hysteresis >= 0)
+ drv->extra_corners++;
+
+ if (desc->mem_acc_threshold)
+ drv->extra_corners++;
+ }
+
+ /* Initialize all threads */
+ for (i = 0; i < desc->num_threads; i++) {
+ ret = cpr_thread_init(drv, i);
+ if (ret)
+ return ret;
+ }
+
+ /* Initialize global parameters */
+ ret = cpr3_init_parameters(drv);
+ if (ret)
+ return ret;
+
+ /* Write initial configuration on all threads */
+ for (i = 0; i < desc->num_threads; i++) {
+ ret = cpr_configure(&drv->threads[i]);
+ if (ret)
+ return ret;
+ }
+
+ ret = of_genpd_add_provider_onecell(dev->of_node, &drv->cell_data);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, drv);
+ cpr3_debugfs_init(drv);
+
+ return 0;
+}
+
+static int cpr_remove(struct platform_device *pdev)
+{
+ struct cpr_drv *drv = platform_get_drvdata(pdev);
+ int i;
+
+ of_genpd_del_provider(pdev->dev.of_node);
+
+ for (i = 0; i < drv->desc->num_threads; i++) {
+ cpr_ctl_disable(&drv->threads[i]);
+ cpr_irq_set(&drv->threads[i], 0);
+ pm_genpd_remove(&drv->threads[i].pd);
+ }
+
+ debugfs_remove_recursive(drv->debugfs);
+
+ return 0;
+}
+
+static const struct of_device_id cpr3_match_table[] = {
+ { .compatible = "qcom,msm8998-cprh", .data = &msm8998_cpr_acc_desc },
+ { .compatible = "qcom,sdm630-cprh", .data = &sdm630_cpr_acc_desc },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cpr3_match_table);
+
+static struct platform_driver cpr3_driver = {
+ .probe = cpr_probe,
+ .remove = cpr_remove,
+ .driver = {
+ .name = "qcom-cpr3",
+ .of_match_table = cpr3_match_table,
+ },
+};
+module_platform_driver(cpr3_driver)
+
+MODULE_DESCRIPTION("Core Power Reduction (CPR) v3/v4 driver");
+MODULE_LICENSE("GPL v2");
\ No newline at end of file
--
2.39.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
` (3 preceding siblings ...)
2023-01-10 17:56 ` [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened Konrad Dybcio
@ 2023-01-10 17:56 ` Konrad Dybcio
2023-01-10 18:45 ` Konrad Dybcio
4 siblings, 1 reply; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 17:56 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno, Konrad Dybcio,
AngeloGioacchino Del Regno, Rob Herring, Krzysztof Kozlowski,
devicetree, linux-kernel
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
Now that the CPR v3/v4/Hardened is ready, enable it on MSM8998.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
[Konrad: separate from adding cpufreq, sort nodes and use lowercase hex]
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
arch/arm64/boot/dts/qcom/msm8998.dtsi | 325 ++++++++++++++++++++++++++
1 file changed, 325 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index af29a4bfd109..84f73484441f 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -139,6 +139,9 @@ CPU0: cpu@0 {
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu_gold_opp_table>;
+ power-domains = <&apc_cprh 0>;
+ power-domain-names = "cprh";
L2_0: l2-cache {
compatible = "cache";
cache-level = <2>;
@@ -153,6 +156,9 @@ CPU1: cpu@1 {
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu_gold_opp_table>;
+ power-domains = <&apc_cprh 0>;
+ power-domain-names = "cprh";
};
CPU2: cpu@2 {
@@ -163,6 +169,9 @@ CPU2: cpu@2 {
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu_gold_opp_table>;
+ power-domains = <&apc_cprh 0>;
+ power-domain-names = "cprh";
};
CPU3: cpu@3 {
@@ -173,6 +182,9 @@ CPU3: cpu@3 {
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu_gold_opp_table>;
+ power-domains = <&apc_cprh 0>;
+ power-domain-names = "cprh";
};
CPU4: cpu@100 {
@@ -183,6 +195,9 @@ CPU4: cpu@100 {
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
+ operating-points-v2 = <&cpu_silver_opp_table>;
+ power-domains = <&apc_cprh 1>;
+ power-domain-names = "cprh";
L2_1: l2-cache {
compatible = "cache";
cache-level = <2>;
@@ -197,6 +212,9 @@ CPU5: cpu@101 {
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
+ operating-points-v2 = <&cpu_silver_opp_table>;
+ power-domains = <&apc_cprh 1>;
+ power-domain-names = "cprh";
};
CPU6: cpu@102 {
@@ -207,6 +225,9 @@ CPU6: cpu@102 {
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
+ operating-points-v2 = <&cpu_silver_opp_table>;
+ power-domains = <&apc_cprh 1>;
+ power-domain-names = "cprh";
};
CPU7: cpu@103 {
@@ -217,6 +238,9 @@ CPU7: cpu@103 {
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
+ operating-points-v2 = <&cpu_silver_opp_table>;
+ power-domains = <&apc_cprh 1>;
+ power-domain-names = "cprh";
};
cpu-map {
@@ -310,6 +334,65 @@ scm {
};
};
+ cpu_gold_opp_table: opp-table-gold {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ required-opps = <&cprh_opp3>;
+ };
+
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ required-opps = <&cprh_opp2>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&cprh_opp1>;
+ };
+ };
+
+ cpu_silver_opp_table: opp-table-silver {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-1843200000 {
+ opp-hz = /bits/ 64 <1843200000>;
+ required-opps = <&cprh_opp3>;
+ };
+
+ opp-1094400000 {
+ opp-hz = /bits/ 64 <1094400000>;
+ required-opps = <&cprh_opp2>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&cprh_opp1>;
+ };
+ };
+
+ cprh_opp_table: opp-table-cprh {
+ compatible = "operating-points-v2-qcom-level";
+
+ cprh_opp1: opp1 {
+ opp-level = <1>;
+ qcom,opp-fuse-level = <1>;
+ };
+
+ cprh_opp2: opp2 {
+ opp-level = <2>;
+ qcom,opp-fuse-level = <2>;
+ };
+
+ cprh_opp3: opp3 {
+ opp-level = <3>;
+ qcom,opp-fuse-level = <2 3>;
+ };
+ };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -839,6 +922,174 @@ qfprom: qfprom@784000 {
#address-cells = <1>;
#size-cells = <1>;
+ cpr_efuse_speedbin: speedbin@133 {
+ reg = <0x133 0x8>;
+ bits = <5 3>;
+ };
+
+ cpr_fuse_revision: cpr_fusing_rev@13e {
+ reg = <0x13e 0x1>;
+ bits = <3 3>;
+ };
+
+ /* CPR Ring Oscillator: Power Cluster */
+ cpr_ro_sel3_pwrcl: rosel3_pwrcl@218 {
+ reg = <0x218 0x1>;
+ bits = <0 4>;
+ };
+
+ cpr_ro_sel2_pwrcl: rosel2_pwrcl@218 {
+ reg = <0x218 0x1>;
+ bits = <4 4>;
+ };
+
+ cpr_ro_sel1_pwrcl: rosel1_pwrcl@219 {
+ reg = <0x219 0x1>;
+ bits = <0 4>;
+ };
+
+ cpr_ro_sel0_pwrcl: rosel0_pwrcl@219 {
+ reg = <0x219 0x1>;
+ bits = <4 4>;
+ };
+
+ /* CPR Init Voltage: Power Cluster */
+ cpr_init_voltage3_pwrcl: ivolt3_pwrcl@21a {
+ reg = <0x21a 0x1>;
+ bits = <0 6>;
+ };
+
+ cpr_init_voltage2_pwrcl: ivolt2_pwrcl@21a {
+ reg = <0x21a 0x1>;
+ bits = <6 6>;
+ };
+
+ cpr_init_voltage1_pwrcl: ivolt1_pwrcl@21b {
+ reg = <0x21b 0x1>;
+ bits = <4 6>;
+ };
+
+ cpr_init_voltage0_pwrcl: ivolt0_pwrcl@21c {
+ reg = <0x21c 0x1>;
+ bits = <2 6>;
+ };
+
+ /* CPR Target Quotients: Power Cluster */
+ cpr_quot3_pwrcl: quot3_pwrcl@21d {
+ reg = <0x21d 0x2>;
+ bits = <6 12>;
+ };
+
+ cpr_quot2_pwrcl: quot2_pwrcl@21f {
+ reg = <0x21f 0x2>;
+ bits = <2 11>;
+ };
+
+ cpr_quot1_pwrcl: quot1_pwrcl@220 {
+ reg = <0x220 0x2>;
+ bits = <6 12>;
+ };
+
+ cpr_quot0_pwrcl: quot0_pwrcl@222 {
+ reg = <0x222 0x2>;
+ bits = <2 12>;
+ };
+
+ /* CPR Quotient Offsets: Power Cluster */
+ cpr_quot_offset3_pwrcl: qoff3_pwrcl@226 {
+ reg = <0x226 0x1>;
+ bits = <1 7>;
+ };
+
+ cpr_quot_offset2_pwrcl: qoff2_pwrcl@227 {
+ reg = <0x227 0x1>;
+ bits = <0 7>;
+ };
+
+ cpr_quot_offset1_pwrcl: qoff1_pwrcl@227 {
+ reg = <0x227 0x1>;
+ bits = <7 6>;
+ };
+
+ /* CPR Ring Oscillator: Performance Cluster */
+ cpr_ro_sel3_perfcl: rosel3_perfcl@229 {
+ reg = <0x229 0x1>;
+ bits = <6 4>;
+ };
+
+ cpr_ro_sel2_perfcl: rosel2_perfcl@22a {
+ reg = <0x22a 0x1>;
+ bits = <2 4>;
+ };
+
+ cpr_ro_sel1_perfcl: rosel1_perfcl@22a {
+ reg = <0x22a 0x1>;
+ bits = <6 4>;
+ };
+
+ cpr_ro_sel0_perfcl: rosel0_perfcl@22b {
+ reg = <0x22b 0x1>;
+ bits = <2 4>;
+ };
+
+ /* CPR Init Voltage: Performance Cluster */
+ cpr_init_voltage3_perfcl: ivolt3_perfcl@22b {
+ reg = <0x22b 0x1>;
+ bits = <6 6>;
+ };
+
+ cpr_init_voltage2_perfcl: ivolt2_perfcl@22c {
+ reg = <0x22c 0x1>;
+ bits = <4 6>;
+ };
+
+ cpr_init_voltage1_perfcl: ivolt1_perfcl@22d {
+ reg = <0x22d 0x1>;
+ bits = <2 6>;
+ };
+
+ cpr_init_voltage0_perfcl: ivolt0_perfcl@22e {
+ reg = <0x22e 0x1>;
+ bits = <0 6>;
+ };
+
+ /* CPR Target Quotients: Performance Cluster */
+ cpr_quot3_perfcl: quot3_perfcl@22f {
+ reg = <0x22f 0x2>;
+ bits = <4 11>;
+ };
+
+ cpr_quot2_perfcl: quot2_perfcl@231 {
+ reg = <0x231 0x2>;
+ bits = <0 12>;
+ };
+
+ cpr_quot1_perfcl: quot1_perfcl@232 {
+ reg = <0x232 0x2>;
+ bits = <4 12>;
+ };
+
+ cpr_quot0_perfcl: quot0_perfcl@234 {
+ reg = <0x234 0x2>;
+ bits = <0 12>;
+ };
+
+ /* CPR Quotient Offsets: Performance Cluster */
+ cpr_quot_offset3_perfcl: qoff3_perfcl@237 {
+ reg = <0x237 0x1>;
+ bits = <7 6>;
+ };
+
+ cpr_quot_offset2_perfcl: qoff2_perfcl@238 {
+ reg = <0x238 0x1>;
+ bits = <6 7>;
+ };
+
+ cpr_quot_offset1_perfcl: qoff1_perfcl@239 {
+ reg = <0x239 0x1>;
+ bits = <5 3>;
+ };
+
qusb2_hstx_trim: hstx-trim@23a {
reg = <0x23a 0x1>;
bits = <0 4>;
@@ -2998,6 +3249,80 @@ frame@17928000 {
};
};
+ apc_cprh: power-controller@179c8000 {
+ compatible = "qcom,msm8998-cprh", "qcom,cprh";
+ reg = <0x0179c4000 0x4000>, <0x0179c8000 0x4000>;
+ clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
+ clock-names = "ref";
+ operating-points-v2 = <&cprh_opp_table>;
+ #power-domain-cells = <1>;
+
+ nvmem-cells = <&cpr_efuse_speedbin>,
+ <&cpr_fuse_revision>,
+ <&cpr_quot0_pwrcl>,
+ <&cpr_quot1_pwrcl>,
+ <&cpr_quot2_pwrcl>,
+ <&cpr_quot3_pwrcl>,
+ <&cpr_quot_offset1_pwrcl>,
+ <&cpr_quot_offset2_pwrcl>,
+ <&cpr_quot_offset3_pwrcl>,
+ <&cpr_init_voltage0_pwrcl>,
+ <&cpr_init_voltage1_pwrcl>,
+ <&cpr_init_voltage2_pwrcl>,
+ <&cpr_init_voltage3_pwrcl>,
+ <&cpr_ro_sel0_pwrcl>,
+ <&cpr_ro_sel1_pwrcl>,
+ <&cpr_ro_sel2_pwrcl>,
+ <&cpr_ro_sel3_pwrcl>,
+ <&cpr_quot0_perfcl>,
+ <&cpr_quot1_perfcl>,
+ <&cpr_quot2_perfcl>,
+ <&cpr_quot3_perfcl>,
+ <&cpr_quot_offset1_perfcl>,
+ <&cpr_quot_offset2_perfcl>,
+ <&cpr_quot_offset3_perfcl>,
+ <&cpr_init_voltage0_perfcl>,
+ <&cpr_init_voltage1_perfcl>,
+ <&cpr_init_voltage2_perfcl>,
+ <&cpr_init_voltage3_perfcl>,
+ <&cpr_ro_sel0_perfcl>,
+ <&cpr_ro_sel1_perfcl>,
+ <&cpr_ro_sel2_perfcl>,
+ <&cpr_ro_sel3_perfcl>;
+ nvmem-cell-names = "cpr_speed_bin",
+ "cpr_fuse_revision",
+ "cpr0_quotient1",
+ "cpr0_quotient2",
+ "cpr0_quotient3",
+ "cpr0_quotient4",
+ "cpr0_quotient_offset2",
+ "cpr0_quotient_offset3",
+ "cpr0_quotient_offset4",
+ "cpr0_init_voltage1",
+ "cpr0_init_voltage2",
+ "cpr0_init_voltage3",
+ "cpr0_init_voltage4",
+ "cpr0_ring_osc1",
+ "cpr0_ring_osc2",
+ "cpr0_ring_osc3",
+ "cpr0_ring_osc4",
+ "cpr1_quotient1",
+ "cpr1_quotient2",
+ "cpr1_quotient3",
+ "cpr1_quotient4",
+ "cpr1_quotient_offset2",
+ "cpr1_quotient_offset3",
+ "cpr1_quotient_offset4",
+ "cpr1_init_voltage1",
+ "cpr1_init_voltage2",
+ "cpr1_init_voltage3",
+ "cpr1_init_voltage4",
+ "cpr1_ring_osc1",
+ "cpr1_ring_osc2",
+ "cpr1_ring_osc3",
+ "cpr1_ring_osc4";
+ };
+
intc: interrupt-controller@17a00000 {
compatible = "arm,gic-v3";
reg = <0x17a00000 0x10000>, /* GICD */
--
2.39.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
2023-01-10 17:56 ` [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened Konrad Dybcio
@ 2023-01-10 18:27 ` Robert Marko
2023-01-10 18:29 ` Konrad Dybcio
2023-01-11 20:43 ` kernel test robot
1 sibling, 1 reply; 17+ messages in thread
From: Robert Marko @ 2023-01-10 18:27 UTC (permalink / raw)
To: Konrad Dybcio, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
linux-kernel
On 10. 01. 2023. 18:56, Konrad Dybcio wrote:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>
> This commit introduces a new driver, based on the one for cpr v1,
> to enable support for the newer Qualcomm Core Power Reduction
> hardware, known downstream as CPR3, CPR4 and CPRh, and support
> for MSM8998 and SDM630 CPU power reduction.
>
> In these new versions of the hardware, support for various new
> features was introduced, including voltage reduction for the GPU,
> security hardening and a new way of controlling CPU DVFS,
> consisting in internal communication between microcontrollers,
> specifically the CPR-Hardened and the Operating State Manager.
>
> The CPR v3, v4 and CPRh are present in a broad range of SoCs,
> from the mid-range to the high end ones including, but not limited
> to, MSM8953/8996/8998, SDM630/636/660/845.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
> [Konrad: rebase, apply review comments]
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Hi Konrad, great to see the series is alive again.
I am working on IPQ8074 which uses CPRv4 and its the last piece for
upstream CPU scaling that is missing so this is really interesting for me.
However, I think you forgot to include the <soc/qcom/cpr.h> header so
it wont currently compile.
Regards,
Robert
> ---
> drivers/soc/qcom/Kconfig | 21 +
> drivers/soc/qcom/Makefile | 4 +-
> drivers/soc/qcom/cpr-common.h | 2 +
> drivers/soc/qcom/cpr3.c | 2923 +++++++++++++++++++++++++++++++++
> 4 files changed, 2949 insertions(+), 1 deletion(-)
> create mode 100644 drivers/soc/qcom/cpr3.c
>
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index 21c4ce2315ba..303e958d9432 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -29,6 +29,7 @@ config QCOM_COMMAND_DB
> config QCOM_CPR
> tristate "QCOM Core Power Reduction (CPR) support"
> depends on ARCH_QCOM && HAS_IOMEM
> + select QCOM_CPR_COMMON
> select PM_OPP
> select REGMAP
> help
> @@ -42,6 +43,26 @@ config QCOM_CPR
> To compile this driver as a module, choose M here: the module will
> be called qcom-cpr
>
> +config QCOM_CPR_COMMON
> + tristate
> +
> +config QCOM_CPR3
> + tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
> + depends on ARCH_QCOM && HAS_IOMEM
> + select PM_OPP
> + select REGMAP
> + help
> + Say Y here to enable support for the CPR hardware found on a broad
> + variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
> + SDM845 and others.
> +
> + This driver populates OPP tables and makes adjustments to them
> + based on feedback from the CPR hardware. If you want to do CPU
> + and/or GPU frequency scaling say Y here.
> +
> + To compile this driver as a module, choose M here: the module will
> + be called qcom-cpr3
> +
> config QCOM_GENI_SE
> tristate "QCOM GENI Serial Engine Driver"
> depends on ARCH_QCOM || COMPILE_TEST
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index ba2b55dd94ff..362e9b712a68 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -3,7 +3,9 @@ CFLAGS_rpmh-rsc.o := -I$(src)
> obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
> obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
> obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
> -obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
> +obj-$(CONFIG_QCOM_CPR) += cpr.o
> +obj-$(CONFIG_QCOM_CPR_COMMON) += cpr-common.o
> +obj-$(CONFIG_QCOM_CPR3) += cpr3.o
> obj-$(CONFIG_QCOM_DCC) += dcc.o
> obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
> obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
> diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
> index 2cd15f7eac90..a90f6351d022 100644
> --- a/drivers/soc/qcom/cpr-common.h
> +++ b/drivers/soc/qcom/cpr-common.h
> @@ -65,6 +65,8 @@ struct corner {
> struct corner_data {
> unsigned int fuse_corner;
> unsigned long freq;
> + int oloop_vadj;
> + int cloop_vadj;
> };
>
> struct acc_desc {
> diff --git a/drivers/soc/qcom/cpr3.c b/drivers/soc/qcom/cpr3.c
> new file mode 100644
> index 000000000000..14a1163d37eb
> --- /dev/null
> +++ b/drivers/soc/qcom/cpr3.c
> @@ -0,0 +1,2923 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2019 Linaro Limited
> + * Copyright (c) 2021, AngeloGioacchino Del Regno
> + * <angelogioacchino.delregno@somainline.org>
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/debugfs.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_opp.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/workqueue.h>
> +#include <soc/qcom/cpr.h>
> +
> +#include "cpr-common.h"
> +
> +#define CPR3_RO_COUNT 16
> +#define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0)
> +
> +/* CPR3 registers */
> +#define CPR3_REG_CPR_VERSION 0x0
> +#define CPRH_CPR_VERSION_4P5 0x40050000
> +
> +#define CPR3_REG_CPR_CTL 0x4
> +#define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0)
> +#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK GENMASK(5, 1)
> +#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT 1
> +#define CPR3_CPR_CTL_COUNT_MODE_MASK GENMASK(7, 6)
> +#define CPR3_CPR_CTL_COUNT_MODE_SHIFT 6
> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN 0
> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX 1
> +#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED 2
> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE 3
> +#define CPR3_CPR_CTL_COUNT_REPEAT_MASK GENMASK(31, 9)
> +#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT 9
> +
> +#define CPR3_REG_CPR_STATUS 0x8
> +#define CPR3_CPR_STATUS_BUSY_MASK BIT(0)
> +
> +/*
> + * This register is not present on controllers that support HW closed-loop
> + * except CPR4 APSS controller.
> + */
> +#define CPR3_REG_CPR_TIMER_AUTO_CONT 0xC
> +
> +#define CPR3_REG_CPR_STEP_QUOT 0x14
> +#define CPR3_CPR_STEP_QUOT_MIN_MASK GENMASK(5, 0)
> +#define CPR3_CPR_STEP_QUOT_MIN_SHIFT 0
> +#define CPR3_CPR_STEP_QUOT_MAX_MASK GENMASK(11, 6)
> +#define CPR3_CPR_STEP_QUOT_MAX_SHIFT 6
> +#define CPRH_DELTA_QUOT_STEP_FACTOR 4
> +
> +#define CPR3_REG_GCNT(ro) (0xA0 + 0x4 * (ro))
> +#define CPR3_REG_SENSOR_OWNER(sensor) (0x200 + 0x4 * (sensor))
> +
> +#define CPR3_REG_CONT_CMD 0x800
> +#define CPR3_CONT_CMD_ACK 0x1
> +#define CPR3_CONT_CMD_NACK 0x0
> +
> +#define CPR3_REG_THRESH(thread) (0x808 + 0x440 * (thread))
> +#define CPR3_THRESH_CONS_DOWN_MASK GENMASK(3, 0)
> +#define CPR3_THRESH_CONS_DOWN_SHIFT 0
> +#define CPR3_THRESH_CONS_UP_MASK GENMASK(7, 4)
> +#define CPR3_THRESH_CONS_UP_SHIFT 4
> +#define CPR3_THRESH_DOWN_THRESH_MASK GENMASK(12, 8)
> +#define CPR3_THRESH_DOWN_THRESH_SHIFT 8
> +#define CPR3_THRESH_UP_THRESH_MASK GENMASK(17, 13)
> +#define CPR3_THRESH_UP_THRESH_SHIFT 13
> +
> +#define CPR3_REG_RO_MASK(thread) (0x80C + 0x440 * (thread))
> +
> +#define CPR3_REG_RESULT0(thread) (0x810 + 0x440 * (thread))
> +#define CPR3_RESULT0_BUSY_MASK BIT(0)
> +#define CPR3_RESULT0_STEP_DN_MASK BIT(1)
> +#define CPR3_RESULT0_STEP_UP_MASK BIT(2)
> +#define CPR3_RESULT0_ERROR_STEPS_MASK GENMASK(7, 3)
> +#define CPR3_RESULT0_ERROR_STEPS_SHIFT 3
> +#define CPR3_RESULT0_ERROR_MASK GENMASK(19, 8)
> +#define CPR3_RESULT0_ERROR_SHIFT 8
> +
> +#define CPR3_REG_RESULT1(thread) (0x814 + 0x440 * (thread))
> +#define CPR3_RESULT1_QUOT_MIN_MASK GENMASK(11, 0)
> +#define CPR3_RESULT1_QUOT_MIN_SHIFT 0
> +#define CPR3_RESULT1_QUOT_MAX_MASK GENMASK(23, 12)
> +#define CPR3_RESULT1_QUOT_MAX_SHIFT 12
> +#define CPR3_RESULT1_RO_MIN_MASK GENMASK(27, 24)
> +#define CPR3_RESULT1_RO_MIN_SHIFT 24
> +#define CPR3_RESULT1_RO_MAX_MASK GENMASK(31, 28)
> +#define CPR3_RESULT1_RO_MAX_SHIFT 28
> +
> +#define CPR3_REG_RESULT2(thread) (0x818 + 0x440 * (thread))
> +#define CPR3_RESULT2_STEP_QUOT_MIN_MASK GENMASK(5, 0)
> +#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT 0
> +#define CPR3_RESULT2_STEP_QUOT_MAX_MASK GENMASK(11, 6)
> +#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT 6
> +#define CPR3_RESULT2_SENSOR_MIN_MASK GENMASK(23, 16)
> +#define CPR3_RESULT2_SENSOR_MIN_SHIFT 16
> +#define CPR3_RESULT2_SENSOR_MAX_MASK GENMASK(31, 24)
> +#define CPR3_RESULT2_SENSOR_MAX_SHIFT 24
> +
> +#define CPR3_REG_IRQ_EN 0x81C
> +#define CPR3_REG_IRQ_CLEAR 0x820
> +#define CPR3_REG_IRQ_STATUS 0x824
> +#define CPR3_IRQ_UP BIT(3)
> +#define CPR3_IRQ_MID BIT(2)
> +#define CPR3_IRQ_DOWN BIT(1)
> +#define CPR3_IRQ_ALL (CPR3_IRQ_UP | CPR3_IRQ_MID | CPR3_IRQ_DOWN)
> +
> +#define CPR3_REG_TARGET_QUOT(thread, ro) (0x840 + 0x440 * (thread) + 0x4 * (ro))
> +
> +/* Registers found only on controllers that support HW closed-loop. */
> +#define CPR3_REG_PD_THROTTLE 0xE8
> +
> +#define CPR3_REG_HW_CLOSED_LOOP_DISABLED 0x3000
> +#define CPR3_REG_CPR_TIMER_MID_CONT 0x3004
> +#define CPR3_REG_CPR_TIMER_UP_DN_CONT 0x3008
> +
> +/* CPR4 controller specific registers and bit definitions */
> +#define CPR4_REG_CPR_TIMER_CLAMP 0x10
> +#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27)
> +
> +#define CPR4_REG_MISC 0x700
> +#define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2)
> +#define CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN BIT(3)
> +
> +#define CPR4_REG_SAW_ERROR_STEP_LIMIT 0x7A4
> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK GENMASK(4, 0)
> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT 0
> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK GENMASK(9, 5)
> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT 5
> +
> +#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS 0x7A8
> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK GENMASK(28, 18)
> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT 18
> +
> +#define CPR4_REG_MARGIN_ADJ_CTL 0x7F8
> +#define CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN BIT(4)
> +#define CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN BIT(7)
> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK GENMASK(16, 12)
> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT 12
> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_MASK GENMASK(31, 26)
> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_SHIFT 26
> +
> +#define CPR4_REG_CPR_MASK_THREAD(thread) (0x80C + 0x440 * (thread))
> +#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD BIT(31)
> +#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0)
> +
> +/* CPRh controller specific registers and bit definitions */
> +#define __CPRH_REG_CORNER(rbase, tbase, tid, cnum) (rbase + (tbase * tid) + (0x4 * cnum))
> +#define CPRH_REG_CORNER(d, t, c) __CPRH_REG_CORNER(d->reg_corner, d->reg_corner_tid, t, c)
> +
> +#define CPRH_CTL_OSM_ENABLED BIT(0)
> +#define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1)
> +#define CPRH_CTL_BASE_VOLTAGE_SHIFT 1
> +#define CPRH_CTL_MODE_SWITCH_DELAY_MASK GENMASK(24, 17)
> +#define CPRH_CTL_MODE_SWITCH_DELAY_SHIFT 17
> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_MASK GENMASK(28, 25)
> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT 25
> +
> +#define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0)
> +#define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0
> +#define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8)
> +#define CPRH_CORNER_FLOOR_VOLTAGE_SHIFT 8
> +#define CPRH_CORNER_QUOT_DELTA_MASK GENMASK(24, 16)
> +#define CPRH_CORNER_QUOT_DELTA_SHIFT 16
> +#define CPRH_CORNER_RO_SEL_MASK GENMASK(28, 25)
> +#define CPRH_CORNER_RO_SEL_SHIFT 25
> +#define CPRH_CORNER_CPR_CL_DISABLE BIT(29)
> +
> +#define CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE 255
> +#define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255
> +#define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511
> +
> +enum cpr_type {
> + CTRL_TYPE_CPR3,
> + CTRL_TYPE_CPR4,
> + CTRL_TYPE_CPRH,
> + CTRL_TYPE_MAX,
> +};
> +
> +/*
> + * struct cpr_thread_desc - CPR Thread-specific parameters
> + *
> + * @controller_id: Identifier of the CPR controller expected by the HW
> + * @ro_scaling_factor: Scaling factor for each ring oscillator entry
> + * @hw_tid: Identifier of the CPR thread expected by the HW
> + * @init_voltage_step: Voltage in uV for number of steps read from fuse array
> + * @init_voltage_width: Bit-width of the voltage read from the fuse array
> + * @sensor_range_start: First sensor ID used by a thread
> + * @sensor_range_end: Last sensor ID used by a thread
> + * @num_fuse_corners: Number of valid entries in fuse_corner_data
> + * @step_quot_init_min: Minimum achievable step quotient for this corner
> + * @step_quot_init_max: Maximum achievable step quotient for this corner
> + * @fuse_corner_data: Parameters for calculation of each fuse corner
> + */
> +struct cpr_thread_desc {
> + u8 controller_id;
> + u8 hw_tid;
> + const int (*ro_scaling_factor)[CPR3_RO_COUNT];
> + int ro_avail_corners;
> + int init_voltage_step;
> + int init_voltage_width;
> + u8 sensor_range_start;
> + u8 sensor_range_end;
> + u8 step_quot_init_min;
> + u8 step_quot_init_max;
> + unsigned int num_fuse_corners;
> + struct fuse_corner_data *fuse_corner_data;
> +};
> +
> +/*
> + * struct cpr_desc - Driver instance-wide CPR parameters
> + *
> + * @cpr_type: Type (base version) of the CPR controller
> + * @num_threads: Max. number of threads supported by this controller
> + * @timer_delay_us: Loop delay time in uS
> + * @timer_updn_delay_us: Voltage after-up/before-down delay time in uS
> + * @timer_cons_up: Wait between consecutive up requests in uS
> + * @timer_cons_down: Wait between consecutive down requests in uS
> + * @up_threshold: Generic corner up threshold
> + * @down_threshold: Generic corner down threshold
> + * @idle_clocks: CPR Sensor: idle timer in cpr clocks unit
> + * @count_mode: CPR Sensor: counting mode
> + * @count_repeat: CPR Sensor: number of times to repeat reading
> + * @gcnt_us: CPR measurement interval in uS
> + * @vreg_step_fixed: Regulator voltage per step (if vreg unusable)
> + * @vreg_step_up_limit: Num. of steps up at once before re-measuring sensors
> + * @vreg_step_down_limit: Num. of steps dn at once before re-measuring sensors
> + * @vdd_settle_time_us: Settling timer to account for one VDD supply step
> + * @corner_settle_time_us: Settle time for corner switch request
> + * @mem_acc_threshold: Memory Accelerator (MEM-ACC) voltage threshold
> + * @apm_threshold: Array Power Mux (APM) voltage threshold
> + * @apm_crossover: Array Power Mux (APM) corner crossover voltage
> + * @apm_hysteresis: Hysteresis for APM V-threshold related calculations
> + * @cpr_base_voltage: Safety: Absolute minimum voltage (uV) on this CPR
> + * @cpr_max_voltage: Safety: Absolute maximum voltage (uV) on this CPR
> + * @pd_throttle_val: CPR Power Domain throttle during voltage switch
> + * @threads: Array containing "CPR Thread" specific parameters
> + * @reduce_to_fuse_uV: Reduce corner max volts (if higher) to fuse ceiling
> + * @reduce_to_corner_uV: Reduce corner max volts (if higher) to corner ceil.
> + * @hw_closed_loop_en: Enable CPR HW Closed-Loop voltage auto-adjustment
> + */
> +struct cpr_desc {
> + enum cpr_type cpr_type;
> + unsigned int num_threads;
> + unsigned int timer_delay_us;
> + u8 timer_updn_delay_us;
> + u8 timer_cons_up;
> + u8 timer_cons_down;
> + u8 up_threshold;
> + u8 down_threshold;
> + u8 idle_clocks;
> + u8 count_mode;
> + u8 count_repeat;
> + u8 gcnt_us;
> + u16 vreg_step_fixed;
> + u8 vreg_step_up_limit;
> + u8 vreg_step_down_limit;
> + u8 vdd_settle_time_us;
> + u8 corner_settle_time_us;
> + int mem_acc_threshold;
> + int apm_threshold;
> + int apm_crossover;
> + int apm_hysteresis;
> + u32 cpr_base_voltage;
> + u32 cpr_max_voltage;
> + u32 pd_throttle_val;
> +
> + const struct cpr_thread_desc **threads;
> + bool reduce_to_fuse_uV;
> + bool reduce_to_corner_uV;
> + bool hw_closed_loop_en;
> +};
> +
> +struct cpr_drv;
> +struct cpr_thread {
> + int num_corners;
> + int id;
> + bool enabled;
> + void __iomem *base;
> + struct clk *cpu_clk;
> + struct corner *corner;
> + struct corner *corners;
> + struct fuse_corner *fuse_corners;
> + struct cpr_drv *drv;
> + struct cpr_ext_data ext_data;
> + struct generic_pm_domain pd;
> + struct device *attached_cpu_dev;
> + struct work_struct restart_work;
> + bool restarting;
> +
> + const struct cpr_fuse *cpr_fuses;
> + const struct cpr_thread_desc *desc;
> +};
> +
> +struct cpr_drv {
> + int irq;
> + unsigned int ref_clk_khz;
> + struct device *dev;
> + struct mutex lock;
> + struct regulator *vreg;
> + struct regmap *tcsr;
> + u32 gcnt;
> + u32 speed_bin;
> + u32 fusing_rev;
> + u32 last_uV;
> + u32 cpr_hw_rev;
> + u32 reg_corner;
> + u32 reg_corner_tid;
> + u32 reg_ctl;
> + u32 reg_status;
> + int fuse_level_set;
> + int extra_corners;
> + unsigned int vreg_step;
> + bool enabled;
> +
> + struct cpr_thread *threads;
> + struct genpd_onecell_data cell_data;
> +
> + const struct cpr_desc *desc;
> + const struct acc_desc *acc_desc;
> + struct dentry *debugfs;
> +};
> +
> +/**
> + * cpr_get_corner_post_vadj() - Get corner post-voltage adjustment values
> + * @opp: Pointer to the corresponding OPP struct
> + * @tid: CPR thread ID
> + * @open_loop: Pointer to the closed-loop adjustment value
> + * @closed_loop: Pointer to the open-loop adjustment value
> + */
> +void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
> + s32 *open_loop, s32 *closed_loop)
> +{
> + struct device_node *np;
> +
> + /*
> + * There is no of_property_read_s32_index, so we just store the
> + * result into a s32 variable. After all, the OF API is doing
> + * the exact same for of_property_read_s32...
> + */
> + np = dev_pm_opp_get_of_node(opp);
> + if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid, open_loop))
> + *open_loop = 0;
> +
> + if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid, closed_loop))
> + *closed_loop = 0;
> +
> + of_node_put(np);
> +}
> +
> +/**
> + * cpr_get_ro_factor() - Get fuse corner ring oscillator factor
> + * @tdesc: CPR Thread-specific parameters
> + * @fnum: Fuse corner
> + * @ro_idx: Ring Oscillator fuse number
> + *
> + * Not all threads have different scaling factors for each
> + * Fuse Corner: if the RO factors are the same for all corners,
> + * then only one is specified, instead of uselessly repeating
> + * the same array for FC-times.
> + * This function checks for the same and gives back the right
> + * factor for the requested ring oscillator.
> + *
> + * Return: Ring oscillator factor
> + */
> +static int cpr_get_ro_factor(const struct cpr_thread_desc *tdesc,
> + int fnum, int ro_idx)
> +{
> + int ro_fnum;
> +
> + if (tdesc->ro_avail_corners == tdesc->num_fuse_corners)
> + ro_fnum = fnum;
> + else
> + ro_fnum = 0;
> +
> + return tdesc->ro_scaling_factor[ro_fnum][ro_idx];
> +}
> +
> +static void cpr_write(struct cpr_thread *thread, u32 offset, u32 value)
> +{
> + writel(value, thread->base + offset);
> +}
> +
> +static u32 cpr_read(struct cpr_thread *thread, u32 offset)
> +{
> + return readl(thread->base + offset);
> +}
> +
> +static void
> +cpr_masked_write(struct cpr_thread *thread, u32 offset, u32 mask, u32 value)
> +{
> + u32 val;
> +
> + val = readl(thread->base + offset);
> + val &= ~mask;
> + val |= value & mask;
> + writel(val, thread->base + offset);
> +}
> +
> +static void cpr_irq_clr(struct cpr_thread *thread)
> +{
> + cpr_write(thread, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_ALL);
> +}
> +
> +static void cpr_irq_clr_nack(struct cpr_thread *thread)
> +{
> + cpr_irq_clr(thread);
> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
> +}
> +
> +static void cpr_irq_clr_ack(struct cpr_thread *thread)
> +{
> + cpr_irq_clr(thread);
> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_ACK);
> +}
> +
> +static void cpr_irq_set(struct cpr_thread *thread, u32 int_bits)
> +{
> + /* On CPR-hardened, interrupts are managed by and on firmware */
> + if (thread->drv->desc->cpr_type == CTRL_TYPE_CPRH)
> + return;
> +
> + cpr_write(thread, CPR3_REG_IRQ_EN, int_bits);
> +}
> +
> +/**
> + * cpr_ctl_enable() - Enable CPR thread
> + * @thread: Structure holding CPR thread-specific parameters
> + */
> +static void cpr_ctl_enable(struct cpr_thread *thread)
> +{
> + if (thread->drv->enabled && !thread->restarting) {
> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
> + CPR3_CPR_CTL_LOOP_EN_MASK,
> + CPR3_CPR_CTL_LOOP_EN_MASK);
> + }
> +}
> +
> +/**
> + * cpr_ctl_disable() - Disable CPR thread
> + * @thread: Structure holding CPR thread-specific parameters
> + */
> +static void cpr_ctl_disable(struct cpr_thread *thread)
> +{
> + const struct cpr_desc *desc = thread->drv->desc;
> +
> + if (desc->cpr_type != CTRL_TYPE_CPRH) {
> + cpr_irq_set(thread, 0);
> + cpr_irq_clr(thread);
> + }
> +
> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
> + CPR3_CPR_CTL_LOOP_EN_MASK, 0);
> +}
> +
> +/**
> + * cpr_ctl_is_enabled() - Check if thread is enabled
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Return: true if the CPR is enabled, false if it is disabled.
> + */
> +static bool cpr_ctl_is_enabled(struct cpr_thread *thread)
> +{
> + u32 reg_val;
> +
> + reg_val = cpr_read(thread, CPR3_REG_CPR_CTL);
> + return reg_val & CPR3_CPR_CTL_LOOP_EN_MASK;
> +}
> +
> +/**
> + * cpr_check_any_thread_busy() - Check if HW is done processing
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Return: true if the CPR is busy, false if it is ready.
> + */
> +static bool cpr_check_any_thread_busy(struct cpr_thread *thread)
> +{
> + int i;
> +
> + for (i = 0; i < thread->drv->desc->num_threads; i++)
> + if (cpr_read(thread, CPR3_REG_RESULT0(i)) &
> + CPR3_RESULT0_BUSY_MASK)
> + return true;
> +
> + return false;
> +}
> +
> +static void cpr_restart_worker(struct work_struct *work)
> +{
> + struct cpr_thread *thread = container_of(work, struct cpr_thread,
> + restart_work);
> + struct cpr_drv *drv = thread->drv;
> + int i;
> +
> + mutex_lock(&drv->lock);
> +
> + thread->restarting = true;
> + cpr_ctl_disable(thread);
> + disable_irq(drv->irq);
> +
> + mutex_unlock(&drv->lock);
> +
> + for (i = 0; i < 20; i++) {
> + u32 cpr_status = cpr_read(thread, CPR3_REG_CPR_STATUS);
> + u32 ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
> +
> + if ((cpr_status & CPR3_CPR_STATUS_BUSY_MASK) &&
> + !(ctl & CPR3_CPR_CTL_LOOP_EN_MASK))
> + break;
> +
> + udelay(10);
> + }
> +
> + cpr_irq_clr(thread);
> +
> + for (i = 0; i < 20; i++) {
> + u32 status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
> +
> + if (!(status & CPR3_IRQ_ALL))
> + break;
> + udelay(10);
> + }
> +
> + mutex_lock(&drv->lock);
> +
> + thread->restarting = false;
> + enable_irq(drv->irq);
> + cpr_ctl_enable(thread);
> +
> + mutex_unlock(&drv->lock);
> +}
> +
> +/**
> + * cpr_corner_restore() - Restore saved corner level
> + * @thread: Structure holding CPR thread-specific parameters
> + * @corner: Structure holding the saved corner level
> + */
> +static void cpr_corner_restore(struct cpr_thread *thread,
> + struct corner *corner)
> +{
> + struct cpr_drv *drv = thread->drv;
> + struct fuse_corner *fuse = corner->fuse_corner;
> + const struct cpr_thread_desc *tdesc = thread->desc;
> + u32 ro_sel = fuse->ring_osc_idx;
> +
> + cpr_write(thread, CPR3_REG_GCNT(ro_sel), drv->gcnt);
> +
> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid),
> + CPR3_RO_MASK & ~BIT(ro_sel));
> +
> + cpr_write(thread, CPR3_REG_TARGET_QUOT(tdesc->hw_tid, ro_sel),
> + fuse->quot - corner->quot_adjust);
> +
> + if (drv->desc->cpr_type == CTRL_TYPE_CPR4)
> + cpr_masked_write(thread,
> + CPR4_REG_CPR_MASK_THREAD(tdesc->hw_tid),
> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK, 0);
> +
> + thread->corner = corner;
> + corner->last_uV = corner->uV;
> +}
> +
> +/**
> + * cpr_set_acc() - Set fuse level to the mem-acc
> + * @drv: Main driver structure
> + * @f: Fuse level
> + */
> +static void cpr_set_acc(struct cpr_drv *drv, int f)
> +{
> + const struct acc_desc *desc = drv->acc_desc;
> + struct reg_sequence *s = desc->settings;
> + int n = desc->num_regs_per_fuse;
> +
> + if (!s || f == drv->fuse_level_set)
> + return;
> +
> + regmap_multi_reg_write(drv->tcsr, s + (n * f), n);
> + drv->fuse_level_set = f;
> +}
> +
> +/**
> + * cpr_pre_voltage() - Actions to execute before setting voltage
> + * @thread: Structure holding CPR thread-specific parameters
> + * @dir: Enumeration for voltage change direction
> + * @fuse_level: Fuse corner for mem-acc, if supported.
> + *
> + * Return: Zero for success or negative number on errors.
> + */
> +static int cpr_pre_voltage(struct cpr_thread *thread,
> + enum voltage_change_dir dir,
> + int fuse_level)
> +{
> + struct cpr_drv *drv = thread->drv;
> +
> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3 &&
> + drv->desc->pd_throttle_val)
> + cpr_write(thread, CPR3_REG_PD_THROTTLE,
> + drv->desc->pd_throttle_val);
> +
> + if (drv->tcsr && dir == DOWN)
> + cpr_set_acc(drv, fuse_level);
> +
> + return 0;
> +}
> +
> +/**
> + * cpr_post_voltage() - Actions to execute after setting voltage
> + * @thread: Structure holding CPR thread-specific parameters
> + * @dir: Enumeration for voltage change direction
> + * @fuse_level: Fuse corner for mem-acc, if supported.
> + *
> + * Return: Zero for success or negative number on errors.
> + */
> +static int cpr_post_voltage(struct cpr_thread *thread,
> + enum voltage_change_dir dir,
> + int fuse_level)
> +{
> + struct cpr_drv *drv = thread->drv;
> +
> + if (drv->tcsr && dir == UP)
> + cpr_set_acc(drv, fuse_level);
> +
> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3)
> + cpr_write(thread, CPR3_REG_PD_THROTTLE, 0);
> +
> + return 0;
> +}
> +
> +/**
> + * cpr_commit_state() - Set the newly requested voltage
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
> + */
> +static int cpr_commit_state(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + int min_uV = 0, max_uV = 0, new_uV = 0, fuse_level = 0;
> + enum voltage_change_dir dir;
> + u32 next_irqmask = 0;
> + int ret, i;
> +
> + /* On CPRhardened, control states are managed in firmware */
> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
> + return 0;
> +
> + for (i = 0; i < drv->desc->num_threads; i++) {
> + struct cpr_thread *thread = &drv->threads[i];
> +
> + if (!thread->corner)
> + continue;
> +
> + fuse_level = max(fuse_level,
> + (int) (thread->corner->fuse_corner -
> + &thread->fuse_corners[0]));
> +
> + max_uV = max(max_uV, thread->corner->max_uV);
> + min_uV = max(min_uV, thread->corner->min_uV);
> + new_uV = max(new_uV, thread->corner->last_uV);
> + }
> + dev_vdbg(drv->dev, "%s: new uV: %d, last uV: %d\n",
> + __func__, new_uV, drv->last_uV);
> +
> + /*
> + * Safety measure: if the voltage is out of the globally allowed
> + * range, then go out and warn the user.
> + * This should *never* happen.
> + */
> + if (new_uV > drv->desc->cpr_max_voltage ||
> + new_uV < drv->desc->cpr_base_voltage) {
> + dev_warn(drv->dev, "Voltage (%u uV) out of range.", new_uV);
> + return -EINVAL;
> + }
> +
> + if (new_uV == drv->last_uV || fuse_level == drv->fuse_level_set)
> + goto out;
> +
> + if (fuse_level > drv->fuse_level_set)
> + dir = UP;
> + else
> + dir = DOWN;
> +
> + ret = cpr_pre_voltage(thread, fuse_level, dir);
> + if (ret)
> + return ret;
> +
> + dev_vdbg(drv->dev, "setting voltage: %d\n", new_uV);
> +
> + ret = regulator_set_voltage(drv->vreg, new_uV, new_uV);
> + if (ret) {
> + dev_err_ratelimited(drv->dev, "failed to set voltage %d: %d\n", new_uV, ret);
> + return ret;
> + }
> +
> + ret = cpr_post_voltage(thread, fuse_level, dir);
> + if (ret)
> + return ret;
> +
> + drv->last_uV = new_uV;
> +out:
> + if (new_uV > min_uV)
> + next_irqmask |= CPR3_IRQ_DOWN;
> + if (new_uV < max_uV)
> + next_irqmask |= CPR3_IRQ_UP;
> +
> + cpr_irq_set(thread, next_irqmask);
> +
> + return 0;
> +}
> +
> +static unsigned int cpr_get_cur_perf_state(struct cpr_thread *thread)
> +{
> + return thread->corner ? thread->corner - thread->corners + 1 : 0;
> +}
> +
> +/**
> + * cpr_scale() - Calculate new voltage for the received direction
> + * @thread: Structure holding CPR thread-specific parameters
> + * @dir: Enumeration for voltage change direction
> + *
> + * The CPR scales one by one: this function calculates the new
> + * voltage to set when a voltage-UP or voltage-DOWN request comes
> + * and stores it into the per-thread structure that gets passed.
> + */
> +static void cpr_scale(struct cpr_thread *thread, enum voltage_change_dir dir)
> +{
> + struct cpr_drv *drv = thread->drv;
> + const struct cpr_thread_desc *tdesc = thread->desc;
> + u32 val, error_steps;
> + int last_uV, new_uV;
> + struct corner *corner;
> +
> + if (dir != UP && dir != DOWN)
> + return;
> +
> + corner = thread->corner;
> + val = cpr_read(thread, CPR3_REG_RESULT0(tdesc->hw_tid));
> + error_steps = val >> CPR3_RESULT0_ERROR_STEPS_SHIFT;
> + error_steps &= CPR3_RESULT0_ERROR_STEPS_MASK;
> +
> + last_uV = corner->last_uV;
> +
> + if (dir == UP) {
> + if (!(val & CPR3_RESULT0_STEP_UP_MASK))
> + return;
> +
> + /* Calculate new voltage */
> + new_uV = last_uV + drv->vreg_step;
> + new_uV = min(new_uV, corner->max_uV);
> +
> + dev_vdbg(drv->dev, "[T%u] UP - new_uV=%d last_uV=%d p-state=%u st=%u\n",
> + thread->id, new_uV, last_uV,
> + cpr_get_cur_perf_state(thread), error_steps);
> + } else {
> + if (!(val & CPR3_RESULT0_STEP_DN_MASK))
> + return;
> +
> + /* Calculate new voltage */
> + new_uV = last_uV - drv->vreg_step;
> + new_uV = max(new_uV, corner->min_uV);
> + dev_vdbg(drv->dev, "[T%u] DOWN - new_uV=%d last_uV=%d p-state=%u st=%u\n",
> + thread->id, new_uV, last_uV,
> + cpr_get_cur_perf_state(thread), error_steps);
> + }
> + corner->last_uV = new_uV;
> +}
> +
> +/**
> + * cpr_irq_handler() - Handle CPR3/CPR4 status interrupts
> + * @irq: Number of the interrupt
> + * @dev: Pointer to the cpr_thread structure
> + *
> + * Handle the interrupts coming from non-hardened CPR HW as to get
> + * an ok to scale voltages immediately, or to pass error status to
> + * the hardware (either success/ACK or failure/NACK).
> + *
> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
> + */
> +static irqreturn_t cpr_irq_handler(int irq, void *dev)
> +{
> + struct cpr_thread *thread = dev;
> + struct cpr_drv *drv = thread->drv;
> + irqreturn_t ret = IRQ_HANDLED;
> + int i, rc;
> + enum voltage_change_dir dir = NO_CHANGE;
> + u32 val;
> +
> + mutex_lock(&drv->lock);
> +
> + val = cpr_read(thread, CPR3_REG_IRQ_STATUS);
> +
> + dev_vdbg(drv->dev, "IRQ_STATUS = %#02x\n", val);
> +
> + if (!cpr_ctl_is_enabled(thread)) {
> + dev_vdbg(drv->dev, "CPR is disabled\n");
> + ret = IRQ_NONE;
> + } else if (cpr_check_any_thread_busy(thread)) {
> + cpr_irq_clr_nack(thread);
> + dev_dbg(drv->dev, "CPR measurement is not ready\n");
> + } else {
> + /*
> + * Following sequence of handling is as per each IRQ's
> + * priority
> + */
> + if (val & CPR3_IRQ_UP)
> + dir = UP;
> + else if (val & CPR3_IRQ_DOWN)
> + dir = DOWN;
> +
> + if (dir != NO_CHANGE) {
> + for (i = 0; i < drv->desc->num_threads; i++) {
> + thread = &drv->threads[i];
> + cpr_scale(thread, dir);
> + }
> +
> + rc = cpr_commit_state(thread);
> + if (rc)
> + cpr_irq_clr_nack(thread);
> + else
> + cpr_irq_clr_ack(thread);
> + } else if (val & CPR3_IRQ_MID) {
> + dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n");
> + } else {
> + dev_warn(drv->dev, "IRQ occurred for unknown flag (%#08x)\n", val);
> + schedule_work(&thread->restart_work);
> + }
> + }
> +
> + mutex_unlock(&drv->lock);
> +
> + return ret;
> +}
> +
> +static int cpr_switch(struct cpr_drv *drv)
> +{
> + int i, ret;
> + bool enabled = false;
> +
> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
> + return 0;
> +
> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
> + enabled = drv->threads[i].enabled;
> +
> + dev_vdbg(drv->dev, "%s: enabled = %d\n", __func__, enabled);
> +
> + if (enabled == drv->enabled)
> + return 0;
> +
> + if (enabled) {
> + ret = regulator_enable(drv->vreg);
> + if (ret)
> + return ret;
> +
> + drv->enabled = enabled;
> +
> + for (i = 0; i < drv->desc->num_threads; i++)
> + if (drv->threads[i].corner)
> + break;
> +
> + if (i < drv->desc->num_threads) {
> + cpr_irq_clr(&drv->threads[i]);
> +
> + cpr_commit_state(&drv->threads[i]);
> + cpr_ctl_enable(&drv->threads[i]);
> + }
> + } else {
> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
> + cpr_ctl_disable(&drv->threads[i]);
> +
> + drv->enabled = enabled;
> +
> + ret = regulator_disable(drv->vreg);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * cpr_enable() - Enables a CPR thread
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Return: Zero for success or negative number on errors.
> + */
> +static int cpr_enable(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + int ret;
> +
> + dev_dbg(drv->dev, "Enabling thread %d\n", thread->id);
> +
> + mutex_lock(&drv->lock);
> +
> + thread->enabled = true;
> + ret = cpr_switch(thread->drv);
> +
> + mutex_unlock(&drv->lock);
> +
> + return ret;
> +}
> +
> +/**
> + * cpr_disable() - Disables a CPR thread
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Return: Zero for success or negative number on errors.
> + */
> +static int cpr_disable(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + int ret;
> +
> + dev_dbg(drv->dev, "Disabling thread %d\n", thread->id);
> +
> + mutex_lock(&drv->lock);
> +
> + thread->enabled = false;
> + ret = cpr_switch(thread->drv);
> +
> + mutex_unlock(&drv->lock);
> +
> + return ret;
> +}
> +
> +/**
> + * cpr_configure() - Configure main HW parameters
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * This function configures the main CPR hardware parameters, such as
> + * internal timers (and delays), sensor ownerships, activates and/or
> + * deactivates cpr-threads and others, as one sequence for all of the
> + * versions supported in this driver. By design, the function may
> + * return a success earlier if the sequence for "a previous version"
> + * has ended.
> + *
> + * Context: The CPR must be clocked before calling this function!
> + *
> + * Return: Zero for success or negative number on errors.
> + */
> +static int cpr_configure(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + const struct cpr_desc *desc = drv->desc;
> + const struct cpr_thread_desc *tdesc = thread->desc;
> + u32 val;
> + int i;
> +
> + /* Disable interrupt and CPR */
> + cpr_irq_set(thread, 0);
> + cpr_write(thread, CPR3_REG_CPR_CTL, 0);
> +
> + /* Init and save gcnt */
> + drv->gcnt = drv->ref_clk_khz * desc->gcnt_us;
> + do_div(drv->gcnt, 1000);
> +
> + /* Program the delay count for the timer */
> + val = drv->ref_clk_khz * desc->timer_delay_us;
> + do_div(val, 1000);
> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
> + cpr_write(thread, CPR3_REG_CPR_TIMER_MID_CONT, val);
> +
> + val = drv->ref_clk_khz * desc->timer_updn_delay_us;
> + do_div(val, 1000);
> + cpr_write(thread, CPR3_REG_CPR_TIMER_UP_DN_CONT, val);
> + } else {
> + cpr_write(thread, CPR3_REG_CPR_TIMER_AUTO_CONT, val);
> + }
> + dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val,
> + desc->timer_delay_us);
> +
> + /* Program the control register */
> + val = desc->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT;
> + val |= desc->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT;
> + val |= desc->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT;
> + cpr_write(thread, CPR3_REG_CPR_CTL, val);
> +
> + /* Configure CPR default step quotients */
> + val = tdesc->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT;
> + val |= tdesc->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT;
> +
> + cpr_write(thread, CPR3_REG_CPR_STEP_QUOT, val);
> +
> + /*
> + * Configure the CPR sensor ownership always on thread 0
> + * TODO: SDM845 has different ownership for sensors!!
> + */
> + for (i = tdesc->sensor_range_start; i < tdesc->sensor_range_end; i++)
> + cpr_write(thread, CPR3_REG_SENSOR_OWNER(i), 0);
> +
> + /* Program Consecutive Up & Down */
> + val = desc->timer_cons_up << CPR3_THRESH_CONS_UP_SHIFT;
> + val |= desc->timer_cons_down << CPR3_THRESH_CONS_DOWN_SHIFT;
> + val |= desc->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT;
> + val |= desc->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT;
> + cpr_write(thread, CPR3_REG_THRESH(tdesc->hw_tid), val);
> +
> + /* Mask all ring oscillators for all threads initially */
> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), CPR3_RO_MASK);
> +
> + /* HW Closed-loop control */
> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
> + cpr_write(thread, CPR3_REG_HW_CLOSED_LOOP_DISABLED,
> + !desc->hw_closed_loop_en);
> + } else {
> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN,
> + desc->hw_closed_loop_en ?
> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN : 0);
> + }
> +
> + /* Additional configuration for CPR4 and beyond */
> + if (desc->cpr_type < CTRL_TYPE_CPR4)
> + return 0;
> +
> + /* Disable threads initially only on non-hardened CPR4 */
> + if (desc->cpr_type == CTRL_TYPE_CPR4)
> + cpr_masked_write(thread, CPR4_REG_CPR_MASK_THREAD(1),
> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
> +
> + if (tdesc->hw_tid > 0)
> + cpr_masked_write(thread, CPR4_REG_MISC,
> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN,
> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN);
> +
> + val = drv->vreg_step;
> + do_div(val, 1000);
> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
> + CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK,
> + val << CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT);
> +
> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
> + CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
> + desc->vreg_step_down_limit <<
> + CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT);
> +
> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
> + CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
> + desc->vreg_step_up_limit <<
> + CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT);
> +
> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN,
> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN);
> +
> + if (tdesc->hw_tid > 0)
> + cpr_masked_write(thread, CPR4_REG_CPR_TIMER_CLAMP,
> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
> +
> + /* Settling timer to account for one VDD supply step */
> + if (desc->vdd_settle_time_us > 0) {
> + u32 m = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK;
> + u32 s = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT;
> +
> + cpr_masked_write(thread, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
> + m, desc->vdd_settle_time_us << s);
> + }
> +
> + /* Additional configuration for CPR-hardened */
> + if (desc->cpr_type < CTRL_TYPE_CPRH)
> + return 0;
> +
> + /* Settling timer to account for one corner-switch request */
> + if (desc->corner_settle_time_us > 0)
> + cpr_masked_write(thread, drv->reg_ctl,
> + CPRH_CTL_MODE_SWITCH_DELAY_MASK,
> + desc->corner_settle_time_us <<
> + CPRH_CTL_MODE_SWITCH_DELAY_SHIFT);
> +
> + /* Base voltage and multiplier values for CPRh internal calculations */
> + cpr_masked_write(thread, drv->reg_ctl,
> + CPRH_CTL_BASE_VOLTAGE_MASK,
> + (DIV_ROUND_UP(desc->cpr_base_voltage,
> + drv->vreg_step) <<
> + CPRH_CTL_BASE_VOLTAGE_SHIFT));
> +
> + cpr_masked_write(thread, drv->reg_ctl,
> + CPRH_CTL_VOLTAGE_MULTIPLIER_MASK,
> + DIV_ROUND_UP(drv->vreg_step, 1000) <<
> + CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT);
> +
> + return 0;
> +}
> +
> +static int cprh_dummy_set_performance_state(struct generic_pm_domain *domain,
> + unsigned int state)
> +{
> + return 0;
> +}
> +
> +static int cpr_set_performance_state(struct generic_pm_domain *domain,
> + unsigned int state)
> +{
> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
> + struct cpr_drv *drv = thread->drv;
> + struct corner *corner, *end;
> + int ret = 0;
> +
> + mutex_lock(&drv->lock);
> +
> + dev_dbg(drv->dev, "setting perf state: %u (prev state: %u thread: %u)\n",
> + state, cpr_get_cur_perf_state(thread), thread->id);
> +
> + /*
> + * Determine new corner we're going to.
> + * Remove one since lowest performance state is 1.
> + */
> + corner = thread->corners + state - 1;
> + end = &thread->corners[thread->num_corners - 1];
> + if (corner > end || corner < thread->corners) {
> + ret = -EINVAL;
> + goto unlock;
> + }
> +
> + cpr_ctl_disable(thread);
> +
> + cpr_irq_clr(thread);
> + if (thread->corner != corner)
> + cpr_corner_restore(thread, corner);
> +
> + ret = cpr_commit_state(thread);
> + if (ret)
> + goto unlock;
> +
> + cpr_ctl_enable(thread);
> +unlock:
> + mutex_unlock(&drv->lock);
> +
> + dev_dbg(drv->dev, "set perf state %u on thread %u\n", state, thread->id);
> +
> + return ret;
> +}
> +
> +/**
> + * cpr3_adjust_quot - Adjust the closed-loop quotients
> + * @ring_osc_factor: Ring oscillator adjustment factor
> + * @volt_closed_loop: Closed-loop voltage adjustment factor
> + *
> + * Calculates the quotient adjustment factor based on closed-loop
> + * quotients and ring oscillator factor.
> + *
> + * Return: Adjusted quotient
> + */
> +static int cpr3_adjust_quot(int ring_osc_factor, int volt_closed_loop)
> +{
> + s64 temp;
> +
> + if (ring_osc_factor == 0 || volt_closed_loop == 0)
> + return 0;
> +
> + temp = (s64)(ring_osc_factor * volt_closed_loop);
> + return (int)div_s64(temp, 1000000);
> +}
> +
> +/**
> + * cpr_fuse_corner_init() - Calculate fuse corner table
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * This function populates the fuse corners table by reading the
> + * values from the fuses, eventually adjusting them with a fixed
> + * per-corner offset and doing basic checks about them being
> + * supported by the regulator that is assigned to this CPR - if
> + * it is available (on CPR-Hardened, there is no usable vreg, as
> + * that is protected by the hypervisor).
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr_fuse_corner_init(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + const struct cpr_thread_desc *desc = thread->desc;
> + const struct cpr_fuse *cpr_fuse = thread->cpr_fuses;
> + struct fuse_corner_data *fdata;
> + struct fuse_corner *fuse, *prev_fuse, *end;
> + int i, ret;
> +
> + /* Populate fuse_corner members */
> + fuse = thread->fuse_corners;
> + prev_fuse = &fuse[0];
> + end = &fuse[desc->num_fuse_corners - 1];
> + fdata = desc->fuse_corner_data;
> +
> + for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
> + int factor = cpr_get_ro_factor(desc, i, fuse->ring_osc_idx);
> +
> + ret = cpr_populate_fuse_common(drv->dev, fdata, cpr_fuse,
> + fuse, drv->vreg_step,
> + desc->init_voltage_width,
> + desc->init_voltage_step);
> + if (ret)
> + return ret;
> +
> + /*
> + * Adjust the fuse quot with per-fuse-corner closed-loop
> + * voltage adjustment parameters.
> + */
> + fuse->quot += cpr3_adjust_quot(factor, fdata->volt_cloop_adjust);
> +
> + /* CPRh: no regulator access... */
> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
> + goto skip_pvs_restrict;
> +
> + /* Re-check if corner voltage range is supported by regulator */
> + ret = cpr_check_vreg_constraints(drv->dev, drv->vreg, fuse);
> + if (ret)
> + return ret;
> +
> +skip_pvs_restrict:
> + if (fuse->uV < prev_fuse->uV)
> + fuse->uV = prev_fuse->uV;
> + prev_fuse = fuse;
> + dev_dbg(drv->dev, "fuse corner %d: [%d %d %d] RO%hhu quot %d\n",
> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
> + fuse->ring_osc_idx, fuse->quot);
> +
> + /* Check if constraints are valid */
> + if (fuse->uV < fuse->min_uV || fuse->uV > fuse->max_uV) {
> + dev_err(drv->dev, "fuse corner %d: Bad voltage range.\n", i);
> + return -EINVAL;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void cpr3_restrict_corner(struct corner *corner, int threshold,
> + int hysteresis, int step)
> +{
> + if (threshold > corner->min_uV && threshold <= corner->max_uV) {
> + if (corner->uV >= threshold) {
> + corner->min_uV = max(corner->min_uV,
> + threshold - hysteresis);
> + if (corner->min_uV > corner->uV)
> + corner->uV = corner->min_uV;
> + } else {
> + corner->max_uV = threshold;
> + corner->max_uV -= step;
> + }
> + }
> +}
> +
> +/*
> + * cprh_corner_adjust_opps() - Set voltage on each CPU OPP table entry
> + *
> + * On CPR-Hardened, the voltage level is controlled internally through
> + * the OSM hardware: in order to initialize the latter, we have to
> + * communicate the voltage to its driver, so that it will be able to
> + * write the right parameters (as they have to be set both on the CPRh
> + * and on the OSM) on it.
> + * This function is called only for CPRh.
> + *
> + * Return: Zero for success, negative number for error.
> + */
> +static int cprh_corner_adjust_opps(struct cpr_thread *thread)
> +{
> + struct corner *corner = thread->corners;
> + struct cpr_drv *drv = thread->drv;
> + int i, ret;
> +
> + for (i = 0; i < thread->num_corners; i++) {
> + ret = dev_pm_opp_adjust_voltage(thread->attached_cpu_dev,
> + corner[i].freq,
> + corner[i].uV,
> + corner[i].min_uV,
> + corner[i].max_uV);
> + if (ret)
> + break;
> +
> + dev_dbg(drv->dev, "OPP voltage adjusted for %lu kHz, %d uV\n",
> + corner[i].freq, corner[i].uV);
> + }
> +
> + /* If we couldn't adjust voltage for all corners, something went wrong */
> + if (i < thread->num_corners)
> + return -EINVAL;
> +
> + return ret;
> +}
> +
> +/**
> + * cpr3_corner_init() - Calculate and set-up corners for the CPR HW
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * This function calculates all the corner parameters by comparing
> + * and interpolating the values read from the various set-points
> + * read from the fuses (also called "fuse corners") to generate and
> + * program to the CPR a lookup table that describes each voltage
> + * step, mapped to a performance level (or corner number).
> + *
> + * It also programs other essential parameters on the CPR and - if
> + * we are dealing with CPR-Hardened, it will also enable the internal
> + * interface between the Operating State Manager (OSM) and the CPRh
> + * in order to achieve CPU DVFS.
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr3_corner_init(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + const struct cpr_desc *desc = drv->desc;
> + const struct cpr_thread_desc *tdesc = thread->desc;
> + const struct cpr_fuse *fuses = thread->cpr_fuses;
> + int i, ret, total_corners, extra_corners, level, scaling = 0;
> + unsigned int fnum, fc;
> + const char *quot_offset;
> + const struct fuse_corner_data *fdata;
> + struct fuse_corner *fuse, *prev_fuse;
> + struct corner *corner, *prev_corner, *end;
> + struct corner_data *cdata;
> + struct dev_pm_opp *opp;
> + unsigned long freq;
> + u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
> +
> + corner = thread->corners;
> + prev_corner = &thread->corners[0];
> + end = &corner[thread->num_corners - 1];
> +
> + cdata = devm_kcalloc(drv->dev, thread->num_corners + drv->extra_corners,
> + sizeof(struct corner_data), GFP_KERNEL);
> + if (!cdata)
> + return -ENOMEM;
> +
> + for (level = 1; level <= thread->num_corners; level++) {
> + opp = dev_pm_opp_find_level_exact(&thread->pd.dev, level);
> + if (IS_ERR(opp))
> + return -EINVAL;
> +
> + /*
> + * If there is only one specified qcom,opp-fuse-level, then
> + * it is assumed that this only one is global and valid for
> + * all IDs, so try to get the specific one but, on failure,
> + * go for the global one.
> + */
> + fc = cpr_get_fuse_corner(opp, thread->id);
> + if (fc == 0) {
> + fc = cpr_get_fuse_corner(opp, 0);
> + if (fc == 0) {
> + dev_err(drv->dev, "qcom,opp-fuse-level is missing!\n");
> + dev_pm_opp_put(opp);
> + return -EINVAL;
> + }
> + }
> + fnum = fc - 1;
> +
> + freq = cpr_get_opp_hz_for_req(opp, thread->attached_cpu_dev);
> + if (!freq) {
> + thread->num_corners = max(level - 1, 0);
> + end = &thread->corners[thread->num_corners - 1];
> + break;
> + }
> +
> + /*
> + * If any post-vadj (open/closed loop) is not specified, then
> + * it's zero, meaning that it is not required for this corner.
> + */
> + cpr_get_corner_post_vadj(opp, thread->id,
> + &cdata[level - 1].oloop_vadj,
> + &cdata[level - 1].cloop_vadj);
> + cdata[level - 1].fuse_corner = fnum;
> + cdata[level - 1].freq = freq;
> +
> + fuse = &thread->fuse_corners[fnum];
> + dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n",
> + freq, dev_pm_opp_get_level(opp) - 1, fnum);
> + if (freq > fuse->max_freq)
> + fuse->max_freq = freq;
> + dev_pm_opp_put(opp);
> +
> + /*
> + * Make sure that the frequencies in the table are in ascending
> + * order, as this is critical for the algorithm to work.
> + */
> + if (cdata[level - 2].freq > freq) {
> + dev_err(drv->dev, "Frequency table not in ascending order.\n");
> + return -EINVAL;
> + }
> + }
> +
> + if (thread->num_corners < 2) {
> + dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
> + return -EINVAL;
> + }
> +
> + /*
> + * Get the quotient adjustment scaling factor, according to:
> + *
> + * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
> + * / (freq(corner_N) - freq(corner_N-1)), max_factor)
> + *
> + * QUOT(corner_N): quotient read from fuse for fuse corner N
> + * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1)
> + * freq(corner_N): max frequency in MHz supported by fuse corner N
> + * freq(corner_N-1): max frequency in MHz supported by fuse corner
> + * (N - 1)
> + *
> + * Then walk through the corners mapped to each fuse corner
> + * and calculate the quotient adjustment for each one using the
> + * following formula:
> + *
> + * quot_adjust = (freq_max - freq_corner) * scaling / 1000
> + *
> + * freq_max: max frequency in MHz supported by the fuse corner
> + * freq_corner: frequency in MHz corresponding to the corner
> + * scaling: calculated from above equation
> + *
> + *
> + * + +
> + * | v |
> + * q | f c o | f c
> + * u | c l | c
> + * o | f t | f
> + * t | c a | c
> + * | c f g | c f
> + * | e |
> + * +--------------- +----------------
> + * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
> + * corner corner
> + *
> + * c = corner
> + * f = fuse corner
> + *
> + */
> + for (i = 0; corner <= end; corner++, i++) {
> + unsigned long freq_diff_mhz;
> + int ro_fac, vadj, prev_quot;
> +
> + fnum = cdata[i].fuse_corner;
> + fdata = &tdesc->fuse_corner_data[fnum];
> + quot_offset = fuses[fnum].quotient_offset;
> + fuse = &thread->fuse_corners[fnum];
> + ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
> + if (fnum)
> + prev_fuse = &thread->fuse_corners[fnum - 1];
> + else
> + prev_fuse = NULL;
> +
> + corner->fuse_corner = fuse;
> + corner->freq = cdata[i].freq;
> + corner->uV = fuse->uV;
> +
> + if (prev_fuse) {
> + if (prev_fuse->ring_osc_idx == fuse->ring_osc_idx)
> + quot_offset = NULL;
> +
> + scaling = cpr_calculate_scaling(drv->dev, quot_offset,
> + fdata, corner);
> + if (scaling < 0)
> + return scaling;
> +
> + freq_diff_mhz = fuse->max_freq - corner->freq;
> + do_div(freq_diff_mhz, 1000000); /* now in MHz */
> +
> + corner->quot_adjust = scaling * freq_diff_mhz;
> + do_div(corner->quot_adjust, 1000);
> +
> + /* Fine-tune QUOT (closed-loop) based on fixed values */
> + ro_fac = cpr_get_ro_factor(tdesc, fnum, fuse->ring_osc_idx);
> + vadj = cdata[i].cloop_vadj;
> + corner->quot_adjust -= cpr3_adjust_quot(ro_fac, vadj);
> + dev_vdbg(drv->dev, "Quot fine-tuning to %d for post-vadj=%d\n",
> + corner->quot_adjust, vadj);
> +
> + /*
> + * Make sure that we scale (up) monotonically.
> + * P.S.: Fuse quots can never be descending.
> + */
> + prev_quot = prev_corner->fuse_corner->quot;
> + prev_quot -= prev_corner->quot_adjust;
> + if (fuse->quot - corner->quot_adjust < prev_quot) {
> + int new_adj = prev_corner->fuse_corner->quot;
> +
> + new_adj -= fuse->quot;
> + dev_vdbg(drv->dev, "Monotonic increase forced: %d->%d\n",
> + corner->quot_adjust, new_adj);
> + corner->quot_adjust = new_adj;
> + }
> +
> + corner->uV = cpr_interpolate(corner,
> + drv->vreg_step, fdata);
> + }
> + /* Negative fuse quotients are nonsense. */
> + if (fuse->quot < corner->quot_adjust)
> + return -EINVAL;
> +
> + min_quotient = min(min_quotient,
> + (u32)(fuse->quot - corner->quot_adjust));
> +
> + /* Fine-tune voltages (open-loop) based on fixed values */
> + corner->uV += cdata[i].oloop_vadj;
> + dev_dbg(drv->dev, "Voltage fine-tuning to %d for post-vadj=%d\n",
> + corner->uV, cdata[i].oloop_vadj);
> +
> + corner->max_uV = fuse->max_uV;
> + corner->min_uV = fuse->min_uV;
> + corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV);
> + dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d %d]\n",
> + corner->min_uV, corner->uV, corner->max_uV);
> +
> + /* Make sure that we scale monotonically here, too. */
> + if (corner->uV < prev_corner->uV)
> + corner->uV = prev_corner->uV;
> +
> + corner->last_uV = corner->uV;
> +
> + /* Reduce the ceiling voltage if needed */
> + if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV)
> + corner->max_uV = corner->uV;
> + else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV)
> + corner->max_uV = max(corner->min_uV, fuse->uV);
> +
> + corner->min_uV = max(corner->max_uV - fdata->range_uV,
> + corner->min_uV);
> +
> + /*
> + * Adjust per-corner floor and ceiling voltages so that
> + * they do not overlap the memory Array Power Mux (APM)
> + * nor the Memory Accelerator (MEM-ACC) threshold voltages.
> + */
> + if (desc->apm_threshold)
> + cpr3_restrict_corner(corner, desc->apm_threshold,
> + desc->apm_hysteresis,
> + drv->vreg_step);
> + if (desc->mem_acc_threshold)
> + cpr3_restrict_corner(corner, desc->mem_acc_threshold,
> + 0, drv->vreg_step);
> +
> + prev_corner = corner;
> + dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d quot %d\n", i,
> + corner->min_uV, corner->uV, corner->max_uV, scaling,
> + fuse->quot - corner->quot_adjust);
> + }
> +
> + /* Additional setup for CPRh only */
> + if (desc->cpr_type < CTRL_TYPE_CPRH)
> + return 0;
> +
> + /* If the OPPs can't be adjusted, programming the CPRh is useless */
> + ret = cprh_corner_adjust_opps(thread);
> + if (ret) {
> + dev_err(drv->dev, "Cannot adjust CPU OPP voltages: %d\n", ret);
> + return ret;
> + }
> +
> + total_corners = thread->num_corners;
> + extra_corners = drv->extra_corners;
> +
> + /* If the APM extra corner exists, add it now. */
> + if (desc->apm_crossover && desc->apm_threshold && extra_corners) {
> + /* Program the APM crossover corner on the CPR-Hardened */
> + thread->corners[total_corners].uV = desc->apm_crossover;
> + thread->corners[total_corners].min_uV = desc->apm_crossover;
> + thread->corners[total_corners].max_uV = desc->apm_crossover;
> + thread->corners[total_corners].is_open_loop = true;
> +
> + /*
> + * We have calculated the APM parameters for this clock plan:
> + * make the APM *threshold* available to external callers.
> + * The crossover is used only internally in the CPR.
> + */
> + thread->ext_data.apm_threshold_uV = desc->apm_threshold;
> +
> + dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] Open-Loop\n",
> + total_corners, desc->apm_crossover,
> + desc->apm_crossover, desc->apm_crossover);
> +
> + total_corners++;
> + extra_corners--;
> + }
> +
> + if (desc->mem_acc_threshold && extra_corners) {
> + /* Program the Memory Accelerator threshold corner to CPRh */
> + thread->corners[total_corners].uV = desc->mem_acc_threshold;
> + thread->corners[total_corners].min_uV = desc->mem_acc_threshold;
> + thread->corners[total_corners].max_uV = desc->mem_acc_threshold;
> + thread->corners[total_corners].is_open_loop = true;
> +
> + /*
> + * We have calculated a mem-acc threshold for this clock plan:
> + * make it available to external callers.
> + */
> + thread->ext_data.mem_acc_threshold_uV = desc->mem_acc_threshold;
> +
> + dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] Open-Loop\n",
> + total_corners, desc->mem_acc_threshold,
> + desc->mem_acc_threshold, desc->mem_acc_threshold);
> +
> + total_corners++;
> + extra_corners--;
> + }
> +
> + /*
> + * If there are any extra corners left, it means that even though we
> + * expect to fill in both APM and MEM-ACC crossovers, one couldn't
> + * satisfy requirements, which means that the specified parameters
> + * are wrong: in this case, inform the user and bail out, otherwise
> + * if we go on writing the (invalid) table to the CPR-Hardened, the
> + * hardware (in this case, the CPU) will surely freeze and crash.
> + */
> + if (unlikely(extra_corners)) {
> + dev_err(drv->dev, "APM/MEM-ACC corners: bad parameters.\n");
> + return -EINVAL;
> + }
> + /* Reassign extra_corners, as we have to exclude delta_quot for them */
> + extra_corners = drv->extra_corners;
> +
> + /* Disable the interface between OSM and CPRh */
> + cpr_masked_write(thread, drv->reg_ctl,
> + CPRH_CTL_OSM_ENABLED, 0);
> +
> + /* Program the GCNT before unmasking ring oscillator(s) */
> + for (i = 0; i < CPR3_RO_COUNT; i++) {
> + if (!(ring_osc_mask & BIT(i))) {
> + cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
> + dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, drv->gcnt);
> + }
> + }
> +
> + /*
> + * Unmask the ring oscillator(s) that we're going to use: it seems
> + * to be mandatory to do this *before* sending the rest of the
> + * CPRhardened specific configuration.
> + */
> + dev_dbg(drv->dev, "Unmasking ring oscillators with mask 0x%x\n", ring_osc_mask);
> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), ring_osc_mask);
> +
> + /* Setup minimum quotients for ring oscillators */
> + for (i = 0; i < CPR3_RO_COUNT; i++) {
> + u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, i);
> + u32 tgt_quot_val = 0;
> +
> + if (!(ring_osc_mask & BIT(i)))
> + tgt_quot_val = min_quotient;
> +
> + cpr_write(thread, tgt_quot_reg, tgt_quot_val);
> + dev_vdbg(drv->dev, "Programmed min quotient %u for Ring Oscillator %d\n",
> + tgt_quot_val, tgt_quot_reg);
> + }
> +
> + for (i = 0; i < total_corners; i++) {
> + int volt_oloop_steps, volt_floor_steps, delta_quot_steps;
> + int ring_osc;
> + u32 val;
> +
> + fnum = cdata[i].fuse_corner;
> + fuse = &thread->fuse_corners[fnum];
> +
> + val = thread->corners[i].uV - desc->cpr_base_voltage;
> + volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
> +
> + val = thread->corners[i].min_uV - desc->cpr_base_voltage;
> + volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
> +
> + /*
> + * If we are accessing corners that are not used as
> + * an active DCVS set-point, then always select RO 0
> + * and zero out the delta quotient.
> + */
> + if (i >= thread->num_corners) {
> + ring_osc = 0;
> + delta_quot_steps = 0;
> + } else {
> + ring_osc = fuse->ring_osc_idx;
> + val = fuse->quot - thread->corners[i].quot_adjust;
> + val -= min_quotient;
> + delta_quot_steps = DIV_ROUND_UP(val,
> + CPRH_DELTA_QUOT_STEP_FACTOR);
> + }
> +
> + if (volt_oloop_steps > CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE ||
> + volt_floor_steps > CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
> + delta_quot_steps > CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
> + dev_err(drv->dev, "Invalid cfg: oloop=%d, floor=%d, delta=%d\n",
> + volt_oloop_steps, volt_floor_steps,
> + delta_quot_steps);
> + return -EINVAL;
> + }
> + /* Green light: Go, Go, Go! */
> +
> + /* Set number of open-loop steps */
> + val = volt_oloop_steps << CPRH_CORNER_INIT_VOLTAGE_SHIFT;
> + val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
> +
> + /* Set number of floor voltage steps */
> + val |= (volt_floor_steps << CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
> + CPRH_CORNER_FLOOR_VOLTAGE_MASK;
> +
> + /* Set number of target quotient delta steps */
> + val |= (delta_quot_steps << CPRH_CORNER_QUOT_DELTA_SHIFT) &
> + CPRH_CORNER_QUOT_DELTA_MASK;
> +
> + /* Select ring oscillator for this corner */
> + val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
> + CPRH_CORNER_RO_SEL_MASK;
> +
> + /* Open loop corner is usually APM/ACC crossover */
> + if (thread->corners[i].is_open_loop) {
> + dev_dbg(drv->dev, "Disabling Closed-Loop on corner %d\n", i);
> + val |= CPRH_CORNER_CPR_CL_DISABLE;
> + }
> + cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, i), val);
> +
> + dev_dbg(drv->dev, "steps [%d]: open-loop %d, floor %d, delta_quot %d\n",
> + i, volt_oloop_steps, volt_floor_steps,
> + delta_quot_steps);
> + }
> +
> + /* YAY! Setup is done! Enable the internal loop to start CPR. */
> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
> + CPR3_CPR_CTL_LOOP_EN_MASK,
> + CPR3_CPR_CTL_LOOP_EN_MASK);
> +
> + /*
> + * All the writes are going through before enabling internal
> + * communication between the OSM and the CPRh controllers
> + * because we are never using relaxed accessors, but should
> + * we use them, it would be critical to issue a barrier here,
> + * otherwise there is a high risk of hardware lockups due to
> + * under-voltage for the selected CPU clock.
> + *
> + * Please note that the CPR-hardened gets set-up in Linux but
> + * then gets actually used in firmware (and only by the OSM);
> + * after handing it off we will have no more control on it.
> + */
> +
> + /* Enable the interface between OSM and CPRh */
> + cpr_masked_write(thread, drv->reg_ctl,
> + CPRH_CTL_OSM_ENABLED,
> + CPRH_CTL_OSM_ENABLED);
> +
> + /* On success, free cdata manually */
> + devm_kfree(drv->dev, cdata);
> + return 0;
> +}
> +
> +/**
> + * cpr3_init_parameters() - Initialize CPR global parameters
> + * @drv: Main driver structure
> + *
> + * Initial "integrity" checks and setup for the thread-independent parameters.
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr3_init_parameters(struct cpr_drv *drv)
> +{
> + const struct cpr_desc *desc = drv->desc;
> + struct clk *clk;
> +
> + clk = devm_clk_get(drv->dev, "ref");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + drv->ref_clk_khz = clk_get_rate(clk);
> + do_div(drv->ref_clk_khz, 1000);
> +
> + /* On CPRh this clock is not always-on... */
> + if (desc->cpr_type == CTRL_TYPE_CPRH)
> + clk_prepare_enable(clk);
> + else
> + devm_clk_put(drv->dev, clk);
> +
> + if (desc->timer_cons_up > CPR3_THRESH_CONS_UP_MASK ||
> + desc->timer_cons_down > CPR3_THRESH_CONS_DOWN_MASK ||
> + desc->up_threshold > CPR3_THRESH_UP_THRESH_MASK ||
> + desc->down_threshold > CPR3_THRESH_DOWN_THRESH_MASK ||
> + desc->idle_clocks > CPR3_CPR_CTL_IDLE_CLOCKS_MASK ||
> + desc->count_mode > CPR3_CPR_CTL_COUNT_MODE_MASK ||
> + desc->count_repeat > CPR3_CPR_CTL_COUNT_REPEAT_MASK)
> + return -EINVAL;
> +
> + /*
> + * Read the CPR version register only from CPR3 onwards:
> + * this is needed to get the additional register offsets.
> + *
> + * Note: When threaded, even if multi-controller, there
> + * is no chance to have different versions at the
> + * same time in the same domain, so it is safe to
> + * check this only on the first controller/thread.
> + */
> + drv->cpr_hw_rev = cpr_read(&drv->threads[0],
> + CPR3_REG_CPR_VERSION);
> + dev_dbg(drv->dev, "CPR hardware revision: 0x%x\n", drv->cpr_hw_rev);
> +
> + if (drv->cpr_hw_rev >= CPRH_CPR_VERSION_4P5) {
> + drv->reg_corner = 0x3500;
> + drv->reg_corner_tid = 0xa0;
> + drv->reg_ctl = 0x3a80;
> + drv->reg_status = 0x3a84;
> + } else {
> + drv->reg_corner = 0x3a00;
> + drv->reg_corner_tid = 0;
> + drv->reg_ctl = 0x3aa0;
> + drv->reg_status = 0x3aa4;
> + }
> +
> + dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n",
> + desc->up_threshold, desc->down_threshold);
> +
> + return 0;
> +}
> +
> +/**
> + * cpr3_find_initial_corner() - Finds boot-up p-state and enables CPR
> + * @thread: Structure holding CPR thread-specific parameters
> + *
> + * Differently from CPRv1, from CPRv3 onwards when we successfully find
> + * the target boot-up performance state, we must refresh the HW
> + * immediately to guarantee system stability and to avoid overheating
> + * during the boot process, thing that would more likely happen without
> + * this driver doing its job.
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr3_find_initial_corner(struct cpr_thread *thread)
> +{
> + struct cpr_drv *drv = thread->drv;
> + struct corner *corner;
> + int uV, idx;
> +
> + idx = cpr_find_initial_corner(drv->dev, thread->cpu_clk,
> + thread->corners,
> + thread->num_corners);
> + if (idx < 0)
> + return idx;
> +
> + cpr_ctl_disable(thread);
> +
> + corner = &thread->corners[idx];
> + cpr_corner_restore(thread, corner);
> +
> + uV = regulator_get_voltage(drv->vreg);
> + uV = clamp(uV, corner->min_uV, corner->max_uV);
> +
> + corner->last_uV = uV;
> + if (!drv->last_uV)
> + drv->last_uV = uV;
> +
> + cpr_commit_state(thread);
> + thread->enabled = true;
> + cpr_switch(drv);
> +
> + return 0;
> +}
> +
> +static const int msm8998_gold_scaling_factor[][CPR3_RO_COUNT] = {
> + /* Fuse Corner 0 */
> + {
> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
> + },
> + /* Fuse Corner 1 */
> + {
> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
> + },
> + /* Fuse Corner 2 */
> + {
> + 2603, 2755, 2676, 2777, 2573, 2685, 2465, 2610,
> + 2312, 2423, 2243, 3104, 3022, 3036, 2740, 2303
> + },
> + /* Fuse Corner 3 */
> + {
> + 1901, 2016, 2096, 2228, 2034, 2161, 2077, 2188,
> + 1565, 1870, 1925, 2235, 2205, 2413, 1762, 1478
> + }
> +};
> +
> +static const int msm8998_silver_scaling_factor[][CPR3_RO_COUNT] = {
> + /* Fuse Corner 0 */
> + {
> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
> + },
> + /* Fuse Corner 1 */
> + {
> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
> + },
> + /* Fuse Corner 2 */
> + {
> + 2391, 2550, 2483, 2638, 2382, 2564, 2259, 2555,
> + 2766, 3041, 2988, 2935, 2873, 2688, 2013, 2784
> + },
> + /* Fuse Corner 3 */
> + {
> + 2066, 2153, 2300, 2434, 2220, 2386, 2288, 2465,
> + 2028, 2511, 2487, 2734, 2554, 2117, 1892, 2377
> + }
> +};
> +
> +static const struct cpr_thread_desc msm8998_thread_gold = {
> + .controller_id = 1,
> + .hw_tid = 0,
> + .ro_scaling_factor = msm8998_gold_scaling_factor,
> + .ro_avail_corners = ARRAY_SIZE(msm8998_gold_scaling_factor),
> + .sensor_range_start = 0,
> + .sensor_range_end = 9,
> + .init_voltage_step = 10000,
> + .init_voltage_width = 6,
> + .step_quot_init_min = 9,
> + .step_quot_init_max = 14,
> + .num_fuse_corners = 4,
> + .fuse_corner_data = (struct fuse_corner_data[]){
> + /* fuse corner 0 */
> + {
> + .ref_uV = 756000,
> + .max_uV = 828000,
> + .min_uV = 568000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 0,
> + .volt_oloop_adjust = 8000,
> + .max_volt_scale = 4,
> + .max_quot_scale = 10,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 1 */
> + {
> + .ref_uV = 756000,
> + .max_uV = 900000,
> + .min_uV = 624000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 0,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 320,
> + .max_quot_scale = 350,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 2 */
> + {
> + .ref_uV = 828000,
> + .max_uV = 952000,
> + .min_uV = 632000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 12000,
> + .volt_oloop_adjust = 12000,
> + .max_volt_scale = 620,
> + .max_quot_scale = 750,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 3 */
> + {
> + .ref_uV = 1056000,
> + .max_uV = 1136000,
> + .min_uV = 772000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = 50000,
> + .volt_oloop_adjust = 52000,
> + .max_volt_scale = 580,
> + .max_quot_scale = 1040,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + },
> +};
> +
> +static const struct cpr_thread_desc msm8998_thread_silver = {
> + .controller_id = 0,
> + .hw_tid = 0,
> + .ro_scaling_factor = msm8998_silver_scaling_factor,
> + .ro_avail_corners = ARRAY_SIZE(msm8998_silver_scaling_factor),
> + .sensor_range_start = 0,
> + .sensor_range_end = 6,
> + .init_voltage_step = 10000,
> + .init_voltage_width = 6,
> + .step_quot_init_min = 11,
> + .step_quot_init_max = 12,
> + .num_fuse_corners = 4,
> + .fuse_corner_data = (struct fuse_corner_data[]){
> + /* fuse corner 0 */
> + {
> + .ref_uV = 688000,
> + .max_uV = 828000,
> + .min_uV = 568000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 20000,
> + .volt_oloop_adjust = 40000,
> + .max_volt_scale = 4,
> + .max_quot_scale = 10,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 1 */
> + {
> + .ref_uV = 756000,
> + .max_uV = 900000,
> + .min_uV = 632000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 26000,
> + .volt_oloop_adjust = 24000,
> + .max_volt_scale = 500,
> + .max_quot_scale = 800,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 2 */
> + {
> + .ref_uV = 828000,
> + .max_uV = 952000,
> + .min_uV = 664000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = 12000,
> + .volt_oloop_adjust = 12000,
> + .max_volt_scale = 280,
> + .max_quot_scale = 650,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> +
> + },
> + /* fuse corner 3 */
> + {
> + .ref_uV = 1056000,
> + .max_uV = 1056000,
> + .min_uV = 772000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = 30000,
> + .volt_oloop_adjust = 30000,
> + .max_volt_scale = 430,
> + .max_quot_scale = 800,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + },
> +};
> +
> +static const struct cpr_desc msm8998_cpr_desc = {
> + .cpr_type = CTRL_TYPE_CPRH,
> + .num_threads = 2,
> + .mem_acc_threshold = 852000,
> + .apm_threshold = 800000,
> + .apm_crossover = 880000,
> + .apm_hysteresis = 0,
> + .cpr_base_voltage = 352000,
> + .cpr_max_voltage = 1200000,
> + .timer_delay_us = 5000,
> + .timer_cons_up = 0,
> + .timer_cons_down = 2,
> + .up_threshold = 2,
> + .down_threshold = 2,
> + .idle_clocks = 15,
> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
> + .count_repeat = 14,
> + .gcnt_us = 1,
> + .vreg_step_fixed = 4000,
> + .vreg_step_up_limit = 1,
> + .vreg_step_down_limit = 1,
> + .vdd_settle_time_us = 34,
> + .corner_settle_time_us = 6,
> + .reduce_to_corner_uV = true,
> + .hw_closed_loop_en = true,
> + .threads = (const struct cpr_thread_desc *[]) {
> + &msm8998_thread_silver,
> + &msm8998_thread_gold,
> + },
> +};
> +
> +static const struct cpr_acc_desc msm8998_cpr_acc_desc = {
> + .cpr_desc = &msm8998_cpr_desc,
> +};
> +
> +static const int sdm630_gold_scaling_factor[][CPR3_RO_COUNT] = {
> + /* Same RO factors for all fuse corners */
> + {
> + 4040, 3230, 0, 2210, 2560, 2450, 2230, 2220,
> + 2410, 2300, 2560, 2470, 1600, 3120, 2620, 2280
> + }
> +};
> +
> +static const int sdm630_silver_scaling_factor[][CPR3_RO_COUNT] = {
> + /* Same RO factors for all fuse corners */
> + {
> + 3600, 3600, 3830, 2430, 2520, 2700, 1790, 1760,
> + 1970, 1880, 2110, 2010, 2510, 4900, 4370, 4780,
> + }
> +};
> +
> +static const struct cpr_thread_desc sdm630_thread_gold = {
> + .controller_id = 0,
> + .hw_tid = 0,
> + .ro_scaling_factor = sdm630_gold_scaling_factor,
> + .ro_avail_corners = ARRAY_SIZE(sdm630_gold_scaling_factor),
> + .sensor_range_start = 0,
> + .sensor_range_end = 6,
> + .init_voltage_step = 10000,
> + .init_voltage_width = 6,
> + .step_quot_init_min = 12,
> + .step_quot_init_max = 14,
> + .num_fuse_corners = 5,
> + .fuse_corner_data = (struct fuse_corner_data[]){
> + /* fuse corner 0 */
> + {
> + .ref_uV = 644000,
> + .max_uV = 724000,
> + .min_uV = 588000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 15000,
> + .max_volt_scale = 10,
> + .max_quot_scale = 300,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 1 */
> + {
> + .ref_uV = 788000,
> + .max_uV = 788000,
> + .min_uV = 652000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 5000,
> + .max_volt_scale = 320,
> + .max_quot_scale = 275,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 2 */
> + {
> + .ref_uV = 868000,
> + .max_uV = 868000,
> + .min_uV = 712000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 5000,
> + .max_volt_scale = 350,
> + .max_quot_scale = 800,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 3 */
> + {
> + .ref_uV = 988000,
> + .max_uV = 988000,
> + .min_uV = 784000,
> + .range_uV = 66000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 868,
> + .max_quot_scale = 980,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 4 */
> + {
> + .ref_uV = 1068000,
> + .max_uV = 1068000,
> + .min_uV = 844000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 868,
> + .max_quot_scale = 980,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + },
> +};
> +
> +static const struct cpr_thread_desc sdm630_thread_silver = {
> + .controller_id = 1,
> + .hw_tid = 0,
> + .ro_scaling_factor = sdm630_silver_scaling_factor,
> + .ro_avail_corners = ARRAY_SIZE(sdm630_silver_scaling_factor),
> + .sensor_range_start = 0,
> + .sensor_range_end = 6,
> + .init_voltage_step = 10000,
> + .init_voltage_width = 6,
> + .step_quot_init_min = 12,
> + .step_quot_init_max = 14,
> + .num_fuse_corners = 3,
> + .fuse_corner_data = (struct fuse_corner_data[]){
> + /* fuse corner 0 */
> + {
> + .ref_uV = 644000,
> + .max_uV = 724000,
> + .min_uV = 588000,
> + .range_uV = 32000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 10,
> + .max_quot_scale = 360,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 1 */
> + {
> + .ref_uV = 788000,
> + .max_uV = 788000,
> + .min_uV = 652000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 500,
> + .max_quot_scale = 550,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + /* fuse corner 2 */
> + {
> + .ref_uV = 1068000,
> + .max_uV = 1068000,
> + .min_uV = 800000,
> + .range_uV = 40000,
> + .volt_cloop_adjust = -30000,
> + .volt_oloop_adjust = 0,
> + .max_volt_scale = 2370,
> + .max_quot_scale = 550,
> + .quot_offset = 0,
> + .quot_scale = 1,
> + .quot_adjust = 0,
> + .quot_offset_scale = 5,
> + .quot_offset_adjust = 0,
> + },
> + },
> +};
> +
> +static const struct cpr_desc sdm630_cpr_desc = {
> + .cpr_type = CTRL_TYPE_CPRH,
> + .num_threads = 2,
> + .apm_threshold = 872000,
> + .apm_crossover = 872000,
> + .apm_hysteresis = 20000,
> + .cpr_base_voltage = 400000,
> + .cpr_max_voltage = 1300000,
> + .timer_delay_us = 5000,
> + .timer_cons_up = 0,
> + .timer_cons_down = 2,
> + .up_threshold = 2,
> + .down_threshold = 2,
> + .idle_clocks = 15,
> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
> + .count_repeat = 14,
> + .gcnt_us = 1,
> + .vreg_step_fixed = 4000,
> + .vreg_step_up_limit = 1,
> + .vreg_step_down_limit = 1,
> + .vdd_settle_time_us = 34,
> + .corner_settle_time_us = 5,
> + .reduce_to_corner_uV = true,
> + .hw_closed_loop_en = true,
> + .threads = (const struct cpr_thread_desc *[]) {
> + &sdm630_thread_gold,
> + &sdm630_thread_silver,
> + },
> +};
> +
> +static const struct cpr_acc_desc sdm630_cpr_acc_desc = {
> + .cpr_desc = &sdm630_cpr_desc,
> +};
> +
> +static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
> + struct dev_pm_opp *opp)
> +{
> + return dev_pm_opp_get_level(opp);
> +}
> +
> +static int cpr_power_off(struct generic_pm_domain *domain)
> +{
> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
> +
> + return cpr_disable(thread);
> +}
> +
> +static int cpr_power_on(struct generic_pm_domain *domain)
> +{
> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
> +
> + return cpr_enable(thread);
> +}
> +
> +static void cpr_pd_detach_dev(struct generic_pm_domain *domain,
> + struct device *dev)
> +{
> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
> + struct cpr_drv *drv = thread->drv;
> +
> + mutex_lock(&drv->lock);
> +
> + dev_dbg(drv->dev, "detach callback for: %s\n", dev_name(dev));
> + thread->attached_cpu_dev = NULL;
> +
> + mutex_unlock(&drv->lock);
> +}
> +
> +static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
> + struct device *dev)
> +{
> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
> + struct cpr_drv *drv = thread->drv;
> + const struct acc_desc *acc_desc = drv->acc_desc;
> + bool cprh_opp_remove_table = false;
> + int ret = 0;
> +
> + mutex_lock(&drv->lock);
> +
> + dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev));
> +
> + /*
> + * This driver only supports scaling voltage for a CPU cluster
> + * where all CPUs in the cluster share a single regulator.
> + * Therefore, save the struct device pointer only for the first
> + * CPU device that gets attached. There is no need to do any
> + * additional initialization when further CPUs get attached.
> + * This is not an error condition.
> + */
> + if (thread->attached_cpu_dev)
> + goto unlock;
> +
> + /*
> + * cpr_scale_voltage() requires the direction (if we are changing
> + * to a higher or lower OPP). The first time
> + * cpr_set_performance_state() is called, there is no previous
> + * performance state defined. Therefore, we call
> + * cpr_find_initial_corner() that gets the CPU clock frequency
> + * set by the bootloader, so that we can determine the direction
> + * the first time cpr_set_performance_state() is called.
> + */
> + thread->cpu_clk = devm_clk_get(dev, NULL);
> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH && IS_ERR(thread->cpu_clk)) {
> + ret = PTR_ERR(thread->cpu_clk);
> + if (ret != -EPROBE_DEFER)
> + dev_err(drv->dev, "could not get cpu clk: %d\n", ret);
> + goto unlock;
> + }
> + thread->attached_cpu_dev = dev;
> +
> + /*
> + * We are exporting the APM and MEM-ACC thresholds to the caller;
> + * while APM is necessary in the CPU CPR case, MEM-ACC may not be,
> + * depending on the SoC and on fuses.
> + * Initialize both to an invalid value, so that the caller can check
> + * if they got calculated or read from fuses in this driver.
> + */
> + thread->ext_data.apm_threshold_uV = -1;
> + thread->ext_data.mem_acc_threshold_uV = -1;
> + dev_set_drvdata(thread->attached_cpu_dev, &thread->ext_data);
> +
> + dev_dbg(drv->dev, "using cpu clk from: %s\n",
> + dev_name(thread->attached_cpu_dev));
> +
> + /*
> + * Everything related to (virtual) corners has to be initialized
> + * here, when attaching to the power domain, since we need to know
> + * the maximum frequency for each fuse corner, and this is only
> + * available after the cpufreq driver has attached to us.
> + * The reason for this is that we need to know the highest
> + * frequency associated with each fuse corner.
> + */
> + ret = dev_pm_opp_get_opp_count(&thread->pd.dev);
> + if (ret < 0) {
> + dev_err(drv->dev, "could not get OPP count\n");
> + thread->attached_cpu_dev = NULL;
> + goto unlock;
> + }
> + thread->num_corners = ret;
> +
> + thread->corners = devm_kcalloc(drv->dev,
> + thread->num_corners +
> + drv->extra_corners,
> + sizeof(*thread->corners),
> + GFP_KERNEL);
> + if (!thread->corners) {
> + ret = -ENOMEM;
> + goto unlock;
> + }
> +
> + /*
> + * If we are on CPR-Hardened we have to make sure that the attached
> + * device has a OPP table installed, as we're going to modify it here
> + * with our calculations based on qfprom values.
> + */
> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH) {
> + ret = dev_pm_opp_of_add_table(dev);
> + if (ret && ret != -EEXIST) {
> + dev_err(drv->dev, "Cannot add table: %d\n", ret);
> + goto unlock;
> + }
> + cprh_opp_remove_table = true;
> + }
> +
> + ret = cpr3_corner_init(thread);
> + if (ret)
> + goto exit;
> +
> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH) {
> + ret = cpr3_find_initial_corner(thread);
> + if (ret)
> + goto exit;
> +
> + if (acc_desc->config)
> + regmap_multi_reg_write(drv->tcsr, acc_desc->config,
> + acc_desc->num_regs_per_fuse);
> +
> + /* Enable ACC if required */
> + if (acc_desc->enable_mask)
> + regmap_update_bits(drv->tcsr, acc_desc->enable_reg,
> + acc_desc->enable_mask,
> + acc_desc->enable_mask);
> + }
> + dev_info(drv->dev, "thread %d initialized with %u OPPs\n",
> + thread->id, thread->num_corners);
> +exit:
> + /*
> + * If we are on CPRh and we reached an error condition, we installed
> + * the OPP table but we haven't done any setup on it, nor we ever will.
> + * In order to leave a clean state, remove the table.
> + */
> + if (ret && cprh_opp_remove_table)
> + dev_pm_opp_of_remove_table(thread->attached_cpu_dev);
> +unlock:
> + mutex_unlock(&drv->lock);
> +
> + return ret;
> +}
> +
> +static int cpr3_debug_info_show(struct seq_file *s, void *unused)
> +{
> + u32 ro_sel, ctl, irq_status, reg, quot;
> + struct cpr_thread *thread = s->private;
> + struct corner *corner = thread->corners;
> + struct fuse_corner *fuse = thread->fuse_corners;
> + unsigned int i;
> +
> + const struct {
> + const char *name;
> + uint32_t mask;
> + uint8_t shift;
> + } result0_fields[] = {
> + { "busy", 1, 0 },
> + { "step_dn", 1, 1 },
> + { "step_up", 1, 2 },
> + { "error_steps", CPR3_RESULT0_ERROR_STEPS_MASK,
> + CPR3_RESULT0_ERROR_STEPS_SHIFT },
> + { "error", CPR3_RESULT0_ERROR_MASK, CPR3_RESULT0_ERROR_SHIFT },
> + { "negative", 1, 20 },
> + }, result1_fields[] = {
> + { "quot_min", CPR3_RESULT1_QUOT_MIN_MASK,
> + CPR3_RESULT1_QUOT_MIN_SHIFT },
> + { "quot_max", CPR3_RESULT1_QUOT_MAX_MASK,
> + CPR3_RESULT1_QUOT_MAX_SHIFT },
> + { "ro_min", CPR3_RESULT1_RO_MIN_MASK,
> + CPR3_RESULT1_RO_MIN_SHIFT },
> + { "ro_max", CPR3_RESULT1_RO_MAX_MASK,
> + CPR3_RESULT1_RO_MAX_SHIFT },
> + }, result2_fields[] = {
> + { "qout_step_min", CPR3_RESULT2_STEP_QUOT_MIN_MASK,
> + CPR3_RESULT2_STEP_QUOT_MIN_SHIFT },
> + { "qout_step_max", CPR3_RESULT2_STEP_QUOT_MAX_MASK,
> + CPR3_RESULT2_STEP_QUOT_MAX_SHIFT },
> + { "sensor_min", CPR3_RESULT2_SENSOR_MIN_MASK,
> + CPR3_RESULT2_SENSOR_MIN_SHIFT },
> + { "sensor_max", CPR3_RESULT2_SENSOR_MAX_MASK,
> + CPR3_RESULT2_SENSOR_MAX_SHIFT },
> + };
> +
> + if (thread->drv->desc->cpr_type < CTRL_TYPE_CPRH)
> + seq_printf(s, "current_volt = %d uV\n", thread->drv->last_uV);
> +
> + irq_status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
> + seq_printf(s, "irq_status = %#02X\n", irq_status);
> +
> + ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
> + seq_printf(s, "cpr_ctl = %#02X\n", ctl);
> +
> + seq_printf(s, "thread %d - hw tid: %u - enabled: %d:\n",
> + thread->id, thread->desc->hw_tid, thread->enabled);
> + seq_printf(s, "%d corners, derived from %d fuse corners\n",
> + thread->num_corners, thread->desc->num_fuse_corners);
> +
> + for (i = 0; i < thread->num_corners; i++, corner++)
> + seq_printf(s, "corner %d - uV=[%d %d %d] quot=%d freq=%lu\n",
> + i, corner->min_uV, corner->uV, corner->max_uV,
> + corner->quot_adjust, corner->freq);
> +
> + for (i = 0; i < thread->desc->num_fuse_corners; i++, fuse++)
> + seq_printf(s, "fuse %d - uV=[%d %d %d] quot=%d freq=%lu\n",
> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
> + fuse->quot, corner->freq);
> +
> + seq_printf(s, "requested voltage: %d uV\n", thread->corner->last_uV);
> +
> + ro_sel = corner->fuse_corner->ring_osc_idx;
> + quot = cpr_read(thread, CPR3_REG_TARGET_QUOT(i, ro_sel));
> + seq_printf(s, "quot_target (%u) = %#02X\n", ro_sel, quot);
> +
> + reg = cpr_read(thread, CPR3_REG_RESULT0(i));
> + seq_printf(s, "cpr_result_0 = %#02X\n [", reg);
> + for (i = 0; i < ARRAY_SIZE(result0_fields); i++)
> + seq_printf(s, "%s%s = %u",
> + i ? ", " : "",
> + result0_fields[i].name,
> + (reg >> result0_fields[i].shift) &
> + result0_fields[i].mask);
> + seq_puts(s, "]\n");
> + reg = cpr_read(thread, CPR3_REG_RESULT1(i));
> + seq_printf(s, "cpr_result_1 = %#02X\n [", reg);
> + for (i = 0; i < ARRAY_SIZE(result1_fields); i++)
> + seq_printf(s, "%s%s = %u",
> + i ? ", " : "",
> + result1_fields[i].name,
> + (reg >> result1_fields[i].shift) &
> + result1_fields[i].mask);
> + seq_puts(s, "]\n");
> + reg = cpr_read(thread, CPR3_REG_RESULT2(i));
> + seq_printf(s, "cpr_result_2 = %#02X\n [", reg);
> + for (i = 0; i < ARRAY_SIZE(result2_fields); i++)
> + seq_printf(s, "%s%s = %u",
> + i ? ", " : "",
> + result2_fields[i].name,
> + (reg >> result2_fields[i].shift) &
> + result2_fields[i].mask);
> + seq_puts(s, "]\n");
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(cpr3_debug_info);
> +
> +static void cpr3_debugfs_init(struct cpr_drv *drv)
> +{
> + int i;
> +
> + drv->debugfs = debugfs_create_dir("qcom_cpr3", NULL);
> +
> + for (i = 0; i < drv->desc->num_threads; i++) {
> + char buf[50];
> +
> + snprintf(buf, sizeof(buf), "thread%d", i);
> +
> + debugfs_create_file(buf, 0444, drv->debugfs, &drv->threads[i],
> + &cpr3_debug_info_fops);
> + }
> +}
> +
> +/**
> + * cpr_thread_init() - Initialize CPR thread related parameters
> + * @drv: Main driver structure
> + * @tid: Thread ID
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr_thread_init(struct cpr_drv *drv, int tid)
> +{
> + const struct cpr_desc *desc = drv->desc;
> + const struct cpr_thread_desc *tdesc = desc->threads[tid];
> + struct cpr_thread *thread = &drv->threads[tid];
> + int ret;
> +
> + if (tdesc->step_quot_init_min > CPR3_CPR_STEP_QUOT_MIN_MASK ||
> + tdesc->step_quot_init_max > CPR3_CPR_STEP_QUOT_MAX_MASK)
> + return -EINVAL;
> +
> + thread->id = tid;
> + thread->drv = drv;
> + thread->desc = tdesc;
> + thread->fuse_corners = devm_kcalloc(drv->dev,
> + tdesc->num_fuse_corners +
> + drv->extra_corners,
> + sizeof(*thread->fuse_corners),
> + GFP_KERNEL);
> + if (!thread->fuse_corners)
> + return -ENOMEM;
> +
> + thread->cpr_fuses = cpr_get_fuses(drv->dev, tid,
> + tdesc->num_fuse_corners);
> + if (IS_ERR(thread->cpr_fuses))
> + return PTR_ERR(thread->cpr_fuses);
> +
> + ret = cpr_populate_ring_osc_idx(thread->drv->dev, thread->fuse_corners,
> + thread->cpr_fuses,
> + tdesc->num_fuse_corners);
> + if (ret)
> + return ret;
> +
> + ret = cpr_fuse_corner_init(thread);
> + if (ret)
> + return ret;
> +
> + thread->pd.name = devm_kasprintf(drv->dev, GFP_KERNEL,
> + "%s_thread%d",
> + drv->dev->of_node->full_name,
> + thread->id);
> + if (!thread->pd.name)
> + return -EINVAL;
> +
> + thread->pd.power_off = cpr_power_off;
> + thread->pd.power_on = cpr_power_on;
> + thread->pd.opp_to_performance_state = cpr_get_performance_state;
> + thread->pd.attach_dev = cpr_pd_attach_dev;
> + thread->pd.detach_dev = cpr_pd_detach_dev;
> +
> + /* CPR-Hardened performance states are managed in firmware */
> + if (desc->cpr_type == CTRL_TYPE_CPRH)
> + thread->pd.set_performance_state = cprh_dummy_set_performance_state;
> + else
> + thread->pd.set_performance_state = cpr_set_performance_state;
> +
> + /* Anything later than CPR1 must be always-on for now */
> + thread->pd.flags = GENPD_FLAG_ALWAYS_ON;
> +
> + drv->cell_data.domains[tid] = &thread->pd;
> +
> + ret = pm_genpd_init(&thread->pd, NULL, false);
> + if (ret)
> + return ret;
> +
> + /* On CPRhardened, the interrupts are managed in firmware */
> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
> + INIT_WORK(&thread->restart_work, cpr_restart_worker);
> +
> + ret = devm_request_threaded_irq(drv->dev, drv->irq,
> + NULL, cpr_irq_handler,
> + IRQF_ONESHOT |
> + IRQF_TRIGGER_RISING,
> + "cpr", drv);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * cpr3_resources_init() - Initialize resources used by this driver
> + * @pdev: Platform device
> + * @drv: Main driver structure
> + *
> + * Return: Zero for success, negative number on error
> + */
> +static int cpr3_resources_init(struct platform_device *pdev,
> + struct cpr_drv *drv)
> +{
> + const struct cpr_desc *desc = drv->desc;
> + struct cpr_thread *threads = drv->threads;
> + unsigned int i;
> + u8 cid_mask = 0;
> +
> + /*
> + * Here, we are accounting for the following usecases:
> + * - One controller
> + * - One or multiple threads on the same iospace
> + *
> + * - Multiple controllers
> + * - Each controller has its own iospace and each
> + * may have one or multiple threads in their
> + * parent controller's iospace
> + *
> + * Then, to avoid complicating the code for no reason,
> + * this also needs a mandatory order in the list of
> + * threads which implies that all of them from the same
> + * controllers are specified sequentially. As an example:
> + *
> + * C0-T0, C0-T1...C0-Tn, C1-T0, C1-T1...C1-Tn
> + */
> + for (i = 0; i < desc->num_threads; i++) {
> + u8 cid = desc->threads[i]->controller_id;
> +
> + if (cid_mask & BIT(cid)) {
> + if (desc->threads[i - 1]->controller_id != cid) {
> + dev_err(drv->dev, "Bad threads order. Please fix!\n");
> + return -EINVAL;
> + }
> + threads[i].base = threads[i - 1].base;
> + continue;
> + }
> + threads[i].base = devm_platform_ioremap_resource(pdev, cid);
> + if (IS_ERR(threads[i].base))
> + return PTR_ERR(threads[i].base);
> + cid_mask |= BIT(cid);
> + }
> + return 0;
> +}
> +
> +static int cpr_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct cpr_drv *drv;
> + const struct cpr_desc *desc;
> + const struct cpr_acc_desc *data;
> + struct device_node *np;
> + unsigned int i;
> + int ret;
> +
> + data = of_device_get_match_data(dev);
> + if (!data || !data->cpr_desc)
> + return -EINVAL;
> +
> + desc = data->cpr_desc;
> +
> + /* CPRh disallows MEM-ACC access from the HLOS */
> + if (!data->acc_desc && desc->cpr_type < CTRL_TYPE_CPRH)
> + return -EINVAL;
> +
> + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
> + if (!drv)
> + return -ENOMEM;
> +
> + drv->dev = dev;
> + drv->desc = desc;
> + drv->threads = devm_kcalloc(dev, desc->num_threads,
> + sizeof(*drv->threads), GFP_KERNEL);
> + if (!drv->threads)
> + return -ENOMEM;
> +
> + drv->cell_data.num_domains = desc->num_threads;
> + drv->cell_data.domains = devm_kcalloc(drv->dev,
> + drv->cell_data.num_domains,
> + sizeof(*drv->cell_data.domains),
> + GFP_KERNEL);
> + if (!drv->cell_data.domains)
> + return -ENOMEM;
> +
> + if (data->acc_desc)
> + drv->acc_desc = data->acc_desc;
> +
> + mutex_init(&drv->lock);
> +
> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
> + np = of_parse_phandle(dev->of_node, "acc-syscon", 0);
> + if (!np)
> + return -ENODEV;
> +
> + drv->tcsr = syscon_node_to_regmap(np);
> + of_node_put(np);
> + if (IS_ERR(drv->tcsr))
> + return PTR_ERR(drv->tcsr);
> + }
> +
> + ret = cpr3_resources_init(pdev, drv);
> + if (ret)
> + return ret;
> +
> + drv->irq = platform_get_irq_optional(pdev, 0);
> + if (desc->cpr_type != CTRL_TYPE_CPRH && drv->irq < 0)
> + return -EINVAL;
> +
> + /* On CPRhardened, vreg access it not allowed */
> + drv->vreg = devm_regulator_get_optional(dev, "vdd");
> + if (desc->cpr_type != CTRL_TYPE_CPRH && IS_ERR(drv->vreg))
> + return PTR_ERR(drv->vreg);
> +
> + /*
> + * On at least CPRhardened, vreg is unaccessible and there is no
> + * way to read linear step from that regulator, hence it is hardcoded
> + * in the driver;
> + * When the vreg_step is not declared in the cpr data (or is zero),
> + * then having access to the vreg regulator is mandatory, as this
> + * will be retrieved through the regulator API.
> + */
> + if (desc->vreg_step_fixed)
> + drv->vreg_step = desc->vreg_step_fixed;
> + else
> + drv->vreg_step = regulator_get_linear_step(drv->vreg);
> +
> + if (!drv->vreg_step)
> + return -EINVAL;
> +
> + /*
> + * Initialize fuse corners, since it simply depends
> + * on data in efuses.
> + * Everything related to (virtual) corners has to be
> + * initialized after attaching to the power domain,
> + * since it depends on the CPU's OPP table.
> + */
> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &drv->fusing_rev);
> + if (ret)
> + return ret;
> +
> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_speed_bin", &drv->speed_bin);
> + if (ret)
> + return ret;
> +
> + /*
> + * Some SoCs require extra corners for MEM-ACC or APM: if
> + * the related parameters have been specified, then reserve
> + * a corner for the APM and/or MEM-ACC crossover, used by
> + * OSM and CPRh HW to set the supply voltage during the APM
> + * and/or MEM-ACC switch routine.
> + */
> + if (desc->cpr_type == CTRL_TYPE_CPRH) {
> + if (desc->apm_crossover && desc->apm_hysteresis >= 0)
> + drv->extra_corners++;
> +
> + if (desc->mem_acc_threshold)
> + drv->extra_corners++;
> + }
> +
> + /* Initialize all threads */
> + for (i = 0; i < desc->num_threads; i++) {
> + ret = cpr_thread_init(drv, i);
> + if (ret)
> + return ret;
> + }
> +
> + /* Initialize global parameters */
> + ret = cpr3_init_parameters(drv);
> + if (ret)
> + return ret;
> +
> + /* Write initial configuration on all threads */
> + for (i = 0; i < desc->num_threads; i++) {
> + ret = cpr_configure(&drv->threads[i]);
> + if (ret)
> + return ret;
> + }
> +
> + ret = of_genpd_add_provider_onecell(dev->of_node, &drv->cell_data);
> + if (ret)
> + return ret;
> +
> + platform_set_drvdata(pdev, drv);
> + cpr3_debugfs_init(drv);
> +
> + return 0;
> +}
> +
> +static int cpr_remove(struct platform_device *pdev)
> +{
> + struct cpr_drv *drv = platform_get_drvdata(pdev);
> + int i;
> +
> + of_genpd_del_provider(pdev->dev.of_node);
> +
> + for (i = 0; i < drv->desc->num_threads; i++) {
> + cpr_ctl_disable(&drv->threads[i]);
> + cpr_irq_set(&drv->threads[i], 0);
> + pm_genpd_remove(&drv->threads[i].pd);
> + }
> +
> + debugfs_remove_recursive(drv->debugfs);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id cpr3_match_table[] = {
> + { .compatible = "qcom,msm8998-cprh", .data = &msm8998_cpr_acc_desc },
> + { .compatible = "qcom,sdm630-cprh", .data = &sdm630_cpr_acc_desc },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, cpr3_match_table);
> +
> +static struct platform_driver cpr3_driver = {
> + .probe = cpr_probe,
> + .remove = cpr_remove,
> + .driver = {
> + .name = "qcom-cpr3",
> + .of_match_table = cpr3_match_table,
> + },
> +};
> +module_platform_driver(cpr3_driver)
> +
> +MODULE_DESCRIPTION("Core Power Reduction (CPR) v3/v4 driver");
> +MODULE_LICENSE("GPL v2");
> \ No newline at end of file
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
2023-01-10 18:27 ` Robert Marko
@ 2023-01-10 18:29 ` Konrad Dybcio
2023-01-10 18:42 ` Robert Marko
0 siblings, 1 reply; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 18:29 UTC (permalink / raw)
To: Robert Marko, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
linux-kernel
On 10.01.2023 19:27, Robert Marko wrote:
>
> On 10. 01. 2023. 18:56, Konrad Dybcio wrote:
>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>
>> This commit introduces a new driver, based on the one for cpr v1,
>> to enable support for the newer Qualcomm Core Power Reduction
>> hardware, known downstream as CPR3, CPR4 and CPRh, and support
>> for MSM8998 and SDM630 CPU power reduction.
>>
>> In these new versions of the hardware, support for various new
>> features was introduced, including voltage reduction for the GPU,
>> security hardening and a new way of controlling CPU DVFS,
>> consisting in internal communication between microcontrollers,
>> specifically the CPR-Hardened and the Operating State Manager.
>>
>> The CPR v3, v4 and CPRh are present in a broad range of SoCs,
>> from the mid-range to the high end ones including, but not limited
>> to, MSM8953/8996/8998, SDM630/636/660/845.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>> [Konrad: rebase, apply review comments]
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>
> Hi Konrad, great to see the series is alive again.
> I am working on IPQ8074 which uses CPRv4 and its the last piece for
> upstream CPU scaling that is missing so this is really interesting for me.
>
> However, I think you forgot to include the <soc/qcom/cpr.h> header so
> it wont currently compile.
>
> Regards,
> Robert
Right, that's rather embarassing..
Here's the contents of the file, I will hold on with resending
until there are some more reviwew comments..
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2019 Linaro Limited
* Copyright (c) 2021, AngeloGioacchino Del Regno
* <angelogioacchino.delregno@somainline.org>
*/
#ifndef __CPR_H__
#define __CPR_H__
struct cpr_ext_data {
int mem_acc_threshold_uV;
int apm_threshold_uV;
};
#endif /* __CPR_H__ */
Konrad
>
>> ---
>> drivers/soc/qcom/Kconfig | 21 +
>> drivers/soc/qcom/Makefile | 4 +-
>> drivers/soc/qcom/cpr-common.h | 2 +
>> drivers/soc/qcom/cpr3.c | 2923 +++++++++++++++++++++++++++++++++
>> 4 files changed, 2949 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/soc/qcom/cpr3.c
>>
>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>> index 21c4ce2315ba..303e958d9432 100644
>> --- a/drivers/soc/qcom/Kconfig
>> +++ b/drivers/soc/qcom/Kconfig
>> @@ -29,6 +29,7 @@ config QCOM_COMMAND_DB
>> config QCOM_CPR
>> tristate "QCOM Core Power Reduction (CPR) support"
>> depends on ARCH_QCOM && HAS_IOMEM
>> + select QCOM_CPR_COMMON
>> select PM_OPP
>> select REGMAP
>> help
>> @@ -42,6 +43,26 @@ config QCOM_CPR
>> To compile this driver as a module, choose M here: the module will
>> be called qcom-cpr
>> +config QCOM_CPR_COMMON
>> + tristate
>> +
>> +config QCOM_CPR3
>> + tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
>> + depends on ARCH_QCOM && HAS_IOMEM
>> + select PM_OPP
>> + select REGMAP
>> + help
>> + Say Y here to enable support for the CPR hardware found on a broad
>> + variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
>> + SDM845 and others.
>> +
>> + This driver populates OPP tables and makes adjustments to them
>> + based on feedback from the CPR hardware. If you want to do CPU
>> + and/or GPU frequency scaling say Y here.
>> +
>> + To compile this driver as a module, choose M here: the module will
>> + be called qcom-cpr3
>> +
>> config QCOM_GENI_SE
>> tristate "QCOM GENI Serial Engine Driver"
>> depends on ARCH_QCOM || COMPILE_TEST
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index ba2b55dd94ff..362e9b712a68 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -3,7 +3,9 @@ CFLAGS_rpmh-rsc.o := -I$(src)
>> obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
>> obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
>> obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
>> -obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
>> +obj-$(CONFIG_QCOM_CPR) += cpr.o
>> +obj-$(CONFIG_QCOM_CPR_COMMON) += cpr-common.o
>> +obj-$(CONFIG_QCOM_CPR3) += cpr3.o
>> obj-$(CONFIG_QCOM_DCC) += dcc.o
>> obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
>> obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
>> diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
>> index 2cd15f7eac90..a90f6351d022 100644
>> --- a/drivers/soc/qcom/cpr-common.h
>> +++ b/drivers/soc/qcom/cpr-common.h
>> @@ -65,6 +65,8 @@ struct corner {
>> struct corner_data {
>> unsigned int fuse_corner;
>> unsigned long freq;
>> + int oloop_vadj;
>> + int cloop_vadj;
>> };
>> struct acc_desc {
>> diff --git a/drivers/soc/qcom/cpr3.c b/drivers/soc/qcom/cpr3.c
>> new file mode 100644
>> index 000000000000..14a1163d37eb
>> --- /dev/null
>> +++ b/drivers/soc/qcom/cpr3.c
>> @@ -0,0 +1,2923 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2019 Linaro Limited
>> + * Copyright (c) 2021, AngeloGioacchino Del Regno
>> + * <angelogioacchino.delregno@somainline.org>
>> + */
>> +
>> +#include <linux/bitops.h>
>> +#include <linux/clk.h>
>> +#include <linux/debugfs.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/module.h>
>> +#include <linux/nvmem-consumer.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_domain.h>
>> +#include <linux/pm_opp.h>
>> +#include <linux/regmap.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/slab.h>
>> +#include <linux/string.h>
>> +#include <linux/workqueue.h>
>> +#include <soc/qcom/cpr.h>
>> +
>> +#include "cpr-common.h"
>> +
>> +#define CPR3_RO_COUNT 16
>> +#define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0)
>> +
>> +/* CPR3 registers */
>> +#define CPR3_REG_CPR_VERSION 0x0
>> +#define CPRH_CPR_VERSION_4P5 0x40050000
>> +
>> +#define CPR3_REG_CPR_CTL 0x4
>> +#define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0)
>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK GENMASK(5, 1)
>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT 1
>> +#define CPR3_CPR_CTL_COUNT_MODE_MASK GENMASK(7, 6)
>> +#define CPR3_CPR_CTL_COUNT_MODE_SHIFT 6
>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN 0
>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX 1
>> +#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED 2
>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE 3
>> +#define CPR3_CPR_CTL_COUNT_REPEAT_MASK GENMASK(31, 9)
>> +#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT 9
>> +
>> +#define CPR3_REG_CPR_STATUS 0x8
>> +#define CPR3_CPR_STATUS_BUSY_MASK BIT(0)
>> +
>> +/*
>> + * This register is not present on controllers that support HW closed-loop
>> + * except CPR4 APSS controller.
>> + */
>> +#define CPR3_REG_CPR_TIMER_AUTO_CONT 0xC
>> +
>> +#define CPR3_REG_CPR_STEP_QUOT 0x14
>> +#define CPR3_CPR_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>> +#define CPR3_CPR_STEP_QUOT_MIN_SHIFT 0
>> +#define CPR3_CPR_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>> +#define CPR3_CPR_STEP_QUOT_MAX_SHIFT 6
>> +#define CPRH_DELTA_QUOT_STEP_FACTOR 4
>> +
>> +#define CPR3_REG_GCNT(ro) (0xA0 + 0x4 * (ro))
>> +#define CPR3_REG_SENSOR_OWNER(sensor) (0x200 + 0x4 * (sensor))
>> +
>> +#define CPR3_REG_CONT_CMD 0x800
>> +#define CPR3_CONT_CMD_ACK 0x1
>> +#define CPR3_CONT_CMD_NACK 0x0
>> +
>> +#define CPR3_REG_THRESH(thread) (0x808 + 0x440 * (thread))
>> +#define CPR3_THRESH_CONS_DOWN_MASK GENMASK(3, 0)
>> +#define CPR3_THRESH_CONS_DOWN_SHIFT 0
>> +#define CPR3_THRESH_CONS_UP_MASK GENMASK(7, 4)
>> +#define CPR3_THRESH_CONS_UP_SHIFT 4
>> +#define CPR3_THRESH_DOWN_THRESH_MASK GENMASK(12, 8)
>> +#define CPR3_THRESH_DOWN_THRESH_SHIFT 8
>> +#define CPR3_THRESH_UP_THRESH_MASK GENMASK(17, 13)
>> +#define CPR3_THRESH_UP_THRESH_SHIFT 13
>> +
>> +#define CPR3_REG_RO_MASK(thread) (0x80C + 0x440 * (thread))
>> +
>> +#define CPR3_REG_RESULT0(thread) (0x810 + 0x440 * (thread))
>> +#define CPR3_RESULT0_BUSY_MASK BIT(0)
>> +#define CPR3_RESULT0_STEP_DN_MASK BIT(1)
>> +#define CPR3_RESULT0_STEP_UP_MASK BIT(2)
>> +#define CPR3_RESULT0_ERROR_STEPS_MASK GENMASK(7, 3)
>> +#define CPR3_RESULT0_ERROR_STEPS_SHIFT 3
>> +#define CPR3_RESULT0_ERROR_MASK GENMASK(19, 8)
>> +#define CPR3_RESULT0_ERROR_SHIFT 8
>> +
>> +#define CPR3_REG_RESULT1(thread) (0x814 + 0x440 * (thread))
>> +#define CPR3_RESULT1_QUOT_MIN_MASK GENMASK(11, 0)
>> +#define CPR3_RESULT1_QUOT_MIN_SHIFT 0
>> +#define CPR3_RESULT1_QUOT_MAX_MASK GENMASK(23, 12)
>> +#define CPR3_RESULT1_QUOT_MAX_SHIFT 12
>> +#define CPR3_RESULT1_RO_MIN_MASK GENMASK(27, 24)
>> +#define CPR3_RESULT1_RO_MIN_SHIFT 24
>> +#define CPR3_RESULT1_RO_MAX_MASK GENMASK(31, 28)
>> +#define CPR3_RESULT1_RO_MAX_SHIFT 28
>> +
>> +#define CPR3_REG_RESULT2(thread) (0x818 + 0x440 * (thread))
>> +#define CPR3_RESULT2_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>> +#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT 0
>> +#define CPR3_RESULT2_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>> +#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT 6
>> +#define CPR3_RESULT2_SENSOR_MIN_MASK GENMASK(23, 16)
>> +#define CPR3_RESULT2_SENSOR_MIN_SHIFT 16
>> +#define CPR3_RESULT2_SENSOR_MAX_MASK GENMASK(31, 24)
>> +#define CPR3_RESULT2_SENSOR_MAX_SHIFT 24
>> +
>> +#define CPR3_REG_IRQ_EN 0x81C
>> +#define CPR3_REG_IRQ_CLEAR 0x820
>> +#define CPR3_REG_IRQ_STATUS 0x824
>> +#define CPR3_IRQ_UP BIT(3)
>> +#define CPR3_IRQ_MID BIT(2)
>> +#define CPR3_IRQ_DOWN BIT(1)
>> +#define CPR3_IRQ_ALL (CPR3_IRQ_UP | CPR3_IRQ_MID | CPR3_IRQ_DOWN)
>> +
>> +#define CPR3_REG_TARGET_QUOT(thread, ro) (0x840 + 0x440 * (thread) + 0x4 * (ro))
>> +
>> +/* Registers found only on controllers that support HW closed-loop. */
>> +#define CPR3_REG_PD_THROTTLE 0xE8
>> +
>> +#define CPR3_REG_HW_CLOSED_LOOP_DISABLED 0x3000
>> +#define CPR3_REG_CPR_TIMER_MID_CONT 0x3004
>> +#define CPR3_REG_CPR_TIMER_UP_DN_CONT 0x3008
>> +
>> +/* CPR4 controller specific registers and bit definitions */
>> +#define CPR4_REG_CPR_TIMER_CLAMP 0x10
>> +#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27)
>> +
>> +#define CPR4_REG_MISC 0x700
>> +#define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2)
>> +#define CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN BIT(3)
>> +
>> +#define CPR4_REG_SAW_ERROR_STEP_LIMIT 0x7A4
>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK GENMASK(4, 0)
>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT 0
>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK GENMASK(9, 5)
>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT 5
>> +
>> +#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS 0x7A8
>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK GENMASK(28, 18)
>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT 18
>> +
>> +#define CPR4_REG_MARGIN_ADJ_CTL 0x7F8
>> +#define CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN BIT(4)
>> +#define CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN BIT(7)
>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK GENMASK(16, 12)
>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT 12
>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_MASK GENMASK(31, 26)
>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_SHIFT 26
>> +
>> +#define CPR4_REG_CPR_MASK_THREAD(thread) (0x80C + 0x440 * (thread))
>> +#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD BIT(31)
>> +#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0)
>> +
>> +/* CPRh controller specific registers and bit definitions */
>> +#define __CPRH_REG_CORNER(rbase, tbase, tid, cnum) (rbase + (tbase * tid) + (0x4 * cnum))
>> +#define CPRH_REG_CORNER(d, t, c) __CPRH_REG_CORNER(d->reg_corner, d->reg_corner_tid, t, c)
>> +
>> +#define CPRH_CTL_OSM_ENABLED BIT(0)
>> +#define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1)
>> +#define CPRH_CTL_BASE_VOLTAGE_SHIFT 1
>> +#define CPRH_CTL_MODE_SWITCH_DELAY_MASK GENMASK(24, 17)
>> +#define CPRH_CTL_MODE_SWITCH_DELAY_SHIFT 17
>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_MASK GENMASK(28, 25)
>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT 25
>> +
>> +#define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0)
>> +#define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0
>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8)
>> +#define CPRH_CORNER_FLOOR_VOLTAGE_SHIFT 8
>> +#define CPRH_CORNER_QUOT_DELTA_MASK GENMASK(24, 16)
>> +#define CPRH_CORNER_QUOT_DELTA_SHIFT 16
>> +#define CPRH_CORNER_RO_SEL_MASK GENMASK(28, 25)
>> +#define CPRH_CORNER_RO_SEL_SHIFT 25
>> +#define CPRH_CORNER_CPR_CL_DISABLE BIT(29)
>> +
>> +#define CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE 255
>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255
>> +#define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511
>> +
>> +enum cpr_type {
>> + CTRL_TYPE_CPR3,
>> + CTRL_TYPE_CPR4,
>> + CTRL_TYPE_CPRH,
>> + CTRL_TYPE_MAX,
>> +};
>> +
>> +/*
>> + * struct cpr_thread_desc - CPR Thread-specific parameters
>> + *
>> + * @controller_id: Identifier of the CPR controller expected by the HW
>> + * @ro_scaling_factor: Scaling factor for each ring oscillator entry
>> + * @hw_tid: Identifier of the CPR thread expected by the HW
>> + * @init_voltage_step: Voltage in uV for number of steps read from fuse array
>> + * @init_voltage_width: Bit-width of the voltage read from the fuse array
>> + * @sensor_range_start: First sensor ID used by a thread
>> + * @sensor_range_end: Last sensor ID used by a thread
>> + * @num_fuse_corners: Number of valid entries in fuse_corner_data
>> + * @step_quot_init_min: Minimum achievable step quotient for this corner
>> + * @step_quot_init_max: Maximum achievable step quotient for this corner
>> + * @fuse_corner_data: Parameters for calculation of each fuse corner
>> + */
>> +struct cpr_thread_desc {
>> + u8 controller_id;
>> + u8 hw_tid;
>> + const int (*ro_scaling_factor)[CPR3_RO_COUNT];
>> + int ro_avail_corners;
>> + int init_voltage_step;
>> + int init_voltage_width;
>> + u8 sensor_range_start;
>> + u8 sensor_range_end;
>> + u8 step_quot_init_min;
>> + u8 step_quot_init_max;
>> + unsigned int num_fuse_corners;
>> + struct fuse_corner_data *fuse_corner_data;
>> +};
>> +
>> +/*
>> + * struct cpr_desc - Driver instance-wide CPR parameters
>> + *
>> + * @cpr_type: Type (base version) of the CPR controller
>> + * @num_threads: Max. number of threads supported by this controller
>> + * @timer_delay_us: Loop delay time in uS
>> + * @timer_updn_delay_us: Voltage after-up/before-down delay time in uS
>> + * @timer_cons_up: Wait between consecutive up requests in uS
>> + * @timer_cons_down: Wait between consecutive down requests in uS
>> + * @up_threshold: Generic corner up threshold
>> + * @down_threshold: Generic corner down threshold
>> + * @idle_clocks: CPR Sensor: idle timer in cpr clocks unit
>> + * @count_mode: CPR Sensor: counting mode
>> + * @count_repeat: CPR Sensor: number of times to repeat reading
>> + * @gcnt_us: CPR measurement interval in uS
>> + * @vreg_step_fixed: Regulator voltage per step (if vreg unusable)
>> + * @vreg_step_up_limit: Num. of steps up at once before re-measuring sensors
>> + * @vreg_step_down_limit: Num. of steps dn at once before re-measuring sensors
>> + * @vdd_settle_time_us: Settling timer to account for one VDD supply step
>> + * @corner_settle_time_us: Settle time for corner switch request
>> + * @mem_acc_threshold: Memory Accelerator (MEM-ACC) voltage threshold
>> + * @apm_threshold: Array Power Mux (APM) voltage threshold
>> + * @apm_crossover: Array Power Mux (APM) corner crossover voltage
>> + * @apm_hysteresis: Hysteresis for APM V-threshold related calculations
>> + * @cpr_base_voltage: Safety: Absolute minimum voltage (uV) on this CPR
>> + * @cpr_max_voltage: Safety: Absolute maximum voltage (uV) on this CPR
>> + * @pd_throttle_val: CPR Power Domain throttle during voltage switch
>> + * @threads: Array containing "CPR Thread" specific parameters
>> + * @reduce_to_fuse_uV: Reduce corner max volts (if higher) to fuse ceiling
>> + * @reduce_to_corner_uV: Reduce corner max volts (if higher) to corner ceil.
>> + * @hw_closed_loop_en: Enable CPR HW Closed-Loop voltage auto-adjustment
>> + */
>> +struct cpr_desc {
>> + enum cpr_type cpr_type;
>> + unsigned int num_threads;
>> + unsigned int timer_delay_us;
>> + u8 timer_updn_delay_us;
>> + u8 timer_cons_up;
>> + u8 timer_cons_down;
>> + u8 up_threshold;
>> + u8 down_threshold;
>> + u8 idle_clocks;
>> + u8 count_mode;
>> + u8 count_repeat;
>> + u8 gcnt_us;
>> + u16 vreg_step_fixed;
>> + u8 vreg_step_up_limit;
>> + u8 vreg_step_down_limit;
>> + u8 vdd_settle_time_us;
>> + u8 corner_settle_time_us;
>> + int mem_acc_threshold;
>> + int apm_threshold;
>> + int apm_crossover;
>> + int apm_hysteresis;
>> + u32 cpr_base_voltage;
>> + u32 cpr_max_voltage;
>> + u32 pd_throttle_val;
>> +
>> + const struct cpr_thread_desc **threads;
>> + bool reduce_to_fuse_uV;
>> + bool reduce_to_corner_uV;
>> + bool hw_closed_loop_en;
>> +};
>> +
>> +struct cpr_drv;
>> +struct cpr_thread {
>> + int num_corners;
>> + int id;
>> + bool enabled;
>> + void __iomem *base;
>> + struct clk *cpu_clk;
>> + struct corner *corner;
>> + struct corner *corners;
>> + struct fuse_corner *fuse_corners;
>> + struct cpr_drv *drv;
>> + struct cpr_ext_data ext_data;
>> + struct generic_pm_domain pd;
>> + struct device *attached_cpu_dev;
>> + struct work_struct restart_work;
>> + bool restarting;
>> +
>> + const struct cpr_fuse *cpr_fuses;
>> + const struct cpr_thread_desc *desc;
>> +};
>> +
>> +struct cpr_drv {
>> + int irq;
>> + unsigned int ref_clk_khz;
>> + struct device *dev;
>> + struct mutex lock;
>> + struct regulator *vreg;
>> + struct regmap *tcsr;
>> + u32 gcnt;
>> + u32 speed_bin;
>> + u32 fusing_rev;
>> + u32 last_uV;
>> + u32 cpr_hw_rev;
>> + u32 reg_corner;
>> + u32 reg_corner_tid;
>> + u32 reg_ctl;
>> + u32 reg_status;
>> + int fuse_level_set;
>> + int extra_corners;
>> + unsigned int vreg_step;
>> + bool enabled;
>> +
>> + struct cpr_thread *threads;
>> + struct genpd_onecell_data cell_data;
>> +
>> + const struct cpr_desc *desc;
>> + const struct acc_desc *acc_desc;
>> + struct dentry *debugfs;
>> +};
>> +
>> +/**
>> + * cpr_get_corner_post_vadj() - Get corner post-voltage adjustment values
>> + * @opp: Pointer to the corresponding OPP struct
>> + * @tid: CPR thread ID
>> + * @open_loop: Pointer to the closed-loop adjustment value
>> + * @closed_loop: Pointer to the open-loop adjustment value
>> + */
>> +void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
>> + s32 *open_loop, s32 *closed_loop)
>> +{
>> + struct device_node *np;
>> +
>> + /*
>> + * There is no of_property_read_s32_index, so we just store the
>> + * result into a s32 variable. After all, the OF API is doing
>> + * the exact same for of_property_read_s32...
>> + */
>> + np = dev_pm_opp_get_of_node(opp);
>> + if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid, open_loop))
>> + *open_loop = 0;
>> +
>> + if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid, closed_loop))
>> + *closed_loop = 0;
>> +
>> + of_node_put(np);
>> +}
>> +
>> +/**
>> + * cpr_get_ro_factor() - Get fuse corner ring oscillator factor
>> + * @tdesc: CPR Thread-specific parameters
>> + * @fnum: Fuse corner
>> + * @ro_idx: Ring Oscillator fuse number
>> + *
>> + * Not all threads have different scaling factors for each
>> + * Fuse Corner: if the RO factors are the same for all corners,
>> + * then only one is specified, instead of uselessly repeating
>> + * the same array for FC-times.
>> + * This function checks for the same and gives back the right
>> + * factor for the requested ring oscillator.
>> + *
>> + * Return: Ring oscillator factor
>> + */
>> +static int cpr_get_ro_factor(const struct cpr_thread_desc *tdesc,
>> + int fnum, int ro_idx)
>> +{
>> + int ro_fnum;
>> +
>> + if (tdesc->ro_avail_corners == tdesc->num_fuse_corners)
>> + ro_fnum = fnum;
>> + else
>> + ro_fnum = 0;
>> +
>> + return tdesc->ro_scaling_factor[ro_fnum][ro_idx];
>> +}
>> +
>> +static void cpr_write(struct cpr_thread *thread, u32 offset, u32 value)
>> +{
>> + writel(value, thread->base + offset);
>> +}
>> +
>> +static u32 cpr_read(struct cpr_thread *thread, u32 offset)
>> +{
>> + return readl(thread->base + offset);
>> +}
>> +
>> +static void
>> +cpr_masked_write(struct cpr_thread *thread, u32 offset, u32 mask, u32 value)
>> +{
>> + u32 val;
>> +
>> + val = readl(thread->base + offset);
>> + val &= ~mask;
>> + val |= value & mask;
>> + writel(val, thread->base + offset);
>> +}
>> +
>> +static void cpr_irq_clr(struct cpr_thread *thread)
>> +{
>> + cpr_write(thread, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_ALL);
>> +}
>> +
>> +static void cpr_irq_clr_nack(struct cpr_thread *thread)
>> +{
>> + cpr_irq_clr(thread);
>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
>> +}
>> +
>> +static void cpr_irq_clr_ack(struct cpr_thread *thread)
>> +{
>> + cpr_irq_clr(thread);
>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_ACK);
>> +}
>> +
>> +static void cpr_irq_set(struct cpr_thread *thread, u32 int_bits)
>> +{
>> + /* On CPR-hardened, interrupts are managed by and on firmware */
>> + if (thread->drv->desc->cpr_type == CTRL_TYPE_CPRH)
>> + return;
>> +
>> + cpr_write(thread, CPR3_REG_IRQ_EN, int_bits);
>> +}
>> +
>> +/**
>> + * cpr_ctl_enable() - Enable CPR thread
>> + * @thread: Structure holding CPR thread-specific parameters
>> + */
>> +static void cpr_ctl_enable(struct cpr_thread *thread)
>> +{
>> + if (thread->drv->enabled && !thread->restarting) {
>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>> + }
>> +}
>> +
>> +/**
>> + * cpr_ctl_disable() - Disable CPR thread
>> + * @thread: Structure holding CPR thread-specific parameters
>> + */
>> +static void cpr_ctl_disable(struct cpr_thread *thread)
>> +{
>> + const struct cpr_desc *desc = thread->drv->desc;
>> +
>> + if (desc->cpr_type != CTRL_TYPE_CPRH) {
>> + cpr_irq_set(thread, 0);
>> + cpr_irq_clr(thread);
>> + }
>> +
>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>> + CPR3_CPR_CTL_LOOP_EN_MASK, 0);
>> +}
>> +
>> +/**
>> + * cpr_ctl_is_enabled() - Check if thread is enabled
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Return: true if the CPR is enabled, false if it is disabled.
>> + */
>> +static bool cpr_ctl_is_enabled(struct cpr_thread *thread)
>> +{
>> + u32 reg_val;
>> +
>> + reg_val = cpr_read(thread, CPR3_REG_CPR_CTL);
>> + return reg_val & CPR3_CPR_CTL_LOOP_EN_MASK;
>> +}
>> +
>> +/**
>> + * cpr_check_any_thread_busy() - Check if HW is done processing
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Return: true if the CPR is busy, false if it is ready.
>> + */
>> +static bool cpr_check_any_thread_busy(struct cpr_thread *thread)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < thread->drv->desc->num_threads; i++)
>> + if (cpr_read(thread, CPR3_REG_RESULT0(i)) &
>> + CPR3_RESULT0_BUSY_MASK)
>> + return true;
>> +
>> + return false;
>> +}
>> +
>> +static void cpr_restart_worker(struct work_struct *work)
>> +{
>> + struct cpr_thread *thread = container_of(work, struct cpr_thread,
>> + restart_work);
>> + struct cpr_drv *drv = thread->drv;
>> + int i;
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + thread->restarting = true;
>> + cpr_ctl_disable(thread);
>> + disable_irq(drv->irq);
>> +
>> + mutex_unlock(&drv->lock);
>> +
>> + for (i = 0; i < 20; i++) {
>> + u32 cpr_status = cpr_read(thread, CPR3_REG_CPR_STATUS);
>> + u32 ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>> +
>> + if ((cpr_status & CPR3_CPR_STATUS_BUSY_MASK) &&
>> + !(ctl & CPR3_CPR_CTL_LOOP_EN_MASK))
>> + break;
>> +
>> + udelay(10);
>> + }
>> +
>> + cpr_irq_clr(thread);
>> +
>> + for (i = 0; i < 20; i++) {
>> + u32 status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>> +
>> + if (!(status & CPR3_IRQ_ALL))
>> + break;
>> + udelay(10);
>> + }
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + thread->restarting = false;
>> + enable_irq(drv->irq);
>> + cpr_ctl_enable(thread);
>> +
>> + mutex_unlock(&drv->lock);
>> +}
>> +
>> +/**
>> + * cpr_corner_restore() - Restore saved corner level
>> + * @thread: Structure holding CPR thread-specific parameters
>> + * @corner: Structure holding the saved corner level
>> + */
>> +static void cpr_corner_restore(struct cpr_thread *thread,
>> + struct corner *corner)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + struct fuse_corner *fuse = corner->fuse_corner;
>> + const struct cpr_thread_desc *tdesc = thread->desc;
>> + u32 ro_sel = fuse->ring_osc_idx;
>> +
>> + cpr_write(thread, CPR3_REG_GCNT(ro_sel), drv->gcnt);
>> +
>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid),
>> + CPR3_RO_MASK & ~BIT(ro_sel));
>> +
>> + cpr_write(thread, CPR3_REG_TARGET_QUOT(tdesc->hw_tid, ro_sel),
>> + fuse->quot - corner->quot_adjust);
>> +
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR4)
>> + cpr_masked_write(thread,
>> + CPR4_REG_CPR_MASK_THREAD(tdesc->hw_tid),
>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK, 0);
>> +
>> + thread->corner = corner;
>> + corner->last_uV = corner->uV;
>> +}
>> +
>> +/**
>> + * cpr_set_acc() - Set fuse level to the mem-acc
>> + * @drv: Main driver structure
>> + * @f: Fuse level
>> + */
>> +static void cpr_set_acc(struct cpr_drv *drv, int f)
>> +{
>> + const struct acc_desc *desc = drv->acc_desc;
>> + struct reg_sequence *s = desc->settings;
>> + int n = desc->num_regs_per_fuse;
>> +
>> + if (!s || f == drv->fuse_level_set)
>> + return;
>> +
>> + regmap_multi_reg_write(drv->tcsr, s + (n * f), n);
>> + drv->fuse_level_set = f;
>> +}
>> +
>> +/**
>> + * cpr_pre_voltage() - Actions to execute before setting voltage
>> + * @thread: Structure holding CPR thread-specific parameters
>> + * @dir: Enumeration for voltage change direction
>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>> + *
>> + * Return: Zero for success or negative number on errors.
>> + */
>> +static int cpr_pre_voltage(struct cpr_thread *thread,
>> + enum voltage_change_dir dir,
>> + int fuse_level)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> +
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3 &&
>> + drv->desc->pd_throttle_val)
>> + cpr_write(thread, CPR3_REG_PD_THROTTLE,
>> + drv->desc->pd_throttle_val);
>> +
>> + if (drv->tcsr && dir == DOWN)
>> + cpr_set_acc(drv, fuse_level);
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr_post_voltage() - Actions to execute after setting voltage
>> + * @thread: Structure holding CPR thread-specific parameters
>> + * @dir: Enumeration for voltage change direction
>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>> + *
>> + * Return: Zero for success or negative number on errors.
>> + */
>> +static int cpr_post_voltage(struct cpr_thread *thread,
>> + enum voltage_change_dir dir,
>> + int fuse_level)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> +
>> + if (drv->tcsr && dir == UP)
>> + cpr_set_acc(drv, fuse_level);
>> +
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3)
>> + cpr_write(thread, CPR3_REG_PD_THROTTLE, 0);
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr_commit_state() - Set the newly requested voltage
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>> + */
>> +static int cpr_commit_state(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + int min_uV = 0, max_uV = 0, new_uV = 0, fuse_level = 0;
>> + enum voltage_change_dir dir;
>> + u32 next_irqmask = 0;
>> + int ret, i;
>> +
>> + /* On CPRhardened, control states are managed in firmware */
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>> + return 0;
>> +
>> + for (i = 0; i < drv->desc->num_threads; i++) {
>> + struct cpr_thread *thread = &drv->threads[i];
>> +
>> + if (!thread->corner)
>> + continue;
>> +
>> + fuse_level = max(fuse_level,
>> + (int) (thread->corner->fuse_corner -
>> + &thread->fuse_corners[0]));
>> +
>> + max_uV = max(max_uV, thread->corner->max_uV);
>> + min_uV = max(min_uV, thread->corner->min_uV);
>> + new_uV = max(new_uV, thread->corner->last_uV);
>> + }
>> + dev_vdbg(drv->dev, "%s: new uV: %d, last uV: %d\n",
>> + __func__, new_uV, drv->last_uV);
>> +
>> + /*
>> + * Safety measure: if the voltage is out of the globally allowed
>> + * range, then go out and warn the user.
>> + * This should *never* happen.
>> + */
>> + if (new_uV > drv->desc->cpr_max_voltage ||
>> + new_uV < drv->desc->cpr_base_voltage) {
>> + dev_warn(drv->dev, "Voltage (%u uV) out of range.", new_uV);
>> + return -EINVAL;
>> + }
>> +
>> + if (new_uV == drv->last_uV || fuse_level == drv->fuse_level_set)
>> + goto out;
>> +
>> + if (fuse_level > drv->fuse_level_set)
>> + dir = UP;
>> + else
>> + dir = DOWN;
>> +
>> + ret = cpr_pre_voltage(thread, fuse_level, dir);
>> + if (ret)
>> + return ret;
>> +
>> + dev_vdbg(drv->dev, "setting voltage: %d\n", new_uV);
>> +
>> + ret = regulator_set_voltage(drv->vreg, new_uV, new_uV);
>> + if (ret) {
>> + dev_err_ratelimited(drv->dev, "failed to set voltage %d: %d\n", new_uV, ret);
>> + return ret;
>> + }
>> +
>> + ret = cpr_post_voltage(thread, fuse_level, dir);
>> + if (ret)
>> + return ret;
>> +
>> + drv->last_uV = new_uV;
>> +out:
>> + if (new_uV > min_uV)
>> + next_irqmask |= CPR3_IRQ_DOWN;
>> + if (new_uV < max_uV)
>> + next_irqmask |= CPR3_IRQ_UP;
>> +
>> + cpr_irq_set(thread, next_irqmask);
>> +
>> + return 0;
>> +}
>> +
>> +static unsigned int cpr_get_cur_perf_state(struct cpr_thread *thread)
>> +{
>> + return thread->corner ? thread->corner - thread->corners + 1 : 0;
>> +}
>> +
>> +/**
>> + * cpr_scale() - Calculate new voltage for the received direction
>> + * @thread: Structure holding CPR thread-specific parameters
>> + * @dir: Enumeration for voltage change direction
>> + *
>> + * The CPR scales one by one: this function calculates the new
>> + * voltage to set when a voltage-UP or voltage-DOWN request comes
>> + * and stores it into the per-thread structure that gets passed.
>> + */
>> +static void cpr_scale(struct cpr_thread *thread, enum voltage_change_dir dir)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + const struct cpr_thread_desc *tdesc = thread->desc;
>> + u32 val, error_steps;
>> + int last_uV, new_uV;
>> + struct corner *corner;
>> +
>> + if (dir != UP && dir != DOWN)
>> + return;
>> +
>> + corner = thread->corner;
>> + val = cpr_read(thread, CPR3_REG_RESULT0(tdesc->hw_tid));
>> + error_steps = val >> CPR3_RESULT0_ERROR_STEPS_SHIFT;
>> + error_steps &= CPR3_RESULT0_ERROR_STEPS_MASK;
>> +
>> + last_uV = corner->last_uV;
>> +
>> + if (dir == UP) {
>> + if (!(val & CPR3_RESULT0_STEP_UP_MASK))
>> + return;
>> +
>> + /* Calculate new voltage */
>> + new_uV = last_uV + drv->vreg_step;
>> + new_uV = min(new_uV, corner->max_uV);
>> +
>> + dev_vdbg(drv->dev, "[T%u] UP - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>> + thread->id, new_uV, last_uV,
>> + cpr_get_cur_perf_state(thread), error_steps);
>> + } else {
>> + if (!(val & CPR3_RESULT0_STEP_DN_MASK))
>> + return;
>> +
>> + /* Calculate new voltage */
>> + new_uV = last_uV - drv->vreg_step;
>> + new_uV = max(new_uV, corner->min_uV);
>> + dev_vdbg(drv->dev, "[T%u] DOWN - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>> + thread->id, new_uV, last_uV,
>> + cpr_get_cur_perf_state(thread), error_steps);
>> + }
>> + corner->last_uV = new_uV;
>> +}
>> +
>> +/**
>> + * cpr_irq_handler() - Handle CPR3/CPR4 status interrupts
>> + * @irq: Number of the interrupt
>> + * @dev: Pointer to the cpr_thread structure
>> + *
>> + * Handle the interrupts coming from non-hardened CPR HW as to get
>> + * an ok to scale voltages immediately, or to pass error status to
>> + * the hardware (either success/ACK or failure/NACK).
>> + *
>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>> + */
>> +static irqreturn_t cpr_irq_handler(int irq, void *dev)
>> +{
>> + struct cpr_thread *thread = dev;
>> + struct cpr_drv *drv = thread->drv;
>> + irqreturn_t ret = IRQ_HANDLED;
>> + int i, rc;
>> + enum voltage_change_dir dir = NO_CHANGE;
>> + u32 val;
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + val = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>> +
>> + dev_vdbg(drv->dev, "IRQ_STATUS = %#02x\n", val);
>> +
>> + if (!cpr_ctl_is_enabled(thread)) {
>> + dev_vdbg(drv->dev, "CPR is disabled\n");
>> + ret = IRQ_NONE;
>> + } else if (cpr_check_any_thread_busy(thread)) {
>> + cpr_irq_clr_nack(thread);
>> + dev_dbg(drv->dev, "CPR measurement is not ready\n");
>> + } else {
>> + /*
>> + * Following sequence of handling is as per each IRQ's
>> + * priority
>> + */
>> + if (val & CPR3_IRQ_UP)
>> + dir = UP;
>> + else if (val & CPR3_IRQ_DOWN)
>> + dir = DOWN;
>> +
>> + if (dir != NO_CHANGE) {
>> + for (i = 0; i < drv->desc->num_threads; i++) {
>> + thread = &drv->threads[i];
>> + cpr_scale(thread, dir);
>> + }
>> +
>> + rc = cpr_commit_state(thread);
>> + if (rc)
>> + cpr_irq_clr_nack(thread);
>> + else
>> + cpr_irq_clr_ack(thread);
>> + } else if (val & CPR3_IRQ_MID) {
>> + dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n");
>> + } else {
>> + dev_warn(drv->dev, "IRQ occurred for unknown flag (%#08x)\n", val);
>> + schedule_work(&thread->restart_work);
>> + }
>> + }
>> +
>> + mutex_unlock(&drv->lock);
>> +
>> + return ret;
>> +}
>> +
>> +static int cpr_switch(struct cpr_drv *drv)
>> +{
>> + int i, ret;
>> + bool enabled = false;
>> +
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>> + return 0;
>> +
>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>> + enabled = drv->threads[i].enabled;
>> +
>> + dev_vdbg(drv->dev, "%s: enabled = %d\n", __func__, enabled);
>> +
>> + if (enabled == drv->enabled)
>> + return 0;
>> +
>> + if (enabled) {
>> + ret = regulator_enable(drv->vreg);
>> + if (ret)
>> + return ret;
>> +
>> + drv->enabled = enabled;
>> +
>> + for (i = 0; i < drv->desc->num_threads; i++)
>> + if (drv->threads[i].corner)
>> + break;
>> +
>> + if (i < drv->desc->num_threads) {
>> + cpr_irq_clr(&drv->threads[i]);
>> +
>> + cpr_commit_state(&drv->threads[i]);
>> + cpr_ctl_enable(&drv->threads[i]);
>> + }
>> + } else {
>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>> + cpr_ctl_disable(&drv->threads[i]);
>> +
>> + drv->enabled = enabled;
>> +
>> + ret = regulator_disable(drv->vreg);
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr_enable() - Enables a CPR thread
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Return: Zero for success or negative number on errors.
>> + */
>> +static int cpr_enable(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + int ret;
>> +
>> + dev_dbg(drv->dev, "Enabling thread %d\n", thread->id);
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + thread->enabled = true;
>> + ret = cpr_switch(thread->drv);
>> +
>> + mutex_unlock(&drv->lock);
>> +
>> + return ret;
>> +}
>> +
>> +/**
>> + * cpr_disable() - Disables a CPR thread
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Return: Zero for success or negative number on errors.
>> + */
>> +static int cpr_disable(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + int ret;
>> +
>> + dev_dbg(drv->dev, "Disabling thread %d\n", thread->id);
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + thread->enabled = false;
>> + ret = cpr_switch(thread->drv);
>> +
>> + mutex_unlock(&drv->lock);
>> +
>> + return ret;
>> +}
>> +
>> +/**
>> + * cpr_configure() - Configure main HW parameters
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * This function configures the main CPR hardware parameters, such as
>> + * internal timers (and delays), sensor ownerships, activates and/or
>> + * deactivates cpr-threads and others, as one sequence for all of the
>> + * versions supported in this driver. By design, the function may
>> + * return a success earlier if the sequence for "a previous version"
>> + * has ended.
>> + *
>> + * Context: The CPR must be clocked before calling this function!
>> + *
>> + * Return: Zero for success or negative number on errors.
>> + */
>> +static int cpr_configure(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + const struct cpr_desc *desc = drv->desc;
>> + const struct cpr_thread_desc *tdesc = thread->desc;
>> + u32 val;
>> + int i;
>> +
>> + /* Disable interrupt and CPR */
>> + cpr_irq_set(thread, 0);
>> + cpr_write(thread, CPR3_REG_CPR_CTL, 0);
>> +
>> + /* Init and save gcnt */
>> + drv->gcnt = drv->ref_clk_khz * desc->gcnt_us;
>> + do_div(drv->gcnt, 1000);
>> +
>> + /* Program the delay count for the timer */
>> + val = drv->ref_clk_khz * desc->timer_delay_us;
>> + do_div(val, 1000);
>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>> + cpr_write(thread, CPR3_REG_CPR_TIMER_MID_CONT, val);
>> +
>> + val = drv->ref_clk_khz * desc->timer_updn_delay_us;
>> + do_div(val, 1000);
>> + cpr_write(thread, CPR3_REG_CPR_TIMER_UP_DN_CONT, val);
>> + } else {
>> + cpr_write(thread, CPR3_REG_CPR_TIMER_AUTO_CONT, val);
>> + }
>> + dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val,
>> + desc->timer_delay_us);
>> +
>> + /* Program the control register */
>> + val = desc->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT;
>> + val |= desc->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT;
>> + val |= desc->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT;
>> + cpr_write(thread, CPR3_REG_CPR_CTL, val);
>> +
>> + /* Configure CPR default step quotients */
>> + val = tdesc->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT;
>> + val |= tdesc->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT;
>> +
>> + cpr_write(thread, CPR3_REG_CPR_STEP_QUOT, val);
>> +
>> + /*
>> + * Configure the CPR sensor ownership always on thread 0
>> + * TODO: SDM845 has different ownership for sensors!!
>> + */
>> + for (i = tdesc->sensor_range_start; i < tdesc->sensor_range_end; i++)
>> + cpr_write(thread, CPR3_REG_SENSOR_OWNER(i), 0);
>> +
>> + /* Program Consecutive Up & Down */
>> + val = desc->timer_cons_up << CPR3_THRESH_CONS_UP_SHIFT;
>> + val |= desc->timer_cons_down << CPR3_THRESH_CONS_DOWN_SHIFT;
>> + val |= desc->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT;
>> + val |= desc->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT;
>> + cpr_write(thread, CPR3_REG_THRESH(tdesc->hw_tid), val);
>> +
>> + /* Mask all ring oscillators for all threads initially */
>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), CPR3_RO_MASK);
>> +
>> + /* HW Closed-loop control */
>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>> + cpr_write(thread, CPR3_REG_HW_CLOSED_LOOP_DISABLED,
>> + !desc->hw_closed_loop_en);
>> + } else {
>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN,
>> + desc->hw_closed_loop_en ?
>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN : 0);
>> + }
>> +
>> + /* Additional configuration for CPR4 and beyond */
>> + if (desc->cpr_type < CTRL_TYPE_CPR4)
>> + return 0;
>> +
>> + /* Disable threads initially only on non-hardened CPR4 */
>> + if (desc->cpr_type == CTRL_TYPE_CPR4)
>> + cpr_masked_write(thread, CPR4_REG_CPR_MASK_THREAD(1),
>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
>> +
>> + if (tdesc->hw_tid > 0)
>> + cpr_masked_write(thread, CPR4_REG_MISC,
>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN,
>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN);
>> +
>> + val = drv->vreg_step;
>> + do_div(val, 1000);
>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>> + CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK,
>> + val << CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT);
>> +
>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
>> + desc->vreg_step_down_limit <<
>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT);
>> +
>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
>> + desc->vreg_step_up_limit <<
>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT);
>> +
>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN,
>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN);
>> +
>> + if (tdesc->hw_tid > 0)
>> + cpr_masked_write(thread, CPR4_REG_CPR_TIMER_CLAMP,
>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
>> +
>> + /* Settling timer to account for one VDD supply step */
>> + if (desc->vdd_settle_time_us > 0) {
>> + u32 m = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK;
>> + u32 s = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT;
>> +
>> + cpr_masked_write(thread, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
>> + m, desc->vdd_settle_time_us << s);
>> + }
>> +
>> + /* Additional configuration for CPR-hardened */
>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>> + return 0;
>> +
>> + /* Settling timer to account for one corner-switch request */
>> + if (desc->corner_settle_time_us > 0)
>> + cpr_masked_write(thread, drv->reg_ctl,
>> + CPRH_CTL_MODE_SWITCH_DELAY_MASK,
>> + desc->corner_settle_time_us <<
>> + CPRH_CTL_MODE_SWITCH_DELAY_SHIFT);
>> +
>> + /* Base voltage and multiplier values for CPRh internal calculations */
>> + cpr_masked_write(thread, drv->reg_ctl,
>> + CPRH_CTL_BASE_VOLTAGE_MASK,
>> + (DIV_ROUND_UP(desc->cpr_base_voltage,
>> + drv->vreg_step) <<
>> + CPRH_CTL_BASE_VOLTAGE_SHIFT));
>> +
>> + cpr_masked_write(thread, drv->reg_ctl,
>> + CPRH_CTL_VOLTAGE_MULTIPLIER_MASK,
>> + DIV_ROUND_UP(drv->vreg_step, 1000) <<
>> + CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT);
>> +
>> + return 0;
>> +}
>> +
>> +static int cprh_dummy_set_performance_state(struct generic_pm_domain *domain,
>> + unsigned int state)
>> +{
>> + return 0;
>> +}
>> +
>> +static int cpr_set_performance_state(struct generic_pm_domain *domain,
>> + unsigned int state)
>> +{
>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>> + struct cpr_drv *drv = thread->drv;
>> + struct corner *corner, *end;
>> + int ret = 0;
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + dev_dbg(drv->dev, "setting perf state: %u (prev state: %u thread: %u)\n",
>> + state, cpr_get_cur_perf_state(thread), thread->id);
>> +
>> + /*
>> + * Determine new corner we're going to.
>> + * Remove one since lowest performance state is 1.
>> + */
>> + corner = thread->corners + state - 1;
>> + end = &thread->corners[thread->num_corners - 1];
>> + if (corner > end || corner < thread->corners) {
>> + ret = -EINVAL;
>> + goto unlock;
>> + }
>> +
>> + cpr_ctl_disable(thread);
>> +
>> + cpr_irq_clr(thread);
>> + if (thread->corner != corner)
>> + cpr_corner_restore(thread, corner);
>> +
>> + ret = cpr_commit_state(thread);
>> + if (ret)
>> + goto unlock;
>> +
>> + cpr_ctl_enable(thread);
>> +unlock:
>> + mutex_unlock(&drv->lock);
>> +
>> + dev_dbg(drv->dev, "set perf state %u on thread %u\n", state, thread->id);
>> +
>> + return ret;
>> +}
>> +
>> +/**
>> + * cpr3_adjust_quot - Adjust the closed-loop quotients
>> + * @ring_osc_factor: Ring oscillator adjustment factor
>> + * @volt_closed_loop: Closed-loop voltage adjustment factor
>> + *
>> + * Calculates the quotient adjustment factor based on closed-loop
>> + * quotients and ring oscillator factor.
>> + *
>> + * Return: Adjusted quotient
>> + */
>> +static int cpr3_adjust_quot(int ring_osc_factor, int volt_closed_loop)
>> +{
>> + s64 temp;
>> +
>> + if (ring_osc_factor == 0 || volt_closed_loop == 0)
>> + return 0;
>> +
>> + temp = (s64)(ring_osc_factor * volt_closed_loop);
>> + return (int)div_s64(temp, 1000000);
>> +}
>> +
>> +/**
>> + * cpr_fuse_corner_init() - Calculate fuse corner table
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * This function populates the fuse corners table by reading the
>> + * values from the fuses, eventually adjusting them with a fixed
>> + * per-corner offset and doing basic checks about them being
>> + * supported by the regulator that is assigned to this CPR - if
>> + * it is available (on CPR-Hardened, there is no usable vreg, as
>> + * that is protected by the hypervisor).
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr_fuse_corner_init(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + const struct cpr_thread_desc *desc = thread->desc;
>> + const struct cpr_fuse *cpr_fuse = thread->cpr_fuses;
>> + struct fuse_corner_data *fdata;
>> + struct fuse_corner *fuse, *prev_fuse, *end;
>> + int i, ret;
>> +
>> + /* Populate fuse_corner members */
>> + fuse = thread->fuse_corners;
>> + prev_fuse = &fuse[0];
>> + end = &fuse[desc->num_fuse_corners - 1];
>> + fdata = desc->fuse_corner_data;
>> +
>> + for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
>> + int factor = cpr_get_ro_factor(desc, i, fuse->ring_osc_idx);
>> +
>> + ret = cpr_populate_fuse_common(drv->dev, fdata, cpr_fuse,
>> + fuse, drv->vreg_step,
>> + desc->init_voltage_width,
>> + desc->init_voltage_step);
>> + if (ret)
>> + return ret;
>> +
>> + /*
>> + * Adjust the fuse quot with per-fuse-corner closed-loop
>> + * voltage adjustment parameters.
>> + */
>> + fuse->quot += cpr3_adjust_quot(factor, fdata->volt_cloop_adjust);
>> +
>> + /* CPRh: no regulator access... */
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>> + goto skip_pvs_restrict;
>> +
>> + /* Re-check if corner voltage range is supported by regulator */
>> + ret = cpr_check_vreg_constraints(drv->dev, drv->vreg, fuse);
>> + if (ret)
>> + return ret;
>> +
>> +skip_pvs_restrict:
>> + if (fuse->uV < prev_fuse->uV)
>> + fuse->uV = prev_fuse->uV;
>> + prev_fuse = fuse;
>> + dev_dbg(drv->dev, "fuse corner %d: [%d %d %d] RO%hhu quot %d\n",
>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>> + fuse->ring_osc_idx, fuse->quot);
>> +
>> + /* Check if constraints are valid */
>> + if (fuse->uV < fuse->min_uV || fuse->uV > fuse->max_uV) {
>> + dev_err(drv->dev, "fuse corner %d: Bad voltage range.\n", i);
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void cpr3_restrict_corner(struct corner *corner, int threshold,
>> + int hysteresis, int step)
>> +{
>> + if (threshold > corner->min_uV && threshold <= corner->max_uV) {
>> + if (corner->uV >= threshold) {
>> + corner->min_uV = max(corner->min_uV,
>> + threshold - hysteresis);
>> + if (corner->min_uV > corner->uV)
>> + corner->uV = corner->min_uV;
>> + } else {
>> + corner->max_uV = threshold;
>> + corner->max_uV -= step;
>> + }
>> + }
>> +}
>> +
>> +/*
>> + * cprh_corner_adjust_opps() - Set voltage on each CPU OPP table entry
>> + *
>> + * On CPR-Hardened, the voltage level is controlled internally through
>> + * the OSM hardware: in order to initialize the latter, we have to
>> + * communicate the voltage to its driver, so that it will be able to
>> + * write the right parameters (as they have to be set both on the CPRh
>> + * and on the OSM) on it.
>> + * This function is called only for CPRh.
>> + *
>> + * Return: Zero for success, negative number for error.
>> + */
>> +static int cprh_corner_adjust_opps(struct cpr_thread *thread)
>> +{
>> + struct corner *corner = thread->corners;
>> + struct cpr_drv *drv = thread->drv;
>> + int i, ret;
>> +
>> + for (i = 0; i < thread->num_corners; i++) {
>> + ret = dev_pm_opp_adjust_voltage(thread->attached_cpu_dev,
>> + corner[i].freq,
>> + corner[i].uV,
>> + corner[i].min_uV,
>> + corner[i].max_uV);
>> + if (ret)
>> + break;
>> +
>> + dev_dbg(drv->dev, "OPP voltage adjusted for %lu kHz, %d uV\n",
>> + corner[i].freq, corner[i].uV);
>> + }
>> +
>> + /* If we couldn't adjust voltage for all corners, something went wrong */
>> + if (i < thread->num_corners)
>> + return -EINVAL;
>> +
>> + return ret;
>> +}
>> +
>> +/**
>> + * cpr3_corner_init() - Calculate and set-up corners for the CPR HW
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * This function calculates all the corner parameters by comparing
>> + * and interpolating the values read from the various set-points
>> + * read from the fuses (also called "fuse corners") to generate and
>> + * program to the CPR a lookup table that describes each voltage
>> + * step, mapped to a performance level (or corner number).
>> + *
>> + * It also programs other essential parameters on the CPR and - if
>> + * we are dealing with CPR-Hardened, it will also enable the internal
>> + * interface between the Operating State Manager (OSM) and the CPRh
>> + * in order to achieve CPU DVFS.
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr3_corner_init(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + const struct cpr_desc *desc = drv->desc;
>> + const struct cpr_thread_desc *tdesc = thread->desc;
>> + const struct cpr_fuse *fuses = thread->cpr_fuses;
>> + int i, ret, total_corners, extra_corners, level, scaling = 0;
>> + unsigned int fnum, fc;
>> + const char *quot_offset;
>> + const struct fuse_corner_data *fdata;
>> + struct fuse_corner *fuse, *prev_fuse;
>> + struct corner *corner, *prev_corner, *end;
>> + struct corner_data *cdata;
>> + struct dev_pm_opp *opp;
>> + unsigned long freq;
>> + u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
>> +
>> + corner = thread->corners;
>> + prev_corner = &thread->corners[0];
>> + end = &corner[thread->num_corners - 1];
>> +
>> + cdata = devm_kcalloc(drv->dev, thread->num_corners + drv->extra_corners,
>> + sizeof(struct corner_data), GFP_KERNEL);
>> + if (!cdata)
>> + return -ENOMEM;
>> +
>> + for (level = 1; level <= thread->num_corners; level++) {
>> + opp = dev_pm_opp_find_level_exact(&thread->pd.dev, level);
>> + if (IS_ERR(opp))
>> + return -EINVAL;
>> +
>> + /*
>> + * If there is only one specified qcom,opp-fuse-level, then
>> + * it is assumed that this only one is global and valid for
>> + * all IDs, so try to get the specific one but, on failure,
>> + * go for the global one.
>> + */
>> + fc = cpr_get_fuse_corner(opp, thread->id);
>> + if (fc == 0) {
>> + fc = cpr_get_fuse_corner(opp, 0);
>> + if (fc == 0) {
>> + dev_err(drv->dev, "qcom,opp-fuse-level is missing!\n");
>> + dev_pm_opp_put(opp);
>> + return -EINVAL;
>> + }
>> + }
>> + fnum = fc - 1;
>> +
>> + freq = cpr_get_opp_hz_for_req(opp, thread->attached_cpu_dev);
>> + if (!freq) {
>> + thread->num_corners = max(level - 1, 0);
>> + end = &thread->corners[thread->num_corners - 1];
>> + break;
>> + }
>> +
>> + /*
>> + * If any post-vadj (open/closed loop) is not specified, then
>> + * it's zero, meaning that it is not required for this corner.
>> + */
>> + cpr_get_corner_post_vadj(opp, thread->id,
>> + &cdata[level - 1].oloop_vadj,
>> + &cdata[level - 1].cloop_vadj);
>> + cdata[level - 1].fuse_corner = fnum;
>> + cdata[level - 1].freq = freq;
>> +
>> + fuse = &thread->fuse_corners[fnum];
>> + dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n",
>> + freq, dev_pm_opp_get_level(opp) - 1, fnum);
>> + if (freq > fuse->max_freq)
>> + fuse->max_freq = freq;
>> + dev_pm_opp_put(opp);
>> +
>> + /*
>> + * Make sure that the frequencies in the table are in ascending
>> + * order, as this is critical for the algorithm to work.
>> + */
>> + if (cdata[level - 2].freq > freq) {
>> + dev_err(drv->dev, "Frequency table not in ascending order.\n");
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + if (thread->num_corners < 2) {
>> + dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
>> + return -EINVAL;
>> + }
>> +
>> + /*
>> + * Get the quotient adjustment scaling factor, according to:
>> + *
>> + * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
>> + * / (freq(corner_N) - freq(corner_N-1)), max_factor)
>> + *
>> + * QUOT(corner_N): quotient read from fuse for fuse corner N
>> + * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1)
>> + * freq(corner_N): max frequency in MHz supported by fuse corner N
>> + * freq(corner_N-1): max frequency in MHz supported by fuse corner
>> + * (N - 1)
>> + *
>> + * Then walk through the corners mapped to each fuse corner
>> + * and calculate the quotient adjustment for each one using the
>> + * following formula:
>> + *
>> + * quot_adjust = (freq_max - freq_corner) * scaling / 1000
>> + *
>> + * freq_max: max frequency in MHz supported by the fuse corner
>> + * freq_corner: frequency in MHz corresponding to the corner
>> + * scaling: calculated from above equation
>> + *
>> + *
>> + * + +
>> + * | v |
>> + * q | f c o | f c
>> + * u | c l | c
>> + * o | f t | f
>> + * t | c a | c
>> + * | c f g | c f
>> + * | e |
>> + * +--------------- +----------------
>> + * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
>> + * corner corner
>> + *
>> + * c = corner
>> + * f = fuse corner
>> + *
>> + */
>> + for (i = 0; corner <= end; corner++, i++) {
>> + unsigned long freq_diff_mhz;
>> + int ro_fac, vadj, prev_quot;
>> +
>> + fnum = cdata[i].fuse_corner;
>> + fdata = &tdesc->fuse_corner_data[fnum];
>> + quot_offset = fuses[fnum].quotient_offset;
>> + fuse = &thread->fuse_corners[fnum];
>> + ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
>> + if (fnum)
>> + prev_fuse = &thread->fuse_corners[fnum - 1];
>> + else
>> + prev_fuse = NULL;
>> +
>> + corner->fuse_corner = fuse;
>> + corner->freq = cdata[i].freq;
>> + corner->uV = fuse->uV;
>> +
>> + if (prev_fuse) {
>> + if (prev_fuse->ring_osc_idx == fuse->ring_osc_idx)
>> + quot_offset = NULL;
>> +
>> + scaling = cpr_calculate_scaling(drv->dev, quot_offset,
>> + fdata, corner);
>> + if (scaling < 0)
>> + return scaling;
>> +
>> + freq_diff_mhz = fuse->max_freq - corner->freq;
>> + do_div(freq_diff_mhz, 1000000); /* now in MHz */
>> +
>> + corner->quot_adjust = scaling * freq_diff_mhz;
>> + do_div(corner->quot_adjust, 1000);
>> +
>> + /* Fine-tune QUOT (closed-loop) based on fixed values */
>> + ro_fac = cpr_get_ro_factor(tdesc, fnum, fuse->ring_osc_idx);
>> + vadj = cdata[i].cloop_vadj;
>> + corner->quot_adjust -= cpr3_adjust_quot(ro_fac, vadj);
>> + dev_vdbg(drv->dev, "Quot fine-tuning to %d for post-vadj=%d\n",
>> + corner->quot_adjust, vadj);
>> +
>> + /*
>> + * Make sure that we scale (up) monotonically.
>> + * P.S.: Fuse quots can never be descending.
>> + */
>> + prev_quot = prev_corner->fuse_corner->quot;
>> + prev_quot -= prev_corner->quot_adjust;
>> + if (fuse->quot - corner->quot_adjust < prev_quot) {
>> + int new_adj = prev_corner->fuse_corner->quot;
>> +
>> + new_adj -= fuse->quot;
>> + dev_vdbg(drv->dev, "Monotonic increase forced: %d->%d\n",
>> + corner->quot_adjust, new_adj);
>> + corner->quot_adjust = new_adj;
>> + }
>> +
>> + corner->uV = cpr_interpolate(corner,
>> + drv->vreg_step, fdata);
>> + }
>> + /* Negative fuse quotients are nonsense. */
>> + if (fuse->quot < corner->quot_adjust)
>> + return -EINVAL;
>> +
>> + min_quotient = min(min_quotient,
>> + (u32)(fuse->quot - corner->quot_adjust));
>> +
>> + /* Fine-tune voltages (open-loop) based on fixed values */
>> + corner->uV += cdata[i].oloop_vadj;
>> + dev_dbg(drv->dev, "Voltage fine-tuning to %d for post-vadj=%d\n",
>> + corner->uV, cdata[i].oloop_vadj);
>> +
>> + corner->max_uV = fuse->max_uV;
>> + corner->min_uV = fuse->min_uV;
>> + corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV);
>> + dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d %d]\n",
>> + corner->min_uV, corner->uV, corner->max_uV);
>> +
>> + /* Make sure that we scale monotonically here, too. */
>> + if (corner->uV < prev_corner->uV)
>> + corner->uV = prev_corner->uV;
>> +
>> + corner->last_uV = corner->uV;
>> +
>> + /* Reduce the ceiling voltage if needed */
>> + if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV)
>> + corner->max_uV = corner->uV;
>> + else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV)
>> + corner->max_uV = max(corner->min_uV, fuse->uV);
>> +
>> + corner->min_uV = max(corner->max_uV - fdata->range_uV,
>> + corner->min_uV);
>> +
>> + /*
>> + * Adjust per-corner floor and ceiling voltages so that
>> + * they do not overlap the memory Array Power Mux (APM)
>> + * nor the Memory Accelerator (MEM-ACC) threshold voltages.
>> + */
>> + if (desc->apm_threshold)
>> + cpr3_restrict_corner(corner, desc->apm_threshold,
>> + desc->apm_hysteresis,
>> + drv->vreg_step);
>> + if (desc->mem_acc_threshold)
>> + cpr3_restrict_corner(corner, desc->mem_acc_threshold,
>> + 0, drv->vreg_step);
>> +
>> + prev_corner = corner;
>> + dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d quot %d\n", i,
>> + corner->min_uV, corner->uV, corner->max_uV, scaling,
>> + fuse->quot - corner->quot_adjust);
>> + }
>> +
>> + /* Additional setup for CPRh only */
>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>> + return 0;
>> +
>> + /* If the OPPs can't be adjusted, programming the CPRh is useless */
>> + ret = cprh_corner_adjust_opps(thread);
>> + if (ret) {
>> + dev_err(drv->dev, "Cannot adjust CPU OPP voltages: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + total_corners = thread->num_corners;
>> + extra_corners = drv->extra_corners;
>> +
>> + /* If the APM extra corner exists, add it now. */
>> + if (desc->apm_crossover && desc->apm_threshold && extra_corners) {
>> + /* Program the APM crossover corner on the CPR-Hardened */
>> + thread->corners[total_corners].uV = desc->apm_crossover;
>> + thread->corners[total_corners].min_uV = desc->apm_crossover;
>> + thread->corners[total_corners].max_uV = desc->apm_crossover;
>> + thread->corners[total_corners].is_open_loop = true;
>> +
>> + /*
>> + * We have calculated the APM parameters for this clock plan:
>> + * make the APM *threshold* available to external callers.
>> + * The crossover is used only internally in the CPR.
>> + */
>> + thread->ext_data.apm_threshold_uV = desc->apm_threshold;
>> +
>> + dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] Open-Loop\n",
>> + total_corners, desc->apm_crossover,
>> + desc->apm_crossover, desc->apm_crossover);
>> +
>> + total_corners++;
>> + extra_corners--;
>> + }
>> +
>> + if (desc->mem_acc_threshold && extra_corners) {
>> + /* Program the Memory Accelerator threshold corner to CPRh */
>> + thread->corners[total_corners].uV = desc->mem_acc_threshold;
>> + thread->corners[total_corners].min_uV = desc->mem_acc_threshold;
>> + thread->corners[total_corners].max_uV = desc->mem_acc_threshold;
>> + thread->corners[total_corners].is_open_loop = true;
>> +
>> + /*
>> + * We have calculated a mem-acc threshold for this clock plan:
>> + * make it available to external callers.
>> + */
>> + thread->ext_data.mem_acc_threshold_uV = desc->mem_acc_threshold;
>> +
>> + dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] Open-Loop\n",
>> + total_corners, desc->mem_acc_threshold,
>> + desc->mem_acc_threshold, desc->mem_acc_threshold);
>> +
>> + total_corners++;
>> + extra_corners--;
>> + }
>> +
>> + /*
>> + * If there are any extra corners left, it means that even though we
>> + * expect to fill in both APM and MEM-ACC crossovers, one couldn't
>> + * satisfy requirements, which means that the specified parameters
>> + * are wrong: in this case, inform the user and bail out, otherwise
>> + * if we go on writing the (invalid) table to the CPR-Hardened, the
>> + * hardware (in this case, the CPU) will surely freeze and crash.
>> + */
>> + if (unlikely(extra_corners)) {
>> + dev_err(drv->dev, "APM/MEM-ACC corners: bad parameters.\n");
>> + return -EINVAL;
>> + }
>> + /* Reassign extra_corners, as we have to exclude delta_quot for them */
>> + extra_corners = drv->extra_corners;
>> +
>> + /* Disable the interface between OSM and CPRh */
>> + cpr_masked_write(thread, drv->reg_ctl,
>> + CPRH_CTL_OSM_ENABLED, 0);
>> +
>> + /* Program the GCNT before unmasking ring oscillator(s) */
>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>> + if (!(ring_osc_mask & BIT(i))) {
>> + cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
>> + dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, drv->gcnt);
>> + }
>> + }
>> +
>> + /*
>> + * Unmask the ring oscillator(s) that we're going to use: it seems
>> + * to be mandatory to do this *before* sending the rest of the
>> + * CPRhardened specific configuration.
>> + */
>> + dev_dbg(drv->dev, "Unmasking ring oscillators with mask 0x%x\n", ring_osc_mask);
>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), ring_osc_mask);
>> +
>> + /* Setup minimum quotients for ring oscillators */
>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>> + u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, i);
>> + u32 tgt_quot_val = 0;
>> +
>> + if (!(ring_osc_mask & BIT(i)))
>> + tgt_quot_val = min_quotient;
>> +
>> + cpr_write(thread, tgt_quot_reg, tgt_quot_val);
>> + dev_vdbg(drv->dev, "Programmed min quotient %u for Ring Oscillator %d\n",
>> + tgt_quot_val, tgt_quot_reg);
>> + }
>> +
>> + for (i = 0; i < total_corners; i++) {
>> + int volt_oloop_steps, volt_floor_steps, delta_quot_steps;
>> + int ring_osc;
>> + u32 val;
>> +
>> + fnum = cdata[i].fuse_corner;
>> + fuse = &thread->fuse_corners[fnum];
>> +
>> + val = thread->corners[i].uV - desc->cpr_base_voltage;
>> + volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
>> +
>> + val = thread->corners[i].min_uV - desc->cpr_base_voltage;
>> + volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
>> +
>> + /*
>> + * If we are accessing corners that are not used as
>> + * an active DCVS set-point, then always select RO 0
>> + * and zero out the delta quotient.
>> + */
>> + if (i >= thread->num_corners) {
>> + ring_osc = 0;
>> + delta_quot_steps = 0;
>> + } else {
>> + ring_osc = fuse->ring_osc_idx;
>> + val = fuse->quot - thread->corners[i].quot_adjust;
>> + val -= min_quotient;
>> + delta_quot_steps = DIV_ROUND_UP(val,
>> + CPRH_DELTA_QUOT_STEP_FACTOR);
>> + }
>> +
>> + if (volt_oloop_steps > CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE ||
>> + volt_floor_steps > CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
>> + delta_quot_steps > CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
>> + dev_err(drv->dev, "Invalid cfg: oloop=%d, floor=%d, delta=%d\n",
>> + volt_oloop_steps, volt_floor_steps,
>> + delta_quot_steps);
>> + return -EINVAL;
>> + }
>> + /* Green light: Go, Go, Go! */
>> +
>> + /* Set number of open-loop steps */
>> + val = volt_oloop_steps << CPRH_CORNER_INIT_VOLTAGE_SHIFT;
>> + val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
>> +
>> + /* Set number of floor voltage steps */
>> + val |= (volt_floor_steps << CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
>> + CPRH_CORNER_FLOOR_VOLTAGE_MASK;
>> +
>> + /* Set number of target quotient delta steps */
>> + val |= (delta_quot_steps << CPRH_CORNER_QUOT_DELTA_SHIFT) &
>> + CPRH_CORNER_QUOT_DELTA_MASK;
>> +
>> + /* Select ring oscillator for this corner */
>> + val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
>> + CPRH_CORNER_RO_SEL_MASK;
>> +
>> + /* Open loop corner is usually APM/ACC crossover */
>> + if (thread->corners[i].is_open_loop) {
>> + dev_dbg(drv->dev, "Disabling Closed-Loop on corner %d\n", i);
>> + val |= CPRH_CORNER_CPR_CL_DISABLE;
>> + }
>> + cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, i), val);
>> +
>> + dev_dbg(drv->dev, "steps [%d]: open-loop %d, floor %d, delta_quot %d\n",
>> + i, volt_oloop_steps, volt_floor_steps,
>> + delta_quot_steps);
>> + }
>> +
>> + /* YAY! Setup is done! Enable the internal loop to start CPR. */
>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>> +
>> + /*
>> + * All the writes are going through before enabling internal
>> + * communication between the OSM and the CPRh controllers
>> + * because we are never using relaxed accessors, but should
>> + * we use them, it would be critical to issue a barrier here,
>> + * otherwise there is a high risk of hardware lockups due to
>> + * under-voltage for the selected CPU clock.
>> + *
>> + * Please note that the CPR-hardened gets set-up in Linux but
>> + * then gets actually used in firmware (and only by the OSM);
>> + * after handing it off we will have no more control on it.
>> + */
>> +
>> + /* Enable the interface between OSM and CPRh */
>> + cpr_masked_write(thread, drv->reg_ctl,
>> + CPRH_CTL_OSM_ENABLED,
>> + CPRH_CTL_OSM_ENABLED);
>> +
>> + /* On success, free cdata manually */
>> + devm_kfree(drv->dev, cdata);
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr3_init_parameters() - Initialize CPR global parameters
>> + * @drv: Main driver structure
>> + *
>> + * Initial "integrity" checks and setup for the thread-independent parameters.
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr3_init_parameters(struct cpr_drv *drv)
>> +{
>> + const struct cpr_desc *desc = drv->desc;
>> + struct clk *clk;
>> +
>> + clk = devm_clk_get(drv->dev, "ref");
>> + if (IS_ERR(clk))
>> + return PTR_ERR(clk);
>> +
>> + drv->ref_clk_khz = clk_get_rate(clk);
>> + do_div(drv->ref_clk_khz, 1000);
>> +
>> + /* On CPRh this clock is not always-on... */
>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>> + clk_prepare_enable(clk);
>> + else
>> + devm_clk_put(drv->dev, clk);
>> +
>> + if (desc->timer_cons_up > CPR3_THRESH_CONS_UP_MASK ||
>> + desc->timer_cons_down > CPR3_THRESH_CONS_DOWN_MASK ||
>> + desc->up_threshold > CPR3_THRESH_UP_THRESH_MASK ||
>> + desc->down_threshold > CPR3_THRESH_DOWN_THRESH_MASK ||
>> + desc->idle_clocks > CPR3_CPR_CTL_IDLE_CLOCKS_MASK ||
>> + desc->count_mode > CPR3_CPR_CTL_COUNT_MODE_MASK ||
>> + desc->count_repeat > CPR3_CPR_CTL_COUNT_REPEAT_MASK)
>> + return -EINVAL;
>> +
>> + /*
>> + * Read the CPR version register only from CPR3 onwards:
>> + * this is needed to get the additional register offsets.
>> + *
>> + * Note: When threaded, even if multi-controller, there
>> + * is no chance to have different versions at the
>> + * same time in the same domain, so it is safe to
>> + * check this only on the first controller/thread.
>> + */
>> + drv->cpr_hw_rev = cpr_read(&drv->threads[0],
>> + CPR3_REG_CPR_VERSION);
>> + dev_dbg(drv->dev, "CPR hardware revision: 0x%x\n", drv->cpr_hw_rev);
>> +
>> + if (drv->cpr_hw_rev >= CPRH_CPR_VERSION_4P5) {
>> + drv->reg_corner = 0x3500;
>> + drv->reg_corner_tid = 0xa0;
>> + drv->reg_ctl = 0x3a80;
>> + drv->reg_status = 0x3a84;
>> + } else {
>> + drv->reg_corner = 0x3a00;
>> + drv->reg_corner_tid = 0;
>> + drv->reg_ctl = 0x3aa0;
>> + drv->reg_status = 0x3aa4;
>> + }
>> +
>> + dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n",
>> + desc->up_threshold, desc->down_threshold);
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr3_find_initial_corner() - Finds boot-up p-state and enables CPR
>> + * @thread: Structure holding CPR thread-specific parameters
>> + *
>> + * Differently from CPRv1, from CPRv3 onwards when we successfully find
>> + * the target boot-up performance state, we must refresh the HW
>> + * immediately to guarantee system stability and to avoid overheating
>> + * during the boot process, thing that would more likely happen without
>> + * this driver doing its job.
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr3_find_initial_corner(struct cpr_thread *thread)
>> +{
>> + struct cpr_drv *drv = thread->drv;
>> + struct corner *corner;
>> + int uV, idx;
>> +
>> + idx = cpr_find_initial_corner(drv->dev, thread->cpu_clk,
>> + thread->corners,
>> + thread->num_corners);
>> + if (idx < 0)
>> + return idx;
>> +
>> + cpr_ctl_disable(thread);
>> +
>> + corner = &thread->corners[idx];
>> + cpr_corner_restore(thread, corner);
>> +
>> + uV = regulator_get_voltage(drv->vreg);
>> + uV = clamp(uV, corner->min_uV, corner->max_uV);
>> +
>> + corner->last_uV = uV;
>> + if (!drv->last_uV)
>> + drv->last_uV = uV;
>> +
>> + cpr_commit_state(thread);
>> + thread->enabled = true;
>> + cpr_switch(drv);
>> +
>> + return 0;
>> +}
>> +
>> +static const int msm8998_gold_scaling_factor[][CPR3_RO_COUNT] = {
>> + /* Fuse Corner 0 */
>> + {
>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>> + },
>> + /* Fuse Corner 1 */
>> + {
>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>> + },
>> + /* Fuse Corner 2 */
>> + {
>> + 2603, 2755, 2676, 2777, 2573, 2685, 2465, 2610,
>> + 2312, 2423, 2243, 3104, 3022, 3036, 2740, 2303
>> + },
>> + /* Fuse Corner 3 */
>> + {
>> + 1901, 2016, 2096, 2228, 2034, 2161, 2077, 2188,
>> + 1565, 1870, 1925, 2235, 2205, 2413, 1762, 1478
>> + }
>> +};
>> +
>> +static const int msm8998_silver_scaling_factor[][CPR3_RO_COUNT] = {
>> + /* Fuse Corner 0 */
>> + {
>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>> + },
>> + /* Fuse Corner 1 */
>> + {
>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>> + },
>> + /* Fuse Corner 2 */
>> + {
>> + 2391, 2550, 2483, 2638, 2382, 2564, 2259, 2555,
>> + 2766, 3041, 2988, 2935, 2873, 2688, 2013, 2784
>> + },
>> + /* Fuse Corner 3 */
>> + {
>> + 2066, 2153, 2300, 2434, 2220, 2386, 2288, 2465,
>> + 2028, 2511, 2487, 2734, 2554, 2117, 1892, 2377
>> + }
>> +};
>> +
>> +static const struct cpr_thread_desc msm8998_thread_gold = {
>> + .controller_id = 1,
>> + .hw_tid = 0,
>> + .ro_scaling_factor = msm8998_gold_scaling_factor,
>> + .ro_avail_corners = ARRAY_SIZE(msm8998_gold_scaling_factor),
>> + .sensor_range_start = 0,
>> + .sensor_range_end = 9,
>> + .init_voltage_step = 10000,
>> + .init_voltage_width = 6,
>> + .step_quot_init_min = 9,
>> + .step_quot_init_max = 14,
>> + .num_fuse_corners = 4,
>> + .fuse_corner_data = (struct fuse_corner_data[]){
>> + /* fuse corner 0 */
>> + {
>> + .ref_uV = 756000,
>> + .max_uV = 828000,
>> + .min_uV = 568000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 0,
>> + .volt_oloop_adjust = 8000,
>> + .max_volt_scale = 4,
>> + .max_quot_scale = 10,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 1 */
>> + {
>> + .ref_uV = 756000,
>> + .max_uV = 900000,
>> + .min_uV = 624000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 0,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 320,
>> + .max_quot_scale = 350,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 2 */
>> + {
>> + .ref_uV = 828000,
>> + .max_uV = 952000,
>> + .min_uV = 632000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 12000,
>> + .volt_oloop_adjust = 12000,
>> + .max_volt_scale = 620,
>> + .max_quot_scale = 750,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 3 */
>> + {
>> + .ref_uV = 1056000,
>> + .max_uV = 1136000,
>> + .min_uV = 772000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = 50000,
>> + .volt_oloop_adjust = 52000,
>> + .max_volt_scale = 580,
>> + .max_quot_scale = 1040,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + },
>> +};
>> +
>> +static const struct cpr_thread_desc msm8998_thread_silver = {
>> + .controller_id = 0,
>> + .hw_tid = 0,
>> + .ro_scaling_factor = msm8998_silver_scaling_factor,
>> + .ro_avail_corners = ARRAY_SIZE(msm8998_silver_scaling_factor),
>> + .sensor_range_start = 0,
>> + .sensor_range_end = 6,
>> + .init_voltage_step = 10000,
>> + .init_voltage_width = 6,
>> + .step_quot_init_min = 11,
>> + .step_quot_init_max = 12,
>> + .num_fuse_corners = 4,
>> + .fuse_corner_data = (struct fuse_corner_data[]){
>> + /* fuse corner 0 */
>> + {
>> + .ref_uV = 688000,
>> + .max_uV = 828000,
>> + .min_uV = 568000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 20000,
>> + .volt_oloop_adjust = 40000,
>> + .max_volt_scale = 4,
>> + .max_quot_scale = 10,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 1 */
>> + {
>> + .ref_uV = 756000,
>> + .max_uV = 900000,
>> + .min_uV = 632000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 26000,
>> + .volt_oloop_adjust = 24000,
>> + .max_volt_scale = 500,
>> + .max_quot_scale = 800,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 2 */
>> + {
>> + .ref_uV = 828000,
>> + .max_uV = 952000,
>> + .min_uV = 664000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = 12000,
>> + .volt_oloop_adjust = 12000,
>> + .max_volt_scale = 280,
>> + .max_quot_scale = 650,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> +
>> + },
>> + /* fuse corner 3 */
>> + {
>> + .ref_uV = 1056000,
>> + .max_uV = 1056000,
>> + .min_uV = 772000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = 30000,
>> + .volt_oloop_adjust = 30000,
>> + .max_volt_scale = 430,
>> + .max_quot_scale = 800,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + },
>> +};
>> +
>> +static const struct cpr_desc msm8998_cpr_desc = {
>> + .cpr_type = CTRL_TYPE_CPRH,
>> + .num_threads = 2,
>> + .mem_acc_threshold = 852000,
>> + .apm_threshold = 800000,
>> + .apm_crossover = 880000,
>> + .apm_hysteresis = 0,
>> + .cpr_base_voltage = 352000,
>> + .cpr_max_voltage = 1200000,
>> + .timer_delay_us = 5000,
>> + .timer_cons_up = 0,
>> + .timer_cons_down = 2,
>> + .up_threshold = 2,
>> + .down_threshold = 2,
>> + .idle_clocks = 15,
>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>> + .count_repeat = 14,
>> + .gcnt_us = 1,
>> + .vreg_step_fixed = 4000,
>> + .vreg_step_up_limit = 1,
>> + .vreg_step_down_limit = 1,
>> + .vdd_settle_time_us = 34,
>> + .corner_settle_time_us = 6,
>> + .reduce_to_corner_uV = true,
>> + .hw_closed_loop_en = true,
>> + .threads = (const struct cpr_thread_desc *[]) {
>> + &msm8998_thread_silver,
>> + &msm8998_thread_gold,
>> + },
>> +};
>> +
>> +static const struct cpr_acc_desc msm8998_cpr_acc_desc = {
>> + .cpr_desc = &msm8998_cpr_desc,
>> +};
>> +
>> +static const int sdm630_gold_scaling_factor[][CPR3_RO_COUNT] = {
>> + /* Same RO factors for all fuse corners */
>> + {
>> + 4040, 3230, 0, 2210, 2560, 2450, 2230, 2220,
>> + 2410, 2300, 2560, 2470, 1600, 3120, 2620, 2280
>> + }
>> +};
>> +
>> +static const int sdm630_silver_scaling_factor[][CPR3_RO_COUNT] = {
>> + /* Same RO factors for all fuse corners */
>> + {
>> + 3600, 3600, 3830, 2430, 2520, 2700, 1790, 1760,
>> + 1970, 1880, 2110, 2010, 2510, 4900, 4370, 4780,
>> + }
>> +};
>> +
>> +static const struct cpr_thread_desc sdm630_thread_gold = {
>> + .controller_id = 0,
>> + .hw_tid = 0,
>> + .ro_scaling_factor = sdm630_gold_scaling_factor,
>> + .ro_avail_corners = ARRAY_SIZE(sdm630_gold_scaling_factor),
>> + .sensor_range_start = 0,
>> + .sensor_range_end = 6,
>> + .init_voltage_step = 10000,
>> + .init_voltage_width = 6,
>> + .step_quot_init_min = 12,
>> + .step_quot_init_max = 14,
>> + .num_fuse_corners = 5,
>> + .fuse_corner_data = (struct fuse_corner_data[]){
>> + /* fuse corner 0 */
>> + {
>> + .ref_uV = 644000,
>> + .max_uV = 724000,
>> + .min_uV = 588000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 15000,
>> + .max_volt_scale = 10,
>> + .max_quot_scale = 300,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 1 */
>> + {
>> + .ref_uV = 788000,
>> + .max_uV = 788000,
>> + .min_uV = 652000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 5000,
>> + .max_volt_scale = 320,
>> + .max_quot_scale = 275,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 2 */
>> + {
>> + .ref_uV = 868000,
>> + .max_uV = 868000,
>> + .min_uV = 712000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 5000,
>> + .max_volt_scale = 350,
>> + .max_quot_scale = 800,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 3 */
>> + {
>> + .ref_uV = 988000,
>> + .max_uV = 988000,
>> + .min_uV = 784000,
>> + .range_uV = 66000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 868,
>> + .max_quot_scale = 980,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 4 */
>> + {
>> + .ref_uV = 1068000,
>> + .max_uV = 1068000,
>> + .min_uV = 844000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 868,
>> + .max_quot_scale = 980,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + },
>> +};
>> +
>> +static const struct cpr_thread_desc sdm630_thread_silver = {
>> + .controller_id = 1,
>> + .hw_tid = 0,
>> + .ro_scaling_factor = sdm630_silver_scaling_factor,
>> + .ro_avail_corners = ARRAY_SIZE(sdm630_silver_scaling_factor),
>> + .sensor_range_start = 0,
>> + .sensor_range_end = 6,
>> + .init_voltage_step = 10000,
>> + .init_voltage_width = 6,
>> + .step_quot_init_min = 12,
>> + .step_quot_init_max = 14,
>> + .num_fuse_corners = 3,
>> + .fuse_corner_data = (struct fuse_corner_data[]){
>> + /* fuse corner 0 */
>> + {
>> + .ref_uV = 644000,
>> + .max_uV = 724000,
>> + .min_uV = 588000,
>> + .range_uV = 32000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 10,
>> + .max_quot_scale = 360,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 1 */
>> + {
>> + .ref_uV = 788000,
>> + .max_uV = 788000,
>> + .min_uV = 652000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 500,
>> + .max_quot_scale = 550,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + /* fuse corner 2 */
>> + {
>> + .ref_uV = 1068000,
>> + .max_uV = 1068000,
>> + .min_uV = 800000,
>> + .range_uV = 40000,
>> + .volt_cloop_adjust = -30000,
>> + .volt_oloop_adjust = 0,
>> + .max_volt_scale = 2370,
>> + .max_quot_scale = 550,
>> + .quot_offset = 0,
>> + .quot_scale = 1,
>> + .quot_adjust = 0,
>> + .quot_offset_scale = 5,
>> + .quot_offset_adjust = 0,
>> + },
>> + },
>> +};
>> +
>> +static const struct cpr_desc sdm630_cpr_desc = {
>> + .cpr_type = CTRL_TYPE_CPRH,
>> + .num_threads = 2,
>> + .apm_threshold = 872000,
>> + .apm_crossover = 872000,
>> + .apm_hysteresis = 20000,
>> + .cpr_base_voltage = 400000,
>> + .cpr_max_voltage = 1300000,
>> + .timer_delay_us = 5000,
>> + .timer_cons_up = 0,
>> + .timer_cons_down = 2,
>> + .up_threshold = 2,
>> + .down_threshold = 2,
>> + .idle_clocks = 15,
>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>> + .count_repeat = 14,
>> + .gcnt_us = 1,
>> + .vreg_step_fixed = 4000,
>> + .vreg_step_up_limit = 1,
>> + .vreg_step_down_limit = 1,
>> + .vdd_settle_time_us = 34,
>> + .corner_settle_time_us = 5,
>> + .reduce_to_corner_uV = true,
>> + .hw_closed_loop_en = true,
>> + .threads = (const struct cpr_thread_desc *[]) {
>> + &sdm630_thread_gold,
>> + &sdm630_thread_silver,
>> + },
>> +};
>> +
>> +static const struct cpr_acc_desc sdm630_cpr_acc_desc = {
>> + .cpr_desc = &sdm630_cpr_desc,
>> +};
>> +
>> +static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
>> + struct dev_pm_opp *opp)
>> +{
>> + return dev_pm_opp_get_level(opp);
>> +}
>> +
>> +static int cpr_power_off(struct generic_pm_domain *domain)
>> +{
>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>> +
>> + return cpr_disable(thread);
>> +}
>> +
>> +static int cpr_power_on(struct generic_pm_domain *domain)
>> +{
>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>> +
>> + return cpr_enable(thread);
>> +}
>> +
>> +static void cpr_pd_detach_dev(struct generic_pm_domain *domain,
>> + struct device *dev)
>> +{
>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>> + struct cpr_drv *drv = thread->drv;
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + dev_dbg(drv->dev, "detach callback for: %s\n", dev_name(dev));
>> + thread->attached_cpu_dev = NULL;
>> +
>> + mutex_unlock(&drv->lock);
>> +}
>> +
>> +static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
>> + struct device *dev)
>> +{
>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>> + struct cpr_drv *drv = thread->drv;
>> + const struct acc_desc *acc_desc = drv->acc_desc;
>> + bool cprh_opp_remove_table = false;
>> + int ret = 0;
>> +
>> + mutex_lock(&drv->lock);
>> +
>> + dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev));
>> +
>> + /*
>> + * This driver only supports scaling voltage for a CPU cluster
>> + * where all CPUs in the cluster share a single regulator.
>> + * Therefore, save the struct device pointer only for the first
>> + * CPU device that gets attached. There is no need to do any
>> + * additional initialization when further CPUs get attached.
>> + * This is not an error condition.
>> + */
>> + if (thread->attached_cpu_dev)
>> + goto unlock;
>> +
>> + /*
>> + * cpr_scale_voltage() requires the direction (if we are changing
>> + * to a higher or lower OPP). The first time
>> + * cpr_set_performance_state() is called, there is no previous
>> + * performance state defined. Therefore, we call
>> + * cpr_find_initial_corner() that gets the CPU clock frequency
>> + * set by the bootloader, so that we can determine the direction
>> + * the first time cpr_set_performance_state() is called.
>> + */
>> + thread->cpu_clk = devm_clk_get(dev, NULL);
>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH && IS_ERR(thread->cpu_clk)) {
>> + ret = PTR_ERR(thread->cpu_clk);
>> + if (ret != -EPROBE_DEFER)
>> + dev_err(drv->dev, "could not get cpu clk: %d\n", ret);
>> + goto unlock;
>> + }
>> + thread->attached_cpu_dev = dev;
>> +
>> + /*
>> + * We are exporting the APM and MEM-ACC thresholds to the caller;
>> + * while APM is necessary in the CPU CPR case, MEM-ACC may not be,
>> + * depending on the SoC and on fuses.
>> + * Initialize both to an invalid value, so that the caller can check
>> + * if they got calculated or read from fuses in this driver.
>> + */
>> + thread->ext_data.apm_threshold_uV = -1;
>> + thread->ext_data.mem_acc_threshold_uV = -1;
>> + dev_set_drvdata(thread->attached_cpu_dev, &thread->ext_data);
>> +
>> + dev_dbg(drv->dev, "using cpu clk from: %s\n",
>> + dev_name(thread->attached_cpu_dev));
>> +
>> + /*
>> + * Everything related to (virtual) corners has to be initialized
>> + * here, when attaching to the power domain, since we need to know
>> + * the maximum frequency for each fuse corner, and this is only
>> + * available after the cpufreq driver has attached to us.
>> + * The reason for this is that we need to know the highest
>> + * frequency associated with each fuse corner.
>> + */
>> + ret = dev_pm_opp_get_opp_count(&thread->pd.dev);
>> + if (ret < 0) {
>> + dev_err(drv->dev, "could not get OPP count\n");
>> + thread->attached_cpu_dev = NULL;
>> + goto unlock;
>> + }
>> + thread->num_corners = ret;
>> +
>> + thread->corners = devm_kcalloc(drv->dev,
>> + thread->num_corners +
>> + drv->extra_corners,
>> + sizeof(*thread->corners),
>> + GFP_KERNEL);
>> + if (!thread->corners) {
>> + ret = -ENOMEM;
>> + goto unlock;
>> + }
>> +
>> + /*
>> + * If we are on CPR-Hardened we have to make sure that the attached
>> + * device has a OPP table installed, as we're going to modify it here
>> + * with our calculations based on qfprom values.
>> + */
>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH) {
>> + ret = dev_pm_opp_of_add_table(dev);
>> + if (ret && ret != -EEXIST) {
>> + dev_err(drv->dev, "Cannot add table: %d\n", ret);
>> + goto unlock;
>> + }
>> + cprh_opp_remove_table = true;
>> + }
>> +
>> + ret = cpr3_corner_init(thread);
>> + if (ret)
>> + goto exit;
>> +
>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH) {
>> + ret = cpr3_find_initial_corner(thread);
>> + if (ret)
>> + goto exit;
>> +
>> + if (acc_desc->config)
>> + regmap_multi_reg_write(drv->tcsr, acc_desc->config,
>> + acc_desc->num_regs_per_fuse);
>> +
>> + /* Enable ACC if required */
>> + if (acc_desc->enable_mask)
>> + regmap_update_bits(drv->tcsr, acc_desc->enable_reg,
>> + acc_desc->enable_mask,
>> + acc_desc->enable_mask);
>> + }
>> + dev_info(drv->dev, "thread %d initialized with %u OPPs\n",
>> + thread->id, thread->num_corners);
>> +exit:
>> + /*
>> + * If we are on CPRh and we reached an error condition, we installed
>> + * the OPP table but we haven't done any setup on it, nor we ever will.
>> + * In order to leave a clean state, remove the table.
>> + */
>> + if (ret && cprh_opp_remove_table)
>> + dev_pm_opp_of_remove_table(thread->attached_cpu_dev);
>> +unlock:
>> + mutex_unlock(&drv->lock);
>> +
>> + return ret;
>> +}
>> +
>> +static int cpr3_debug_info_show(struct seq_file *s, void *unused)
>> +{
>> + u32 ro_sel, ctl, irq_status, reg, quot;
>> + struct cpr_thread *thread = s->private;
>> + struct corner *corner = thread->corners;
>> + struct fuse_corner *fuse = thread->fuse_corners;
>> + unsigned int i;
>> +
>> + const struct {
>> + const char *name;
>> + uint32_t mask;
>> + uint8_t shift;
>> + } result0_fields[] = {
>> + { "busy", 1, 0 },
>> + { "step_dn", 1, 1 },
>> + { "step_up", 1, 2 },
>> + { "error_steps", CPR3_RESULT0_ERROR_STEPS_MASK,
>> + CPR3_RESULT0_ERROR_STEPS_SHIFT },
>> + { "error", CPR3_RESULT0_ERROR_MASK, CPR3_RESULT0_ERROR_SHIFT },
>> + { "negative", 1, 20 },
>> + }, result1_fields[] = {
>> + { "quot_min", CPR3_RESULT1_QUOT_MIN_MASK,
>> + CPR3_RESULT1_QUOT_MIN_SHIFT },
>> + { "quot_max", CPR3_RESULT1_QUOT_MAX_MASK,
>> + CPR3_RESULT1_QUOT_MAX_SHIFT },
>> + { "ro_min", CPR3_RESULT1_RO_MIN_MASK,
>> + CPR3_RESULT1_RO_MIN_SHIFT },
>> + { "ro_max", CPR3_RESULT1_RO_MAX_MASK,
>> + CPR3_RESULT1_RO_MAX_SHIFT },
>> + }, result2_fields[] = {
>> + { "qout_step_min", CPR3_RESULT2_STEP_QUOT_MIN_MASK,
>> + CPR3_RESULT2_STEP_QUOT_MIN_SHIFT },
>> + { "qout_step_max", CPR3_RESULT2_STEP_QUOT_MAX_MASK,
>> + CPR3_RESULT2_STEP_QUOT_MAX_SHIFT },
>> + { "sensor_min", CPR3_RESULT2_SENSOR_MIN_MASK,
>> + CPR3_RESULT2_SENSOR_MIN_SHIFT },
>> + { "sensor_max", CPR3_RESULT2_SENSOR_MAX_MASK,
>> + CPR3_RESULT2_SENSOR_MAX_SHIFT },
>> + };
>> +
>> + if (thread->drv->desc->cpr_type < CTRL_TYPE_CPRH)
>> + seq_printf(s, "current_volt = %d uV\n", thread->drv->last_uV);
>> +
>> + irq_status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>> + seq_printf(s, "irq_status = %#02X\n", irq_status);
>> +
>> + ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>> + seq_printf(s, "cpr_ctl = %#02X\n", ctl);
>> +
>> + seq_printf(s, "thread %d - hw tid: %u - enabled: %d:\n",
>> + thread->id, thread->desc->hw_tid, thread->enabled);
>> + seq_printf(s, "%d corners, derived from %d fuse corners\n",
>> + thread->num_corners, thread->desc->num_fuse_corners);
>> +
>> + for (i = 0; i < thread->num_corners; i++, corner++)
>> + seq_printf(s, "corner %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>> + i, corner->min_uV, corner->uV, corner->max_uV,
>> + corner->quot_adjust, corner->freq);
>> +
>> + for (i = 0; i < thread->desc->num_fuse_corners; i++, fuse++)
>> + seq_printf(s, "fuse %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>> + fuse->quot, corner->freq);
>> +
>> + seq_printf(s, "requested voltage: %d uV\n", thread->corner->last_uV);
>> +
>> + ro_sel = corner->fuse_corner->ring_osc_idx;
>> + quot = cpr_read(thread, CPR3_REG_TARGET_QUOT(i, ro_sel));
>> + seq_printf(s, "quot_target (%u) = %#02X\n", ro_sel, quot);
>> +
>> + reg = cpr_read(thread, CPR3_REG_RESULT0(i));
>> + seq_printf(s, "cpr_result_0 = %#02X\n [", reg);
>> + for (i = 0; i < ARRAY_SIZE(result0_fields); i++)
>> + seq_printf(s, "%s%s = %u",
>> + i ? ", " : "",
>> + result0_fields[i].name,
>> + (reg >> result0_fields[i].shift) &
>> + result0_fields[i].mask);
>> + seq_puts(s, "]\n");
>> + reg = cpr_read(thread, CPR3_REG_RESULT1(i));
>> + seq_printf(s, "cpr_result_1 = %#02X\n [", reg);
>> + for (i = 0; i < ARRAY_SIZE(result1_fields); i++)
>> + seq_printf(s, "%s%s = %u",
>> + i ? ", " : "",
>> + result1_fields[i].name,
>> + (reg >> result1_fields[i].shift) &
>> + result1_fields[i].mask);
>> + seq_puts(s, "]\n");
>> + reg = cpr_read(thread, CPR3_REG_RESULT2(i));
>> + seq_printf(s, "cpr_result_2 = %#02X\n [", reg);
>> + for (i = 0; i < ARRAY_SIZE(result2_fields); i++)
>> + seq_printf(s, "%s%s = %u",
>> + i ? ", " : "",
>> + result2_fields[i].name,
>> + (reg >> result2_fields[i].shift) &
>> + result2_fields[i].mask);
>> + seq_puts(s, "]\n");
>> +
>> + return 0;
>> +}
>> +DEFINE_SHOW_ATTRIBUTE(cpr3_debug_info);
>> +
>> +static void cpr3_debugfs_init(struct cpr_drv *drv)
>> +{
>> + int i;
>> +
>> + drv->debugfs = debugfs_create_dir("qcom_cpr3", NULL);
>> +
>> + for (i = 0; i < drv->desc->num_threads; i++) {
>> + char buf[50];
>> +
>> + snprintf(buf, sizeof(buf), "thread%d", i);
>> +
>> + debugfs_create_file(buf, 0444, drv->debugfs, &drv->threads[i],
>> + &cpr3_debug_info_fops);
>> + }
>> +}
>> +
>> +/**
>> + * cpr_thread_init() - Initialize CPR thread related parameters
>> + * @drv: Main driver structure
>> + * @tid: Thread ID
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr_thread_init(struct cpr_drv *drv, int tid)
>> +{
>> + const struct cpr_desc *desc = drv->desc;
>> + const struct cpr_thread_desc *tdesc = desc->threads[tid];
>> + struct cpr_thread *thread = &drv->threads[tid];
>> + int ret;
>> +
>> + if (tdesc->step_quot_init_min > CPR3_CPR_STEP_QUOT_MIN_MASK ||
>> + tdesc->step_quot_init_max > CPR3_CPR_STEP_QUOT_MAX_MASK)
>> + return -EINVAL;
>> +
>> + thread->id = tid;
>> + thread->drv = drv;
>> + thread->desc = tdesc;
>> + thread->fuse_corners = devm_kcalloc(drv->dev,
>> + tdesc->num_fuse_corners +
>> + drv->extra_corners,
>> + sizeof(*thread->fuse_corners),
>> + GFP_KERNEL);
>> + if (!thread->fuse_corners)
>> + return -ENOMEM;
>> +
>> + thread->cpr_fuses = cpr_get_fuses(drv->dev, tid,
>> + tdesc->num_fuse_corners);
>> + if (IS_ERR(thread->cpr_fuses))
>> + return PTR_ERR(thread->cpr_fuses);
>> +
>> + ret = cpr_populate_ring_osc_idx(thread->drv->dev, thread->fuse_corners,
>> + thread->cpr_fuses,
>> + tdesc->num_fuse_corners);
>> + if (ret)
>> + return ret;
>> +
>> + ret = cpr_fuse_corner_init(thread);
>> + if (ret)
>> + return ret;
>> +
>> + thread->pd.name = devm_kasprintf(drv->dev, GFP_KERNEL,
>> + "%s_thread%d",
>> + drv->dev->of_node->full_name,
>> + thread->id);
>> + if (!thread->pd.name)
>> + return -EINVAL;
>> +
>> + thread->pd.power_off = cpr_power_off;
>> + thread->pd.power_on = cpr_power_on;
>> + thread->pd.opp_to_performance_state = cpr_get_performance_state;
>> + thread->pd.attach_dev = cpr_pd_attach_dev;
>> + thread->pd.detach_dev = cpr_pd_detach_dev;
>> +
>> + /* CPR-Hardened performance states are managed in firmware */
>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>> + thread->pd.set_performance_state = cprh_dummy_set_performance_state;
>> + else
>> + thread->pd.set_performance_state = cpr_set_performance_state;
>> +
>> + /* Anything later than CPR1 must be always-on for now */
>> + thread->pd.flags = GENPD_FLAG_ALWAYS_ON;
>> +
>> + drv->cell_data.domains[tid] = &thread->pd;
>> +
>> + ret = pm_genpd_init(&thread->pd, NULL, false);
>> + if (ret)
>> + return ret;
>> +
>> + /* On CPRhardened, the interrupts are managed in firmware */
>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>> + INIT_WORK(&thread->restart_work, cpr_restart_worker);
>> +
>> + ret = devm_request_threaded_irq(drv->dev, drv->irq,
>> + NULL, cpr_irq_handler,
>> + IRQF_ONESHOT |
>> + IRQF_TRIGGER_RISING,
>> + "cpr", drv);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * cpr3_resources_init() - Initialize resources used by this driver
>> + * @pdev: Platform device
>> + * @drv: Main driver structure
>> + *
>> + * Return: Zero for success, negative number on error
>> + */
>> +static int cpr3_resources_init(struct platform_device *pdev,
>> + struct cpr_drv *drv)
>> +{
>> + const struct cpr_desc *desc = drv->desc;
>> + struct cpr_thread *threads = drv->threads;
>> + unsigned int i;
>> + u8 cid_mask = 0;
>> +
>> + /*
>> + * Here, we are accounting for the following usecases:
>> + * - One controller
>> + * - One or multiple threads on the same iospace
>> + *
>> + * - Multiple controllers
>> + * - Each controller has its own iospace and each
>> + * may have one or multiple threads in their
>> + * parent controller's iospace
>> + *
>> + * Then, to avoid complicating the code for no reason,
>> + * this also needs a mandatory order in the list of
>> + * threads which implies that all of them from the same
>> + * controllers are specified sequentially. As an example:
>> + *
>> + * C0-T0, C0-T1...C0-Tn, C1-T0, C1-T1...C1-Tn
>> + */
>> + for (i = 0; i < desc->num_threads; i++) {
>> + u8 cid = desc->threads[i]->controller_id;
>> +
>> + if (cid_mask & BIT(cid)) {
>> + if (desc->threads[i - 1]->controller_id != cid) {
>> + dev_err(drv->dev, "Bad threads order. Please fix!\n");
>> + return -EINVAL;
>> + }
>> + threads[i].base = threads[i - 1].base;
>> + continue;
>> + }
>> + threads[i].base = devm_platform_ioremap_resource(pdev, cid);
>> + if (IS_ERR(threads[i].base))
>> + return PTR_ERR(threads[i].base);
>> + cid_mask |= BIT(cid);
>> + }
>> + return 0;
>> +}
>> +
>> +static int cpr_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct cpr_drv *drv;
>> + const struct cpr_desc *desc;
>> + const struct cpr_acc_desc *data;
>> + struct device_node *np;
>> + unsigned int i;
>> + int ret;
>> +
>> + data = of_device_get_match_data(dev);
>> + if (!data || !data->cpr_desc)
>> + return -EINVAL;
>> +
>> + desc = data->cpr_desc;
>> +
>> + /* CPRh disallows MEM-ACC access from the HLOS */
>> + if (!data->acc_desc && desc->cpr_type < CTRL_TYPE_CPRH)
>> + return -EINVAL;
>> +
>> + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
>> + if (!drv)
>> + return -ENOMEM;
>> +
>> + drv->dev = dev;
>> + drv->desc = desc;
>> + drv->threads = devm_kcalloc(dev, desc->num_threads,
>> + sizeof(*drv->threads), GFP_KERNEL);
>> + if (!drv->threads)
>> + return -ENOMEM;
>> +
>> + drv->cell_data.num_domains = desc->num_threads;
>> + drv->cell_data.domains = devm_kcalloc(drv->dev,
>> + drv->cell_data.num_domains,
>> + sizeof(*drv->cell_data.domains),
>> + GFP_KERNEL);
>> + if (!drv->cell_data.domains)
>> + return -ENOMEM;
>> +
>> + if (data->acc_desc)
>> + drv->acc_desc = data->acc_desc;
>> +
>> + mutex_init(&drv->lock);
>> +
>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>> + np = of_parse_phandle(dev->of_node, "acc-syscon", 0);
>> + if (!np)
>> + return -ENODEV;
>> +
>> + drv->tcsr = syscon_node_to_regmap(np);
>> + of_node_put(np);
>> + if (IS_ERR(drv->tcsr))
>> + return PTR_ERR(drv->tcsr);
>> + }
>> +
>> + ret = cpr3_resources_init(pdev, drv);
>> + if (ret)
>> + return ret;
>> +
>> + drv->irq = platform_get_irq_optional(pdev, 0);
>> + if (desc->cpr_type != CTRL_TYPE_CPRH && drv->irq < 0)
>> + return -EINVAL;
>> +
>> + /* On CPRhardened, vreg access it not allowed */
>> + drv->vreg = devm_regulator_get_optional(dev, "vdd");
>> + if (desc->cpr_type != CTRL_TYPE_CPRH && IS_ERR(drv->vreg))
>> + return PTR_ERR(drv->vreg);
>> +
>> + /*
>> + * On at least CPRhardened, vreg is unaccessible and there is no
>> + * way to read linear step from that regulator, hence it is hardcoded
>> + * in the driver;
>> + * When the vreg_step is not declared in the cpr data (or is zero),
>> + * then having access to the vreg regulator is mandatory, as this
>> + * will be retrieved through the regulator API.
>> + */
>> + if (desc->vreg_step_fixed)
>> + drv->vreg_step = desc->vreg_step_fixed;
>> + else
>> + drv->vreg_step = regulator_get_linear_step(drv->vreg);
>> +
>> + if (!drv->vreg_step)
>> + return -EINVAL;
>> +
>> + /*
>> + * Initialize fuse corners, since it simply depends
>> + * on data in efuses.
>> + * Everything related to (virtual) corners has to be
>> + * initialized after attaching to the power domain,
>> + * since it depends on the CPU's OPP table.
>> + */
>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &drv->fusing_rev);
>> + if (ret)
>> + return ret;
>> +
>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_speed_bin", &drv->speed_bin);
>> + if (ret)
>> + return ret;
>> +
>> + /*
>> + * Some SoCs require extra corners for MEM-ACC or APM: if
>> + * the related parameters have been specified, then reserve
>> + * a corner for the APM and/or MEM-ACC crossover, used by
>> + * OSM and CPRh HW to set the supply voltage during the APM
>> + * and/or MEM-ACC switch routine.
>> + */
>> + if (desc->cpr_type == CTRL_TYPE_CPRH) {
>> + if (desc->apm_crossover && desc->apm_hysteresis >= 0)
>> + drv->extra_corners++;
>> +
>> + if (desc->mem_acc_threshold)
>> + drv->extra_corners++;
>> + }
>> +
>> + /* Initialize all threads */
>> + for (i = 0; i < desc->num_threads; i++) {
>> + ret = cpr_thread_init(drv, i);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + /* Initialize global parameters */
>> + ret = cpr3_init_parameters(drv);
>> + if (ret)
>> + return ret;
>> +
>> + /* Write initial configuration on all threads */
>> + for (i = 0; i < desc->num_threads; i++) {
>> + ret = cpr_configure(&drv->threads[i]);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + ret = of_genpd_add_provider_onecell(dev->of_node, &drv->cell_data);
>> + if (ret)
>> + return ret;
>> +
>> + platform_set_drvdata(pdev, drv);
>> + cpr3_debugfs_init(drv);
>> +
>> + return 0;
>> +}
>> +
>> +static int cpr_remove(struct platform_device *pdev)
>> +{
>> + struct cpr_drv *drv = platform_get_drvdata(pdev);
>> + int i;
>> +
>> + of_genpd_del_provider(pdev->dev.of_node);
>> +
>> + for (i = 0; i < drv->desc->num_threads; i++) {
>> + cpr_ctl_disable(&drv->threads[i]);
>> + cpr_irq_set(&drv->threads[i], 0);
>> + pm_genpd_remove(&drv->threads[i].pd);
>> + }
>> +
>> + debugfs_remove_recursive(drv->debugfs);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id cpr3_match_table[] = {
>> + { .compatible = "qcom,msm8998-cprh", .data = &msm8998_cpr_acc_desc },
>> + { .compatible = "qcom,sdm630-cprh", .data = &sdm630_cpr_acc_desc },
>> + { }
>> +};
>> +MODULE_DEVICE_TABLE(of, cpr3_match_table);
>> +
>> +static struct platform_driver cpr3_driver = {
>> + .probe = cpr_probe,
>> + .remove = cpr_remove,
>> + .driver = {
>> + .name = "qcom-cpr3",
>> + .of_match_table = cpr3_match_table,
>> + },
>> +};
>> +module_platform_driver(cpr3_driver)
>> +
>> +MODULE_DESCRIPTION("Core Power Reduction (CPR) v3/v4 driver");
>> +MODULE_LICENSE("GPL v2");
>> \ No newline at end of file
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
2023-01-10 18:29 ` Konrad Dybcio
@ 2023-01-10 18:42 ` Robert Marko
2023-01-10 18:43 ` Konrad Dybcio
0 siblings, 1 reply; 17+ messages in thread
From: Robert Marko @ 2023-01-10 18:42 UTC (permalink / raw)
To: Konrad Dybcio, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
linux-kernel
On 10. 01. 2023. 19:29, Konrad Dybcio wrote:
>
> On 10.01.2023 19:27, Robert Marko wrote:
>> On 10. 01. 2023. 18:56, Konrad Dybcio wrote:
>>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>
>>> This commit introduces a new driver, based on the one for cpr v1,
>>> to enable support for the newer Qualcomm Core Power Reduction
>>> hardware, known downstream as CPR3, CPR4 and CPRh, and support
>>> for MSM8998 and SDM630 CPU power reduction.
>>>
>>> In these new versions of the hardware, support for various new
>>> features was introduced, including voltage reduction for the GPU,
>>> security hardening and a new way of controlling CPU DVFS,
>>> consisting in internal communication between microcontrollers,
>>> specifically the CPR-Hardened and the Operating State Manager.
>>>
>>> The CPR v3, v4 and CPRh are present in a broad range of SoCs,
>>> from the mid-range to the high end ones including, but not limited
>>> to, MSM8953/8996/8998, SDM630/636/660/845.
>>>
>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>> [Konrad: rebase, apply review comments]
>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>> Hi Konrad, great to see the series is alive again.
>> I am working on IPQ8074 which uses CPRv4 and its the last piece for
>> upstream CPU scaling that is missing so this is really interesting for me.
>>
>> However, I think you forgot to include the <soc/qcom/cpr.h> header so
>> it wont currently compile.
>>
>> Regards,
>> Robert
> Right, that's rather embarassing..
>
> Here's the contents of the file, I will hold on with resending
> until there are some more reviwew comments..
Thanks, that gets it mostly compiling, however it seems that common
CPR code is not getting selected to the symbols will be missing.
Adding select QCOM_CPR_COMMON to QCOM_CPR3 sorts that out, so I
assume it was just forgotten as QCOM_CPR has it selected.
Regards,
Robert
>
>
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
> * Copyright (c) 2019 Linaro Limited
> * Copyright (c) 2021, AngeloGioacchino Del Regno
> * <angelogioacchino.delregno@somainline.org>
> */
>
> #ifndef __CPR_H__
> #define __CPR_H__
>
> struct cpr_ext_data {
> int mem_acc_threshold_uV;
> int apm_threshold_uV;
> };
>
> #endif /* __CPR_H__ */
>
>
> Konrad
>>> ---
>>> drivers/soc/qcom/Kconfig | 21 +
>>> drivers/soc/qcom/Makefile | 4 +-
>>> drivers/soc/qcom/cpr-common.h | 2 +
>>> drivers/soc/qcom/cpr3.c | 2923 +++++++++++++++++++++++++++++++++
>>> 4 files changed, 2949 insertions(+), 1 deletion(-)
>>> create mode 100644 drivers/soc/qcom/cpr3.c
>>>
>>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>>> index 21c4ce2315ba..303e958d9432 100644
>>> --- a/drivers/soc/qcom/Kconfig
>>> +++ b/drivers/soc/qcom/Kconfig
>>> @@ -29,6 +29,7 @@ config QCOM_COMMAND_DB
>>> config QCOM_CPR
>>> tristate "QCOM Core Power Reduction (CPR) support"
>>> depends on ARCH_QCOM && HAS_IOMEM
>>> + select QCOM_CPR_COMMON
>>> select PM_OPP
>>> select REGMAP
>>> help
>>> @@ -42,6 +43,26 @@ config QCOM_CPR
>>> To compile this driver as a module, choose M here: the module will
>>> be called qcom-cpr
>>> +config QCOM_CPR_COMMON
>>> + tristate
>>> +
>>> +config QCOM_CPR3
>>> + tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
>>> + depends on ARCH_QCOM && HAS_IOMEM
>>> + select PM_OPP
>>> + select REGMAP
>>> + help
>>> + Say Y here to enable support for the CPR hardware found on a broad
>>> + variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
>>> + SDM845 and others.
>>> +
>>> + This driver populates OPP tables and makes adjustments to them
>>> + based on feedback from the CPR hardware. If you want to do CPU
>>> + and/or GPU frequency scaling say Y here.
>>> +
>>> + To compile this driver as a module, choose M here: the module will
>>> + be called qcom-cpr3
>>> +
>>> config QCOM_GENI_SE
>>> tristate "QCOM GENI Serial Engine Driver"
>>> depends on ARCH_QCOM || COMPILE_TEST
>>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>>> index ba2b55dd94ff..362e9b712a68 100644
>>> --- a/drivers/soc/qcom/Makefile
>>> +++ b/drivers/soc/qcom/Makefile
>>> @@ -3,7 +3,9 @@ CFLAGS_rpmh-rsc.o := -I$(src)
>>> obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
>>> obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
>>> obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
>>> -obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
>>> +obj-$(CONFIG_QCOM_CPR) += cpr.o
>>> +obj-$(CONFIG_QCOM_CPR_COMMON) += cpr-common.o
>>> +obj-$(CONFIG_QCOM_CPR3) += cpr3.o
>>> obj-$(CONFIG_QCOM_DCC) += dcc.o
>>> obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
>>> obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
>>> diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
>>> index 2cd15f7eac90..a90f6351d022 100644
>>> --- a/drivers/soc/qcom/cpr-common.h
>>> +++ b/drivers/soc/qcom/cpr-common.h
>>> @@ -65,6 +65,8 @@ struct corner {
>>> struct corner_data {
>>> unsigned int fuse_corner;
>>> unsigned long freq;
>>> + int oloop_vadj;
>>> + int cloop_vadj;
>>> };
>>> struct acc_desc {
>>> diff --git a/drivers/soc/qcom/cpr3.c b/drivers/soc/qcom/cpr3.c
>>> new file mode 100644
>>> index 000000000000..14a1163d37eb
>>> --- /dev/null
>>> +++ b/drivers/soc/qcom/cpr3.c
>>> @@ -0,0 +1,2923 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
>>> + * Copyright (c) 2019 Linaro Limited
>>> + * Copyright (c) 2021, AngeloGioacchino Del Regno
>>> + * <angelogioacchino.delregno@somainline.org>
>>> + */
>>> +
>>> +#include <linux/bitops.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/debugfs.h>
>>> +#include <linux/err.h>
>>> +#include <linux/init.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/io.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/mfd/syscon.h>
>>> +#include <linux/module.h>
>>> +#include <linux/nvmem-consumer.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/pm_domain.h>
>>> +#include <linux/pm_opp.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/regulator/consumer.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/string.h>
>>> +#include <linux/workqueue.h>
>>> +#include <soc/qcom/cpr.h>
>>> +
>>> +#include "cpr-common.h"
>>> +
>>> +#define CPR3_RO_COUNT 16
>>> +#define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0)
>>> +
>>> +/* CPR3 registers */
>>> +#define CPR3_REG_CPR_VERSION 0x0
>>> +#define CPRH_CPR_VERSION_4P5 0x40050000
>>> +
>>> +#define CPR3_REG_CPR_CTL 0x4
>>> +#define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0)
>>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK GENMASK(5, 1)
>>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT 1
>>> +#define CPR3_CPR_CTL_COUNT_MODE_MASK GENMASK(7, 6)
>>> +#define CPR3_CPR_CTL_COUNT_MODE_SHIFT 6
>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN 0
>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX 1
>>> +#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED 2
>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE 3
>>> +#define CPR3_CPR_CTL_COUNT_REPEAT_MASK GENMASK(31, 9)
>>> +#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT 9
>>> +
>>> +#define CPR3_REG_CPR_STATUS 0x8
>>> +#define CPR3_CPR_STATUS_BUSY_MASK BIT(0)
>>> +
>>> +/*
>>> + * This register is not present on controllers that support HW closed-loop
>>> + * except CPR4 APSS controller.
>>> + */
>>> +#define CPR3_REG_CPR_TIMER_AUTO_CONT 0xC
>>> +
>>> +#define CPR3_REG_CPR_STEP_QUOT 0x14
>>> +#define CPR3_CPR_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>>> +#define CPR3_CPR_STEP_QUOT_MIN_SHIFT 0
>>> +#define CPR3_CPR_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>>> +#define CPR3_CPR_STEP_QUOT_MAX_SHIFT 6
>>> +#define CPRH_DELTA_QUOT_STEP_FACTOR 4
>>> +
>>> +#define CPR3_REG_GCNT(ro) (0xA0 + 0x4 * (ro))
>>> +#define CPR3_REG_SENSOR_OWNER(sensor) (0x200 + 0x4 * (sensor))
>>> +
>>> +#define CPR3_REG_CONT_CMD 0x800
>>> +#define CPR3_CONT_CMD_ACK 0x1
>>> +#define CPR3_CONT_CMD_NACK 0x0
>>> +
>>> +#define CPR3_REG_THRESH(thread) (0x808 + 0x440 * (thread))
>>> +#define CPR3_THRESH_CONS_DOWN_MASK GENMASK(3, 0)
>>> +#define CPR3_THRESH_CONS_DOWN_SHIFT 0
>>> +#define CPR3_THRESH_CONS_UP_MASK GENMASK(7, 4)
>>> +#define CPR3_THRESH_CONS_UP_SHIFT 4
>>> +#define CPR3_THRESH_DOWN_THRESH_MASK GENMASK(12, 8)
>>> +#define CPR3_THRESH_DOWN_THRESH_SHIFT 8
>>> +#define CPR3_THRESH_UP_THRESH_MASK GENMASK(17, 13)
>>> +#define CPR3_THRESH_UP_THRESH_SHIFT 13
>>> +
>>> +#define CPR3_REG_RO_MASK(thread) (0x80C + 0x440 * (thread))
>>> +
>>> +#define CPR3_REG_RESULT0(thread) (0x810 + 0x440 * (thread))
>>> +#define CPR3_RESULT0_BUSY_MASK BIT(0)
>>> +#define CPR3_RESULT0_STEP_DN_MASK BIT(1)
>>> +#define CPR3_RESULT0_STEP_UP_MASK BIT(2)
>>> +#define CPR3_RESULT0_ERROR_STEPS_MASK GENMASK(7, 3)
>>> +#define CPR3_RESULT0_ERROR_STEPS_SHIFT 3
>>> +#define CPR3_RESULT0_ERROR_MASK GENMASK(19, 8)
>>> +#define CPR3_RESULT0_ERROR_SHIFT 8
>>> +
>>> +#define CPR3_REG_RESULT1(thread) (0x814 + 0x440 * (thread))
>>> +#define CPR3_RESULT1_QUOT_MIN_MASK GENMASK(11, 0)
>>> +#define CPR3_RESULT1_QUOT_MIN_SHIFT 0
>>> +#define CPR3_RESULT1_QUOT_MAX_MASK GENMASK(23, 12)
>>> +#define CPR3_RESULT1_QUOT_MAX_SHIFT 12
>>> +#define CPR3_RESULT1_RO_MIN_MASK GENMASK(27, 24)
>>> +#define CPR3_RESULT1_RO_MIN_SHIFT 24
>>> +#define CPR3_RESULT1_RO_MAX_MASK GENMASK(31, 28)
>>> +#define CPR3_RESULT1_RO_MAX_SHIFT 28
>>> +
>>> +#define CPR3_REG_RESULT2(thread) (0x818 + 0x440 * (thread))
>>> +#define CPR3_RESULT2_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>>> +#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT 0
>>> +#define CPR3_RESULT2_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>>> +#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT 6
>>> +#define CPR3_RESULT2_SENSOR_MIN_MASK GENMASK(23, 16)
>>> +#define CPR3_RESULT2_SENSOR_MIN_SHIFT 16
>>> +#define CPR3_RESULT2_SENSOR_MAX_MASK GENMASK(31, 24)
>>> +#define CPR3_RESULT2_SENSOR_MAX_SHIFT 24
>>> +
>>> +#define CPR3_REG_IRQ_EN 0x81C
>>> +#define CPR3_REG_IRQ_CLEAR 0x820
>>> +#define CPR3_REG_IRQ_STATUS 0x824
>>> +#define CPR3_IRQ_UP BIT(3)
>>> +#define CPR3_IRQ_MID BIT(2)
>>> +#define CPR3_IRQ_DOWN BIT(1)
>>> +#define CPR3_IRQ_ALL (CPR3_IRQ_UP | CPR3_IRQ_MID | CPR3_IRQ_DOWN)
>>> +
>>> +#define CPR3_REG_TARGET_QUOT(thread, ro) (0x840 + 0x440 * (thread) + 0x4 * (ro))
>>> +
>>> +/* Registers found only on controllers that support HW closed-loop. */
>>> +#define CPR3_REG_PD_THROTTLE 0xE8
>>> +
>>> +#define CPR3_REG_HW_CLOSED_LOOP_DISABLED 0x3000
>>> +#define CPR3_REG_CPR_TIMER_MID_CONT 0x3004
>>> +#define CPR3_REG_CPR_TIMER_UP_DN_CONT 0x3008
>>> +
>>> +/* CPR4 controller specific registers and bit definitions */
>>> +#define CPR4_REG_CPR_TIMER_CLAMP 0x10
>>> +#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27)
>>> +
>>> +#define CPR4_REG_MISC 0x700
>>> +#define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2)
>>> +#define CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN BIT(3)
>>> +
>>> +#define CPR4_REG_SAW_ERROR_STEP_LIMIT 0x7A4
>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK GENMASK(4, 0)
>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT 0
>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK GENMASK(9, 5)
>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT 5
>>> +
>>> +#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS 0x7A8
>>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK GENMASK(28, 18)
>>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT 18
>>> +
>>> +#define CPR4_REG_MARGIN_ADJ_CTL 0x7F8
>>> +#define CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN BIT(4)
>>> +#define CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN BIT(7)
>>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK GENMASK(16, 12)
>>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT 12
>>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_MASK GENMASK(31, 26)
>>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_SHIFT 26
>>> +
>>> +#define CPR4_REG_CPR_MASK_THREAD(thread) (0x80C + 0x440 * (thread))
>>> +#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD BIT(31)
>>> +#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0)
>>> +
>>> +/* CPRh controller specific registers and bit definitions */
>>> +#define __CPRH_REG_CORNER(rbase, tbase, tid, cnum) (rbase + (tbase * tid) + (0x4 * cnum))
>>> +#define CPRH_REG_CORNER(d, t, c) __CPRH_REG_CORNER(d->reg_corner, d->reg_corner_tid, t, c)
>>> +
>>> +#define CPRH_CTL_OSM_ENABLED BIT(0)
>>> +#define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1)
>>> +#define CPRH_CTL_BASE_VOLTAGE_SHIFT 1
>>> +#define CPRH_CTL_MODE_SWITCH_DELAY_MASK GENMASK(24, 17)
>>> +#define CPRH_CTL_MODE_SWITCH_DELAY_SHIFT 17
>>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_MASK GENMASK(28, 25)
>>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT 25
>>> +
>>> +#define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0)
>>> +#define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0
>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8)
>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_SHIFT 8
>>> +#define CPRH_CORNER_QUOT_DELTA_MASK GENMASK(24, 16)
>>> +#define CPRH_CORNER_QUOT_DELTA_SHIFT 16
>>> +#define CPRH_CORNER_RO_SEL_MASK GENMASK(28, 25)
>>> +#define CPRH_CORNER_RO_SEL_SHIFT 25
>>> +#define CPRH_CORNER_CPR_CL_DISABLE BIT(29)
>>> +
>>> +#define CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE 255
>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255
>>> +#define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511
>>> +
>>> +enum cpr_type {
>>> + CTRL_TYPE_CPR3,
>>> + CTRL_TYPE_CPR4,
>>> + CTRL_TYPE_CPRH,
>>> + CTRL_TYPE_MAX,
>>> +};
>>> +
>>> +/*
>>> + * struct cpr_thread_desc - CPR Thread-specific parameters
>>> + *
>>> + * @controller_id: Identifier of the CPR controller expected by the HW
>>> + * @ro_scaling_factor: Scaling factor for each ring oscillator entry
>>> + * @hw_tid: Identifier of the CPR thread expected by the HW
>>> + * @init_voltage_step: Voltage in uV for number of steps read from fuse array
>>> + * @init_voltage_width: Bit-width of the voltage read from the fuse array
>>> + * @sensor_range_start: First sensor ID used by a thread
>>> + * @sensor_range_end: Last sensor ID used by a thread
>>> + * @num_fuse_corners: Number of valid entries in fuse_corner_data
>>> + * @step_quot_init_min: Minimum achievable step quotient for this corner
>>> + * @step_quot_init_max: Maximum achievable step quotient for this corner
>>> + * @fuse_corner_data: Parameters for calculation of each fuse corner
>>> + */
>>> +struct cpr_thread_desc {
>>> + u8 controller_id;
>>> + u8 hw_tid;
>>> + const int (*ro_scaling_factor)[CPR3_RO_COUNT];
>>> + int ro_avail_corners;
>>> + int init_voltage_step;
>>> + int init_voltage_width;
>>> + u8 sensor_range_start;
>>> + u8 sensor_range_end;
>>> + u8 step_quot_init_min;
>>> + u8 step_quot_init_max;
>>> + unsigned int num_fuse_corners;
>>> + struct fuse_corner_data *fuse_corner_data;
>>> +};
>>> +
>>> +/*
>>> + * struct cpr_desc - Driver instance-wide CPR parameters
>>> + *
>>> + * @cpr_type: Type (base version) of the CPR controller
>>> + * @num_threads: Max. number of threads supported by this controller
>>> + * @timer_delay_us: Loop delay time in uS
>>> + * @timer_updn_delay_us: Voltage after-up/before-down delay time in uS
>>> + * @timer_cons_up: Wait between consecutive up requests in uS
>>> + * @timer_cons_down: Wait between consecutive down requests in uS
>>> + * @up_threshold: Generic corner up threshold
>>> + * @down_threshold: Generic corner down threshold
>>> + * @idle_clocks: CPR Sensor: idle timer in cpr clocks unit
>>> + * @count_mode: CPR Sensor: counting mode
>>> + * @count_repeat: CPR Sensor: number of times to repeat reading
>>> + * @gcnt_us: CPR measurement interval in uS
>>> + * @vreg_step_fixed: Regulator voltage per step (if vreg unusable)
>>> + * @vreg_step_up_limit: Num. of steps up at once before re-measuring sensors
>>> + * @vreg_step_down_limit: Num. of steps dn at once before re-measuring sensors
>>> + * @vdd_settle_time_us: Settling timer to account for one VDD supply step
>>> + * @corner_settle_time_us: Settle time for corner switch request
>>> + * @mem_acc_threshold: Memory Accelerator (MEM-ACC) voltage threshold
>>> + * @apm_threshold: Array Power Mux (APM) voltage threshold
>>> + * @apm_crossover: Array Power Mux (APM) corner crossover voltage
>>> + * @apm_hysteresis: Hysteresis for APM V-threshold related calculations
>>> + * @cpr_base_voltage: Safety: Absolute minimum voltage (uV) on this CPR
>>> + * @cpr_max_voltage: Safety: Absolute maximum voltage (uV) on this CPR
>>> + * @pd_throttle_val: CPR Power Domain throttle during voltage switch
>>> + * @threads: Array containing "CPR Thread" specific parameters
>>> + * @reduce_to_fuse_uV: Reduce corner max volts (if higher) to fuse ceiling
>>> + * @reduce_to_corner_uV: Reduce corner max volts (if higher) to corner ceil.
>>> + * @hw_closed_loop_en: Enable CPR HW Closed-Loop voltage auto-adjustment
>>> + */
>>> +struct cpr_desc {
>>> + enum cpr_type cpr_type;
>>> + unsigned int num_threads;
>>> + unsigned int timer_delay_us;
>>> + u8 timer_updn_delay_us;
>>> + u8 timer_cons_up;
>>> + u8 timer_cons_down;
>>> + u8 up_threshold;
>>> + u8 down_threshold;
>>> + u8 idle_clocks;
>>> + u8 count_mode;
>>> + u8 count_repeat;
>>> + u8 gcnt_us;
>>> + u16 vreg_step_fixed;
>>> + u8 vreg_step_up_limit;
>>> + u8 vreg_step_down_limit;
>>> + u8 vdd_settle_time_us;
>>> + u8 corner_settle_time_us;
>>> + int mem_acc_threshold;
>>> + int apm_threshold;
>>> + int apm_crossover;
>>> + int apm_hysteresis;
>>> + u32 cpr_base_voltage;
>>> + u32 cpr_max_voltage;
>>> + u32 pd_throttle_val;
>>> +
>>> + const struct cpr_thread_desc **threads;
>>> + bool reduce_to_fuse_uV;
>>> + bool reduce_to_corner_uV;
>>> + bool hw_closed_loop_en;
>>> +};
>>> +
>>> +struct cpr_drv;
>>> +struct cpr_thread {
>>> + int num_corners;
>>> + int id;
>>> + bool enabled;
>>> + void __iomem *base;
>>> + struct clk *cpu_clk;
>>> + struct corner *corner;
>>> + struct corner *corners;
>>> + struct fuse_corner *fuse_corners;
>>> + struct cpr_drv *drv;
>>> + struct cpr_ext_data ext_data;
>>> + struct generic_pm_domain pd;
>>> + struct device *attached_cpu_dev;
>>> + struct work_struct restart_work;
>>> + bool restarting;
>>> +
>>> + const struct cpr_fuse *cpr_fuses;
>>> + const struct cpr_thread_desc *desc;
>>> +};
>>> +
>>> +struct cpr_drv {
>>> + int irq;
>>> + unsigned int ref_clk_khz;
>>> + struct device *dev;
>>> + struct mutex lock;
>>> + struct regulator *vreg;
>>> + struct regmap *tcsr;
>>> + u32 gcnt;
>>> + u32 speed_bin;
>>> + u32 fusing_rev;
>>> + u32 last_uV;
>>> + u32 cpr_hw_rev;
>>> + u32 reg_corner;
>>> + u32 reg_corner_tid;
>>> + u32 reg_ctl;
>>> + u32 reg_status;
>>> + int fuse_level_set;
>>> + int extra_corners;
>>> + unsigned int vreg_step;
>>> + bool enabled;
>>> +
>>> + struct cpr_thread *threads;
>>> + struct genpd_onecell_data cell_data;
>>> +
>>> + const struct cpr_desc *desc;
>>> + const struct acc_desc *acc_desc;
>>> + struct dentry *debugfs;
>>> +};
>>> +
>>> +/**
>>> + * cpr_get_corner_post_vadj() - Get corner post-voltage adjustment values
>>> + * @opp: Pointer to the corresponding OPP struct
>>> + * @tid: CPR thread ID
>>> + * @open_loop: Pointer to the closed-loop adjustment value
>>> + * @closed_loop: Pointer to the open-loop adjustment value
>>> + */
>>> +void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
>>> + s32 *open_loop, s32 *closed_loop)
>>> +{
>>> + struct device_node *np;
>>> +
>>> + /*
>>> + * There is no of_property_read_s32_index, so we just store the
>>> + * result into a s32 variable. After all, the OF API is doing
>>> + * the exact same for of_property_read_s32...
>>> + */
>>> + np = dev_pm_opp_get_of_node(opp);
>>> + if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid, open_loop))
>>> + *open_loop = 0;
>>> +
>>> + if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid, closed_loop))
>>> + *closed_loop = 0;
>>> +
>>> + of_node_put(np);
>>> +}
>>> +
>>> +/**
>>> + * cpr_get_ro_factor() - Get fuse corner ring oscillator factor
>>> + * @tdesc: CPR Thread-specific parameters
>>> + * @fnum: Fuse corner
>>> + * @ro_idx: Ring Oscillator fuse number
>>> + *
>>> + * Not all threads have different scaling factors for each
>>> + * Fuse Corner: if the RO factors are the same for all corners,
>>> + * then only one is specified, instead of uselessly repeating
>>> + * the same array for FC-times.
>>> + * This function checks for the same and gives back the right
>>> + * factor for the requested ring oscillator.
>>> + *
>>> + * Return: Ring oscillator factor
>>> + */
>>> +static int cpr_get_ro_factor(const struct cpr_thread_desc *tdesc,
>>> + int fnum, int ro_idx)
>>> +{
>>> + int ro_fnum;
>>> +
>>> + if (tdesc->ro_avail_corners == tdesc->num_fuse_corners)
>>> + ro_fnum = fnum;
>>> + else
>>> + ro_fnum = 0;
>>> +
>>> + return tdesc->ro_scaling_factor[ro_fnum][ro_idx];
>>> +}
>>> +
>>> +static void cpr_write(struct cpr_thread *thread, u32 offset, u32 value)
>>> +{
>>> + writel(value, thread->base + offset);
>>> +}
>>> +
>>> +static u32 cpr_read(struct cpr_thread *thread, u32 offset)
>>> +{
>>> + return readl(thread->base + offset);
>>> +}
>>> +
>>> +static void
>>> +cpr_masked_write(struct cpr_thread *thread, u32 offset, u32 mask, u32 value)
>>> +{
>>> + u32 val;
>>> +
>>> + val = readl(thread->base + offset);
>>> + val &= ~mask;
>>> + val |= value & mask;
>>> + writel(val, thread->base + offset);
>>> +}
>>> +
>>> +static void cpr_irq_clr(struct cpr_thread *thread)
>>> +{
>>> + cpr_write(thread, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_ALL);
>>> +}
>>> +
>>> +static void cpr_irq_clr_nack(struct cpr_thread *thread)
>>> +{
>>> + cpr_irq_clr(thread);
>>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
>>> +}
>>> +
>>> +static void cpr_irq_clr_ack(struct cpr_thread *thread)
>>> +{
>>> + cpr_irq_clr(thread);
>>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_ACK);
>>> +}
>>> +
>>> +static void cpr_irq_set(struct cpr_thread *thread, u32 int_bits)
>>> +{
>>> + /* On CPR-hardened, interrupts are managed by and on firmware */
>>> + if (thread->drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>> + return;
>>> +
>>> + cpr_write(thread, CPR3_REG_IRQ_EN, int_bits);
>>> +}
>>> +
>>> +/**
>>> + * cpr_ctl_enable() - Enable CPR thread
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + */
>>> +static void cpr_ctl_enable(struct cpr_thread *thread)
>>> +{
>>> + if (thread->drv->enabled && !thread->restarting) {
>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * cpr_ctl_disable() - Disable CPR thread
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + */
>>> +static void cpr_ctl_disable(struct cpr_thread *thread)
>>> +{
>>> + const struct cpr_desc *desc = thread->drv->desc;
>>> +
>>> + if (desc->cpr_type != CTRL_TYPE_CPRH) {
>>> + cpr_irq_set(thread, 0);
>>> + cpr_irq_clr(thread);
>>> + }
>>> +
>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>> + CPR3_CPR_CTL_LOOP_EN_MASK, 0);
>>> +}
>>> +
>>> +/**
>>> + * cpr_ctl_is_enabled() - Check if thread is enabled
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Return: true if the CPR is enabled, false if it is disabled.
>>> + */
>>> +static bool cpr_ctl_is_enabled(struct cpr_thread *thread)
>>> +{
>>> + u32 reg_val;
>>> +
>>> + reg_val = cpr_read(thread, CPR3_REG_CPR_CTL);
>>> + return reg_val & CPR3_CPR_CTL_LOOP_EN_MASK;
>>> +}
>>> +
>>> +/**
>>> + * cpr_check_any_thread_busy() - Check if HW is done processing
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Return: true if the CPR is busy, false if it is ready.
>>> + */
>>> +static bool cpr_check_any_thread_busy(struct cpr_thread *thread)
>>> +{
>>> + int i;
>>> +
>>> + for (i = 0; i < thread->drv->desc->num_threads; i++)
>>> + if (cpr_read(thread, CPR3_REG_RESULT0(i)) &
>>> + CPR3_RESULT0_BUSY_MASK)
>>> + return true;
>>> +
>>> + return false;
>>> +}
>>> +
>>> +static void cpr_restart_worker(struct work_struct *work)
>>> +{
>>> + struct cpr_thread *thread = container_of(work, struct cpr_thread,
>>> + restart_work);
>>> + struct cpr_drv *drv = thread->drv;
>>> + int i;
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + thread->restarting = true;
>>> + cpr_ctl_disable(thread);
>>> + disable_irq(drv->irq);
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + for (i = 0; i < 20; i++) {
>>> + u32 cpr_status = cpr_read(thread, CPR3_REG_CPR_STATUS);
>>> + u32 ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>>> +
>>> + if ((cpr_status & CPR3_CPR_STATUS_BUSY_MASK) &&
>>> + !(ctl & CPR3_CPR_CTL_LOOP_EN_MASK))
>>> + break;
>>> +
>>> + udelay(10);
>>> + }
>>> +
>>> + cpr_irq_clr(thread);
>>> +
>>> + for (i = 0; i < 20; i++) {
>>> + u32 status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>> +
>>> + if (!(status & CPR3_IRQ_ALL))
>>> + break;
>>> + udelay(10);
>>> + }
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + thread->restarting = false;
>>> + enable_irq(drv->irq);
>>> + cpr_ctl_enable(thread);
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +}
>>> +
>>> +/**
>>> + * cpr_corner_restore() - Restore saved corner level
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + * @corner: Structure holding the saved corner level
>>> + */
>>> +static void cpr_corner_restore(struct cpr_thread *thread,
>>> + struct corner *corner)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + struct fuse_corner *fuse = corner->fuse_corner;
>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>> + u32 ro_sel = fuse->ring_osc_idx;
>>> +
>>> + cpr_write(thread, CPR3_REG_GCNT(ro_sel), drv->gcnt);
>>> +
>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid),
>>> + CPR3_RO_MASK & ~BIT(ro_sel));
>>> +
>>> + cpr_write(thread, CPR3_REG_TARGET_QUOT(tdesc->hw_tid, ro_sel),
>>> + fuse->quot - corner->quot_adjust);
>>> +
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR4)
>>> + cpr_masked_write(thread,
>>> + CPR4_REG_CPR_MASK_THREAD(tdesc->hw_tid),
>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK, 0);
>>> +
>>> + thread->corner = corner;
>>> + corner->last_uV = corner->uV;
>>> +}
>>> +
>>> +/**
>>> + * cpr_set_acc() - Set fuse level to the mem-acc
>>> + * @drv: Main driver structure
>>> + * @f: Fuse level
>>> + */
>>> +static void cpr_set_acc(struct cpr_drv *drv, int f)
>>> +{
>>> + const struct acc_desc *desc = drv->acc_desc;
>>> + struct reg_sequence *s = desc->settings;
>>> + int n = desc->num_regs_per_fuse;
>>> +
>>> + if (!s || f == drv->fuse_level_set)
>>> + return;
>>> +
>>> + regmap_multi_reg_write(drv->tcsr, s + (n * f), n);
>>> + drv->fuse_level_set = f;
>>> +}
>>> +
>>> +/**
>>> + * cpr_pre_voltage() - Actions to execute before setting voltage
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + * @dir: Enumeration for voltage change direction
>>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>>> + *
>>> + * Return: Zero for success or negative number on errors.
>>> + */
>>> +static int cpr_pre_voltage(struct cpr_thread *thread,
>>> + enum voltage_change_dir dir,
>>> + int fuse_level)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> +
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3 &&
>>> + drv->desc->pd_throttle_val)
>>> + cpr_write(thread, CPR3_REG_PD_THROTTLE,
>>> + drv->desc->pd_throttle_val);
>>> +
>>> + if (drv->tcsr && dir == DOWN)
>>> + cpr_set_acc(drv, fuse_level);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr_post_voltage() - Actions to execute after setting voltage
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + * @dir: Enumeration for voltage change direction
>>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>>> + *
>>> + * Return: Zero for success or negative number on errors.
>>> + */
>>> +static int cpr_post_voltage(struct cpr_thread *thread,
>>> + enum voltage_change_dir dir,
>>> + int fuse_level)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> +
>>> + if (drv->tcsr && dir == UP)
>>> + cpr_set_acc(drv, fuse_level);
>>> +
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3)
>>> + cpr_write(thread, CPR3_REG_PD_THROTTLE, 0);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr_commit_state() - Set the newly requested voltage
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>>> + */
>>> +static int cpr_commit_state(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + int min_uV = 0, max_uV = 0, new_uV = 0, fuse_level = 0;
>>> + enum voltage_change_dir dir;
>>> + u32 next_irqmask = 0;
>>> + int ret, i;
>>> +
>>> + /* On CPRhardened, control states are managed in firmware */
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>> + return 0;
>>> +
>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>> + struct cpr_thread *thread = &drv->threads[i];
>>> +
>>> + if (!thread->corner)
>>> + continue;
>>> +
>>> + fuse_level = max(fuse_level,
>>> + (int) (thread->corner->fuse_corner -
>>> + &thread->fuse_corners[0]));
>>> +
>>> + max_uV = max(max_uV, thread->corner->max_uV);
>>> + min_uV = max(min_uV, thread->corner->min_uV);
>>> + new_uV = max(new_uV, thread->corner->last_uV);
>>> + }
>>> + dev_vdbg(drv->dev, "%s: new uV: %d, last uV: %d\n",
>>> + __func__, new_uV, drv->last_uV);
>>> +
>>> + /*
>>> + * Safety measure: if the voltage is out of the globally allowed
>>> + * range, then go out and warn the user.
>>> + * This should *never* happen.
>>> + */
>>> + if (new_uV > drv->desc->cpr_max_voltage ||
>>> + new_uV < drv->desc->cpr_base_voltage) {
>>> + dev_warn(drv->dev, "Voltage (%u uV) out of range.", new_uV);
>>> + return -EINVAL;
>>> + }
>>> +
>>> + if (new_uV == drv->last_uV || fuse_level == drv->fuse_level_set)
>>> + goto out;
>>> +
>>> + if (fuse_level > drv->fuse_level_set)
>>> + dir = UP;
>>> + else
>>> + dir = DOWN;
>>> +
>>> + ret = cpr_pre_voltage(thread, fuse_level, dir);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + dev_vdbg(drv->dev, "setting voltage: %d\n", new_uV);
>>> +
>>> + ret = regulator_set_voltage(drv->vreg, new_uV, new_uV);
>>> + if (ret) {
>>> + dev_err_ratelimited(drv->dev, "failed to set voltage %d: %d\n", new_uV, ret);
>>> + return ret;
>>> + }
>>> +
>>> + ret = cpr_post_voltage(thread, fuse_level, dir);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + drv->last_uV = new_uV;
>>> +out:
>>> + if (new_uV > min_uV)
>>> + next_irqmask |= CPR3_IRQ_DOWN;
>>> + if (new_uV < max_uV)
>>> + next_irqmask |= CPR3_IRQ_UP;
>>> +
>>> + cpr_irq_set(thread, next_irqmask);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static unsigned int cpr_get_cur_perf_state(struct cpr_thread *thread)
>>> +{
>>> + return thread->corner ? thread->corner - thread->corners + 1 : 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr_scale() - Calculate new voltage for the received direction
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + * @dir: Enumeration for voltage change direction
>>> + *
>>> + * The CPR scales one by one: this function calculates the new
>>> + * voltage to set when a voltage-UP or voltage-DOWN request comes
>>> + * and stores it into the per-thread structure that gets passed.
>>> + */
>>> +static void cpr_scale(struct cpr_thread *thread, enum voltage_change_dir dir)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>> + u32 val, error_steps;
>>> + int last_uV, new_uV;
>>> + struct corner *corner;
>>> +
>>> + if (dir != UP && dir != DOWN)
>>> + return;
>>> +
>>> + corner = thread->corner;
>>> + val = cpr_read(thread, CPR3_REG_RESULT0(tdesc->hw_tid));
>>> + error_steps = val >> CPR3_RESULT0_ERROR_STEPS_SHIFT;
>>> + error_steps &= CPR3_RESULT0_ERROR_STEPS_MASK;
>>> +
>>> + last_uV = corner->last_uV;
>>> +
>>> + if (dir == UP) {
>>> + if (!(val & CPR3_RESULT0_STEP_UP_MASK))
>>> + return;
>>> +
>>> + /* Calculate new voltage */
>>> + new_uV = last_uV + drv->vreg_step;
>>> + new_uV = min(new_uV, corner->max_uV);
>>> +
>>> + dev_vdbg(drv->dev, "[T%u] UP - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>>> + thread->id, new_uV, last_uV,
>>> + cpr_get_cur_perf_state(thread), error_steps);
>>> + } else {
>>> + if (!(val & CPR3_RESULT0_STEP_DN_MASK))
>>> + return;
>>> +
>>> + /* Calculate new voltage */
>>> + new_uV = last_uV - drv->vreg_step;
>>> + new_uV = max(new_uV, corner->min_uV);
>>> + dev_vdbg(drv->dev, "[T%u] DOWN - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>>> + thread->id, new_uV, last_uV,
>>> + cpr_get_cur_perf_state(thread), error_steps);
>>> + }
>>> + corner->last_uV = new_uV;
>>> +}
>>> +
>>> +/**
>>> + * cpr_irq_handler() - Handle CPR3/CPR4 status interrupts
>>> + * @irq: Number of the interrupt
>>> + * @dev: Pointer to the cpr_thread structure
>>> + *
>>> + * Handle the interrupts coming from non-hardened CPR HW as to get
>>> + * an ok to scale voltages immediately, or to pass error status to
>>> + * the hardware (either success/ACK or failure/NACK).
>>> + *
>>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>>> + */
>>> +static irqreturn_t cpr_irq_handler(int irq, void *dev)
>>> +{
>>> + struct cpr_thread *thread = dev;
>>> + struct cpr_drv *drv = thread->drv;
>>> + irqreturn_t ret = IRQ_HANDLED;
>>> + int i, rc;
>>> + enum voltage_change_dir dir = NO_CHANGE;
>>> + u32 val;
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + val = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>> +
>>> + dev_vdbg(drv->dev, "IRQ_STATUS = %#02x\n", val);
>>> +
>>> + if (!cpr_ctl_is_enabled(thread)) {
>>> + dev_vdbg(drv->dev, "CPR is disabled\n");
>>> + ret = IRQ_NONE;
>>> + } else if (cpr_check_any_thread_busy(thread)) {
>>> + cpr_irq_clr_nack(thread);
>>> + dev_dbg(drv->dev, "CPR measurement is not ready\n");
>>> + } else {
>>> + /*
>>> + * Following sequence of handling is as per each IRQ's
>>> + * priority
>>> + */
>>> + if (val & CPR3_IRQ_UP)
>>> + dir = UP;
>>> + else if (val & CPR3_IRQ_DOWN)
>>> + dir = DOWN;
>>> +
>>> + if (dir != NO_CHANGE) {
>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>> + thread = &drv->threads[i];
>>> + cpr_scale(thread, dir);
>>> + }
>>> +
>>> + rc = cpr_commit_state(thread);
>>> + if (rc)
>>> + cpr_irq_clr_nack(thread);
>>> + else
>>> + cpr_irq_clr_ack(thread);
>>> + } else if (val & CPR3_IRQ_MID) {
>>> + dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n");
>>> + } else {
>>> + dev_warn(drv->dev, "IRQ occurred for unknown flag (%#08x)\n", val);
>>> + schedule_work(&thread->restart_work);
>>> + }
>>> + }
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +static int cpr_switch(struct cpr_drv *drv)
>>> +{
>>> + int i, ret;
>>> + bool enabled = false;
>>> +
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>> + return 0;
>>> +
>>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>>> + enabled = drv->threads[i].enabled;
>>> +
>>> + dev_vdbg(drv->dev, "%s: enabled = %d\n", __func__, enabled);
>>> +
>>> + if (enabled == drv->enabled)
>>> + return 0;
>>> +
>>> + if (enabled) {
>>> + ret = regulator_enable(drv->vreg);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + drv->enabled = enabled;
>>> +
>>> + for (i = 0; i < drv->desc->num_threads; i++)
>>> + if (drv->threads[i].corner)
>>> + break;
>>> +
>>> + if (i < drv->desc->num_threads) {
>>> + cpr_irq_clr(&drv->threads[i]);
>>> +
>>> + cpr_commit_state(&drv->threads[i]);
>>> + cpr_ctl_enable(&drv->threads[i]);
>>> + }
>>> + } else {
>>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>>> + cpr_ctl_disable(&drv->threads[i]);
>>> +
>>> + drv->enabled = enabled;
>>> +
>>> + ret = regulator_disable(drv->vreg);
>>> + if (ret < 0)
>>> + return ret;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr_enable() - Enables a CPR thread
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Return: Zero for success or negative number on errors.
>>> + */
>>> +static int cpr_enable(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + int ret;
>>> +
>>> + dev_dbg(drv->dev, "Enabling thread %d\n", thread->id);
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + thread->enabled = true;
>>> + ret = cpr_switch(thread->drv);
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * cpr_disable() - Disables a CPR thread
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Return: Zero for success or negative number on errors.
>>> + */
>>> +static int cpr_disable(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + int ret;
>>> +
>>> + dev_dbg(drv->dev, "Disabling thread %d\n", thread->id);
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + thread->enabled = false;
>>> + ret = cpr_switch(thread->drv);
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * cpr_configure() - Configure main HW parameters
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * This function configures the main CPR hardware parameters, such as
>>> + * internal timers (and delays), sensor ownerships, activates and/or
>>> + * deactivates cpr-threads and others, as one sequence for all of the
>>> + * versions supported in this driver. By design, the function may
>>> + * return a success earlier if the sequence for "a previous version"
>>> + * has ended.
>>> + *
>>> + * Context: The CPR must be clocked before calling this function!
>>> + *
>>> + * Return: Zero for success or negative number on errors.
>>> + */
>>> +static int cpr_configure(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + const struct cpr_desc *desc = drv->desc;
>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>> + u32 val;
>>> + int i;
>>> +
>>> + /* Disable interrupt and CPR */
>>> + cpr_irq_set(thread, 0);
>>> + cpr_write(thread, CPR3_REG_CPR_CTL, 0);
>>> +
>>> + /* Init and save gcnt */
>>> + drv->gcnt = drv->ref_clk_khz * desc->gcnt_us;
>>> + do_div(drv->gcnt, 1000);
>>> +
>>> + /* Program the delay count for the timer */
>>> + val = drv->ref_clk_khz * desc->timer_delay_us;
>>> + do_div(val, 1000);
>>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_MID_CONT, val);
>>> +
>>> + val = drv->ref_clk_khz * desc->timer_updn_delay_us;
>>> + do_div(val, 1000);
>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_UP_DN_CONT, val);
>>> + } else {
>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_AUTO_CONT, val);
>>> + }
>>> + dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val,
>>> + desc->timer_delay_us);
>>> +
>>> + /* Program the control register */
>>> + val = desc->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT;
>>> + val |= desc->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT;
>>> + val |= desc->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT;
>>> + cpr_write(thread, CPR3_REG_CPR_CTL, val);
>>> +
>>> + /* Configure CPR default step quotients */
>>> + val = tdesc->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT;
>>> + val |= tdesc->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT;
>>> +
>>> + cpr_write(thread, CPR3_REG_CPR_STEP_QUOT, val);
>>> +
>>> + /*
>>> + * Configure the CPR sensor ownership always on thread 0
>>> + * TODO: SDM845 has different ownership for sensors!!
>>> + */
>>> + for (i = tdesc->sensor_range_start; i < tdesc->sensor_range_end; i++)
>>> + cpr_write(thread, CPR3_REG_SENSOR_OWNER(i), 0);
>>> +
>>> + /* Program Consecutive Up & Down */
>>> + val = desc->timer_cons_up << CPR3_THRESH_CONS_UP_SHIFT;
>>> + val |= desc->timer_cons_down << CPR3_THRESH_CONS_DOWN_SHIFT;
>>> + val |= desc->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT;
>>> + val |= desc->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT;
>>> + cpr_write(thread, CPR3_REG_THRESH(tdesc->hw_tid), val);
>>> +
>>> + /* Mask all ring oscillators for all threads initially */
>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), CPR3_RO_MASK);
>>> +
>>> + /* HW Closed-loop control */
>>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>>> + cpr_write(thread, CPR3_REG_HW_CLOSED_LOOP_DISABLED,
>>> + !desc->hw_closed_loop_en);
>>> + } else {
>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN,
>>> + desc->hw_closed_loop_en ?
>>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN : 0);
>>> + }
>>> +
>>> + /* Additional configuration for CPR4 and beyond */
>>> + if (desc->cpr_type < CTRL_TYPE_CPR4)
>>> + return 0;
>>> +
>>> + /* Disable threads initially only on non-hardened CPR4 */
>>> + if (desc->cpr_type == CTRL_TYPE_CPR4)
>>> + cpr_masked_write(thread, CPR4_REG_CPR_MASK_THREAD(1),
>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
>>> +
>>> + if (tdesc->hw_tid > 0)
>>> + cpr_masked_write(thread, CPR4_REG_MISC,
>>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN,
>>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN);
>>> +
>>> + val = drv->vreg_step;
>>> + do_div(val, 1000);
>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>> + CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK,
>>> + val << CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT);
>>> +
>>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
>>> + desc->vreg_step_down_limit <<
>>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT);
>>> +
>>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
>>> + desc->vreg_step_up_limit <<
>>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT);
>>> +
>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN,
>>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN);
>>> +
>>> + if (tdesc->hw_tid > 0)
>>> + cpr_masked_write(thread, CPR4_REG_CPR_TIMER_CLAMP,
>>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
>>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
>>> +
>>> + /* Settling timer to account for one VDD supply step */
>>> + if (desc->vdd_settle_time_us > 0) {
>>> + u32 m = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK;
>>> + u32 s = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT;
>>> +
>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
>>> + m, desc->vdd_settle_time_us << s);
>>> + }
>>> +
>>> + /* Additional configuration for CPR-hardened */
>>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>>> + return 0;
>>> +
>>> + /* Settling timer to account for one corner-switch request */
>>> + if (desc->corner_settle_time_us > 0)
>>> + cpr_masked_write(thread, drv->reg_ctl,
>>> + CPRH_CTL_MODE_SWITCH_DELAY_MASK,
>>> + desc->corner_settle_time_us <<
>>> + CPRH_CTL_MODE_SWITCH_DELAY_SHIFT);
>>> +
>>> + /* Base voltage and multiplier values for CPRh internal calculations */
>>> + cpr_masked_write(thread, drv->reg_ctl,
>>> + CPRH_CTL_BASE_VOLTAGE_MASK,
>>> + (DIV_ROUND_UP(desc->cpr_base_voltage,
>>> + drv->vreg_step) <<
>>> + CPRH_CTL_BASE_VOLTAGE_SHIFT));
>>> +
>>> + cpr_masked_write(thread, drv->reg_ctl,
>>> + CPRH_CTL_VOLTAGE_MULTIPLIER_MASK,
>>> + DIV_ROUND_UP(drv->vreg_step, 1000) <<
>>> + CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int cprh_dummy_set_performance_state(struct generic_pm_domain *domain,
>>> + unsigned int state)
>>> +{
>>> + return 0;
>>> +}
>>> +
>>> +static int cpr_set_performance_state(struct generic_pm_domain *domain,
>>> + unsigned int state)
>>> +{
>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>> + struct cpr_drv *drv = thread->drv;
>>> + struct corner *corner, *end;
>>> + int ret = 0;
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + dev_dbg(drv->dev, "setting perf state: %u (prev state: %u thread: %u)\n",
>>> + state, cpr_get_cur_perf_state(thread), thread->id);
>>> +
>>> + /*
>>> + * Determine new corner we're going to.
>>> + * Remove one since lowest performance state is 1.
>>> + */
>>> + corner = thread->corners + state - 1;
>>> + end = &thread->corners[thread->num_corners - 1];
>>> + if (corner > end || corner < thread->corners) {
>>> + ret = -EINVAL;
>>> + goto unlock;
>>> + }
>>> +
>>> + cpr_ctl_disable(thread);
>>> +
>>> + cpr_irq_clr(thread);
>>> + if (thread->corner != corner)
>>> + cpr_corner_restore(thread, corner);
>>> +
>>> + ret = cpr_commit_state(thread);
>>> + if (ret)
>>> + goto unlock;
>>> +
>>> + cpr_ctl_enable(thread);
>>> +unlock:
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + dev_dbg(drv->dev, "set perf state %u on thread %u\n", state, thread->id);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * cpr3_adjust_quot - Adjust the closed-loop quotients
>>> + * @ring_osc_factor: Ring oscillator adjustment factor
>>> + * @volt_closed_loop: Closed-loop voltage adjustment factor
>>> + *
>>> + * Calculates the quotient adjustment factor based on closed-loop
>>> + * quotients and ring oscillator factor.
>>> + *
>>> + * Return: Adjusted quotient
>>> + */
>>> +static int cpr3_adjust_quot(int ring_osc_factor, int volt_closed_loop)
>>> +{
>>> + s64 temp;
>>> +
>>> + if (ring_osc_factor == 0 || volt_closed_loop == 0)
>>> + return 0;
>>> +
>>> + temp = (s64)(ring_osc_factor * volt_closed_loop);
>>> + return (int)div_s64(temp, 1000000);
>>> +}
>>> +
>>> +/**
>>> + * cpr_fuse_corner_init() - Calculate fuse corner table
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * This function populates the fuse corners table by reading the
>>> + * values from the fuses, eventually adjusting them with a fixed
>>> + * per-corner offset and doing basic checks about them being
>>> + * supported by the regulator that is assigned to this CPR - if
>>> + * it is available (on CPR-Hardened, there is no usable vreg, as
>>> + * that is protected by the hypervisor).
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr_fuse_corner_init(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + const struct cpr_thread_desc *desc = thread->desc;
>>> + const struct cpr_fuse *cpr_fuse = thread->cpr_fuses;
>>> + struct fuse_corner_data *fdata;
>>> + struct fuse_corner *fuse, *prev_fuse, *end;
>>> + int i, ret;
>>> +
>>> + /* Populate fuse_corner members */
>>> + fuse = thread->fuse_corners;
>>> + prev_fuse = &fuse[0];
>>> + end = &fuse[desc->num_fuse_corners - 1];
>>> + fdata = desc->fuse_corner_data;
>>> +
>>> + for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
>>> + int factor = cpr_get_ro_factor(desc, i, fuse->ring_osc_idx);
>>> +
>>> + ret = cpr_populate_fuse_common(drv->dev, fdata, cpr_fuse,
>>> + fuse, drv->vreg_step,
>>> + desc->init_voltage_width,
>>> + desc->init_voltage_step);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /*
>>> + * Adjust the fuse quot with per-fuse-corner closed-loop
>>> + * voltage adjustment parameters.
>>> + */
>>> + fuse->quot += cpr3_adjust_quot(factor, fdata->volt_cloop_adjust);
>>> +
>>> + /* CPRh: no regulator access... */
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>> + goto skip_pvs_restrict;
>>> +
>>> + /* Re-check if corner voltage range is supported by regulator */
>>> + ret = cpr_check_vreg_constraints(drv->dev, drv->vreg, fuse);
>>> + if (ret)
>>> + return ret;
>>> +
>>> +skip_pvs_restrict:
>>> + if (fuse->uV < prev_fuse->uV)
>>> + fuse->uV = prev_fuse->uV;
>>> + prev_fuse = fuse;
>>> + dev_dbg(drv->dev, "fuse corner %d: [%d %d %d] RO%hhu quot %d\n",
>>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>>> + fuse->ring_osc_idx, fuse->quot);
>>> +
>>> + /* Check if constraints are valid */
>>> + if (fuse->uV < fuse->min_uV || fuse->uV > fuse->max_uV) {
>>> + dev_err(drv->dev, "fuse corner %d: Bad voltage range.\n", i);
>>> + return -EINVAL;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void cpr3_restrict_corner(struct corner *corner, int threshold,
>>> + int hysteresis, int step)
>>> +{
>>> + if (threshold > corner->min_uV && threshold <= corner->max_uV) {
>>> + if (corner->uV >= threshold) {
>>> + corner->min_uV = max(corner->min_uV,
>>> + threshold - hysteresis);
>>> + if (corner->min_uV > corner->uV)
>>> + corner->uV = corner->min_uV;
>>> + } else {
>>> + corner->max_uV = threshold;
>>> + corner->max_uV -= step;
>>> + }
>>> + }
>>> +}
>>> +
>>> +/*
>>> + * cprh_corner_adjust_opps() - Set voltage on each CPU OPP table entry
>>> + *
>>> + * On CPR-Hardened, the voltage level is controlled internally through
>>> + * the OSM hardware: in order to initialize the latter, we have to
>>> + * communicate the voltage to its driver, so that it will be able to
>>> + * write the right parameters (as they have to be set both on the CPRh
>>> + * and on the OSM) on it.
>>> + * This function is called only for CPRh.
>>> + *
>>> + * Return: Zero for success, negative number for error.
>>> + */
>>> +static int cprh_corner_adjust_opps(struct cpr_thread *thread)
>>> +{
>>> + struct corner *corner = thread->corners;
>>> + struct cpr_drv *drv = thread->drv;
>>> + int i, ret;
>>> +
>>> + for (i = 0; i < thread->num_corners; i++) {
>>> + ret = dev_pm_opp_adjust_voltage(thread->attached_cpu_dev,
>>> + corner[i].freq,
>>> + corner[i].uV,
>>> + corner[i].min_uV,
>>> + corner[i].max_uV);
>>> + if (ret)
>>> + break;
>>> +
>>> + dev_dbg(drv->dev, "OPP voltage adjusted for %lu kHz, %d uV\n",
>>> + corner[i].freq, corner[i].uV);
>>> + }
>>> +
>>> + /* If we couldn't adjust voltage for all corners, something went wrong */
>>> + if (i < thread->num_corners)
>>> + return -EINVAL;
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * cpr3_corner_init() - Calculate and set-up corners for the CPR HW
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * This function calculates all the corner parameters by comparing
>>> + * and interpolating the values read from the various set-points
>>> + * read from the fuses (also called "fuse corners") to generate and
>>> + * program to the CPR a lookup table that describes each voltage
>>> + * step, mapped to a performance level (or corner number).
>>> + *
>>> + * It also programs other essential parameters on the CPR and - if
>>> + * we are dealing with CPR-Hardened, it will also enable the internal
>>> + * interface between the Operating State Manager (OSM) and the CPRh
>>> + * in order to achieve CPU DVFS.
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr3_corner_init(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + const struct cpr_desc *desc = drv->desc;
>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>> + const struct cpr_fuse *fuses = thread->cpr_fuses;
>>> + int i, ret, total_corners, extra_corners, level, scaling = 0;
>>> + unsigned int fnum, fc;
>>> + const char *quot_offset;
>>> + const struct fuse_corner_data *fdata;
>>> + struct fuse_corner *fuse, *prev_fuse;
>>> + struct corner *corner, *prev_corner, *end;
>>> + struct corner_data *cdata;
>>> + struct dev_pm_opp *opp;
>>> + unsigned long freq;
>>> + u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
>>> +
>>> + corner = thread->corners;
>>> + prev_corner = &thread->corners[0];
>>> + end = &corner[thread->num_corners - 1];
>>> +
>>> + cdata = devm_kcalloc(drv->dev, thread->num_corners + drv->extra_corners,
>>> + sizeof(struct corner_data), GFP_KERNEL);
>>> + if (!cdata)
>>> + return -ENOMEM;
>>> +
>>> + for (level = 1; level <= thread->num_corners; level++) {
>>> + opp = dev_pm_opp_find_level_exact(&thread->pd.dev, level);
>>> + if (IS_ERR(opp))
>>> + return -EINVAL;
>>> +
>>> + /*
>>> + * If there is only one specified qcom,opp-fuse-level, then
>>> + * it is assumed that this only one is global and valid for
>>> + * all IDs, so try to get the specific one but, on failure,
>>> + * go for the global one.
>>> + */
>>> + fc = cpr_get_fuse_corner(opp, thread->id);
>>> + if (fc == 0) {
>>> + fc = cpr_get_fuse_corner(opp, 0);
>>> + if (fc == 0) {
>>> + dev_err(drv->dev, "qcom,opp-fuse-level is missing!\n");
>>> + dev_pm_opp_put(opp);
>>> + return -EINVAL;
>>> + }
>>> + }
>>> + fnum = fc - 1;
>>> +
>>> + freq = cpr_get_opp_hz_for_req(opp, thread->attached_cpu_dev);
>>> + if (!freq) {
>>> + thread->num_corners = max(level - 1, 0);
>>> + end = &thread->corners[thread->num_corners - 1];
>>> + break;
>>> + }
>>> +
>>> + /*
>>> + * If any post-vadj (open/closed loop) is not specified, then
>>> + * it's zero, meaning that it is not required for this corner.
>>> + */
>>> + cpr_get_corner_post_vadj(opp, thread->id,
>>> + &cdata[level - 1].oloop_vadj,
>>> + &cdata[level - 1].cloop_vadj);
>>> + cdata[level - 1].fuse_corner = fnum;
>>> + cdata[level - 1].freq = freq;
>>> +
>>> + fuse = &thread->fuse_corners[fnum];
>>> + dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n",
>>> + freq, dev_pm_opp_get_level(opp) - 1, fnum);
>>> + if (freq > fuse->max_freq)
>>> + fuse->max_freq = freq;
>>> + dev_pm_opp_put(opp);
>>> +
>>> + /*
>>> + * Make sure that the frequencies in the table are in ascending
>>> + * order, as this is critical for the algorithm to work.
>>> + */
>>> + if (cdata[level - 2].freq > freq) {
>>> + dev_err(drv->dev, "Frequency table not in ascending order.\n");
>>> + return -EINVAL;
>>> + }
>>> + }
>>> +
>>> + if (thread->num_corners < 2) {
>>> + dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
>>> + return -EINVAL;
>>> + }
>>> +
>>> + /*
>>> + * Get the quotient adjustment scaling factor, according to:
>>> + *
>>> + * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
>>> + * / (freq(corner_N) - freq(corner_N-1)), max_factor)
>>> + *
>>> + * QUOT(corner_N): quotient read from fuse for fuse corner N
>>> + * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1)
>>> + * freq(corner_N): max frequency in MHz supported by fuse corner N
>>> + * freq(corner_N-1): max frequency in MHz supported by fuse corner
>>> + * (N - 1)
>>> + *
>>> + * Then walk through the corners mapped to each fuse corner
>>> + * and calculate the quotient adjustment for each one using the
>>> + * following formula:
>>> + *
>>> + * quot_adjust = (freq_max - freq_corner) * scaling / 1000
>>> + *
>>> + * freq_max: max frequency in MHz supported by the fuse corner
>>> + * freq_corner: frequency in MHz corresponding to the corner
>>> + * scaling: calculated from above equation
>>> + *
>>> + *
>>> + * + +
>>> + * | v |
>>> + * q | f c o | f c
>>> + * u | c l | c
>>> + * o | f t | f
>>> + * t | c a | c
>>> + * | c f g | c f
>>> + * | e |
>>> + * +--------------- +----------------
>>> + * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
>>> + * corner corner
>>> + *
>>> + * c = corner
>>> + * f = fuse corner
>>> + *
>>> + */
>>> + for (i = 0; corner <= end; corner++, i++) {
>>> + unsigned long freq_diff_mhz;
>>> + int ro_fac, vadj, prev_quot;
>>> +
>>> + fnum = cdata[i].fuse_corner;
>>> + fdata = &tdesc->fuse_corner_data[fnum];
>>> + quot_offset = fuses[fnum].quotient_offset;
>>> + fuse = &thread->fuse_corners[fnum];
>>> + ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
>>> + if (fnum)
>>> + prev_fuse = &thread->fuse_corners[fnum - 1];
>>> + else
>>> + prev_fuse = NULL;
>>> +
>>> + corner->fuse_corner = fuse;
>>> + corner->freq = cdata[i].freq;
>>> + corner->uV = fuse->uV;
>>> +
>>> + if (prev_fuse) {
>>> + if (prev_fuse->ring_osc_idx == fuse->ring_osc_idx)
>>> + quot_offset = NULL;
>>> +
>>> + scaling = cpr_calculate_scaling(drv->dev, quot_offset,
>>> + fdata, corner);
>>> + if (scaling < 0)
>>> + return scaling;
>>> +
>>> + freq_diff_mhz = fuse->max_freq - corner->freq;
>>> + do_div(freq_diff_mhz, 1000000); /* now in MHz */
>>> +
>>> + corner->quot_adjust = scaling * freq_diff_mhz;
>>> + do_div(corner->quot_adjust, 1000);
>>> +
>>> + /* Fine-tune QUOT (closed-loop) based on fixed values */
>>> + ro_fac = cpr_get_ro_factor(tdesc, fnum, fuse->ring_osc_idx);
>>> + vadj = cdata[i].cloop_vadj;
>>> + corner->quot_adjust -= cpr3_adjust_quot(ro_fac, vadj);
>>> + dev_vdbg(drv->dev, "Quot fine-tuning to %d for post-vadj=%d\n",
>>> + corner->quot_adjust, vadj);
>>> +
>>> + /*
>>> + * Make sure that we scale (up) monotonically.
>>> + * P.S.: Fuse quots can never be descending.
>>> + */
>>> + prev_quot = prev_corner->fuse_corner->quot;
>>> + prev_quot -= prev_corner->quot_adjust;
>>> + if (fuse->quot - corner->quot_adjust < prev_quot) {
>>> + int new_adj = prev_corner->fuse_corner->quot;
>>> +
>>> + new_adj -= fuse->quot;
>>> + dev_vdbg(drv->dev, "Monotonic increase forced: %d->%d\n",
>>> + corner->quot_adjust, new_adj);
>>> + corner->quot_adjust = new_adj;
>>> + }
>>> +
>>> + corner->uV = cpr_interpolate(corner,
>>> + drv->vreg_step, fdata);
>>> + }
>>> + /* Negative fuse quotients are nonsense. */
>>> + if (fuse->quot < corner->quot_adjust)
>>> + return -EINVAL;
>>> +
>>> + min_quotient = min(min_quotient,
>>> + (u32)(fuse->quot - corner->quot_adjust));
>>> +
>>> + /* Fine-tune voltages (open-loop) based on fixed values */
>>> + corner->uV += cdata[i].oloop_vadj;
>>> + dev_dbg(drv->dev, "Voltage fine-tuning to %d for post-vadj=%d\n",
>>> + corner->uV, cdata[i].oloop_vadj);
>>> +
>>> + corner->max_uV = fuse->max_uV;
>>> + corner->min_uV = fuse->min_uV;
>>> + corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV);
>>> + dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d %d]\n",
>>> + corner->min_uV, corner->uV, corner->max_uV);
>>> +
>>> + /* Make sure that we scale monotonically here, too. */
>>> + if (corner->uV < prev_corner->uV)
>>> + corner->uV = prev_corner->uV;
>>> +
>>> + corner->last_uV = corner->uV;
>>> +
>>> + /* Reduce the ceiling voltage if needed */
>>> + if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV)
>>> + corner->max_uV = corner->uV;
>>> + else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV)
>>> + corner->max_uV = max(corner->min_uV, fuse->uV);
>>> +
>>> + corner->min_uV = max(corner->max_uV - fdata->range_uV,
>>> + corner->min_uV);
>>> +
>>> + /*
>>> + * Adjust per-corner floor and ceiling voltages so that
>>> + * they do not overlap the memory Array Power Mux (APM)
>>> + * nor the Memory Accelerator (MEM-ACC) threshold voltages.
>>> + */
>>> + if (desc->apm_threshold)
>>> + cpr3_restrict_corner(corner, desc->apm_threshold,
>>> + desc->apm_hysteresis,
>>> + drv->vreg_step);
>>> + if (desc->mem_acc_threshold)
>>> + cpr3_restrict_corner(corner, desc->mem_acc_threshold,
>>> + 0, drv->vreg_step);
>>> +
>>> + prev_corner = corner;
>>> + dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d quot %d\n", i,
>>> + corner->min_uV, corner->uV, corner->max_uV, scaling,
>>> + fuse->quot - corner->quot_adjust);
>>> + }
>>> +
>>> + /* Additional setup for CPRh only */
>>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>>> + return 0;
>>> +
>>> + /* If the OPPs can't be adjusted, programming the CPRh is useless */
>>> + ret = cprh_corner_adjust_opps(thread);
>>> + if (ret) {
>>> + dev_err(drv->dev, "Cannot adjust CPU OPP voltages: %d\n", ret);
>>> + return ret;
>>> + }
>>> +
>>> + total_corners = thread->num_corners;
>>> + extra_corners = drv->extra_corners;
>>> +
>>> + /* If the APM extra corner exists, add it now. */
>>> + if (desc->apm_crossover && desc->apm_threshold && extra_corners) {
>>> + /* Program the APM crossover corner on the CPR-Hardened */
>>> + thread->corners[total_corners].uV = desc->apm_crossover;
>>> + thread->corners[total_corners].min_uV = desc->apm_crossover;
>>> + thread->corners[total_corners].max_uV = desc->apm_crossover;
>>> + thread->corners[total_corners].is_open_loop = true;
>>> +
>>> + /*
>>> + * We have calculated the APM parameters for this clock plan:
>>> + * make the APM *threshold* available to external callers.
>>> + * The crossover is used only internally in the CPR.
>>> + */
>>> + thread->ext_data.apm_threshold_uV = desc->apm_threshold;
>>> +
>>> + dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] Open-Loop\n",
>>> + total_corners, desc->apm_crossover,
>>> + desc->apm_crossover, desc->apm_crossover);
>>> +
>>> + total_corners++;
>>> + extra_corners--;
>>> + }
>>> +
>>> + if (desc->mem_acc_threshold && extra_corners) {
>>> + /* Program the Memory Accelerator threshold corner to CPRh */
>>> + thread->corners[total_corners].uV = desc->mem_acc_threshold;
>>> + thread->corners[total_corners].min_uV = desc->mem_acc_threshold;
>>> + thread->corners[total_corners].max_uV = desc->mem_acc_threshold;
>>> + thread->corners[total_corners].is_open_loop = true;
>>> +
>>> + /*
>>> + * We have calculated a mem-acc threshold for this clock plan:
>>> + * make it available to external callers.
>>> + */
>>> + thread->ext_data.mem_acc_threshold_uV = desc->mem_acc_threshold;
>>> +
>>> + dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] Open-Loop\n",
>>> + total_corners, desc->mem_acc_threshold,
>>> + desc->mem_acc_threshold, desc->mem_acc_threshold);
>>> +
>>> + total_corners++;
>>> + extra_corners--;
>>> + }
>>> +
>>> + /*
>>> + * If there are any extra corners left, it means that even though we
>>> + * expect to fill in both APM and MEM-ACC crossovers, one couldn't
>>> + * satisfy requirements, which means that the specified parameters
>>> + * are wrong: in this case, inform the user and bail out, otherwise
>>> + * if we go on writing the (invalid) table to the CPR-Hardened, the
>>> + * hardware (in this case, the CPU) will surely freeze and crash.
>>> + */
>>> + if (unlikely(extra_corners)) {
>>> + dev_err(drv->dev, "APM/MEM-ACC corners: bad parameters.\n");
>>> + return -EINVAL;
>>> + }
>>> + /* Reassign extra_corners, as we have to exclude delta_quot for them */
>>> + extra_corners = drv->extra_corners;
>>> +
>>> + /* Disable the interface between OSM and CPRh */
>>> + cpr_masked_write(thread, drv->reg_ctl,
>>> + CPRH_CTL_OSM_ENABLED, 0);
>>> +
>>> + /* Program the GCNT before unmasking ring oscillator(s) */
>>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>>> + if (!(ring_osc_mask & BIT(i))) {
>>> + cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
>>> + dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, drv->gcnt);
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * Unmask the ring oscillator(s) that we're going to use: it seems
>>> + * to be mandatory to do this *before* sending the rest of the
>>> + * CPRhardened specific configuration.
>>> + */
>>> + dev_dbg(drv->dev, "Unmasking ring oscillators with mask 0x%x\n", ring_osc_mask);
>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), ring_osc_mask);
>>> +
>>> + /* Setup minimum quotients for ring oscillators */
>>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>>> + u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, i);
>>> + u32 tgt_quot_val = 0;
>>> +
>>> + if (!(ring_osc_mask & BIT(i)))
>>> + tgt_quot_val = min_quotient;
>>> +
>>> + cpr_write(thread, tgt_quot_reg, tgt_quot_val);
>>> + dev_vdbg(drv->dev, "Programmed min quotient %u for Ring Oscillator %d\n",
>>> + tgt_quot_val, tgt_quot_reg);
>>> + }
>>> +
>>> + for (i = 0; i < total_corners; i++) {
>>> + int volt_oloop_steps, volt_floor_steps, delta_quot_steps;
>>> + int ring_osc;
>>> + u32 val;
>>> +
>>> + fnum = cdata[i].fuse_corner;
>>> + fuse = &thread->fuse_corners[fnum];
>>> +
>>> + val = thread->corners[i].uV - desc->cpr_base_voltage;
>>> + volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
>>> +
>>> + val = thread->corners[i].min_uV - desc->cpr_base_voltage;
>>> + volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
>>> +
>>> + /*
>>> + * If we are accessing corners that are not used as
>>> + * an active DCVS set-point, then always select RO 0
>>> + * and zero out the delta quotient.
>>> + */
>>> + if (i >= thread->num_corners) {
>>> + ring_osc = 0;
>>> + delta_quot_steps = 0;
>>> + } else {
>>> + ring_osc = fuse->ring_osc_idx;
>>> + val = fuse->quot - thread->corners[i].quot_adjust;
>>> + val -= min_quotient;
>>> + delta_quot_steps = DIV_ROUND_UP(val,
>>> + CPRH_DELTA_QUOT_STEP_FACTOR);
>>> + }
>>> +
>>> + if (volt_oloop_steps > CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE ||
>>> + volt_floor_steps > CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
>>> + delta_quot_steps > CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
>>> + dev_err(drv->dev, "Invalid cfg: oloop=%d, floor=%d, delta=%d\n",
>>> + volt_oloop_steps, volt_floor_steps,
>>> + delta_quot_steps);
>>> + return -EINVAL;
>>> + }
>>> + /* Green light: Go, Go, Go! */
>>> +
>>> + /* Set number of open-loop steps */
>>> + val = volt_oloop_steps << CPRH_CORNER_INIT_VOLTAGE_SHIFT;
>>> + val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
>>> +
>>> + /* Set number of floor voltage steps */
>>> + val |= (volt_floor_steps << CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
>>> + CPRH_CORNER_FLOOR_VOLTAGE_MASK;
>>> +
>>> + /* Set number of target quotient delta steps */
>>> + val |= (delta_quot_steps << CPRH_CORNER_QUOT_DELTA_SHIFT) &
>>> + CPRH_CORNER_QUOT_DELTA_MASK;
>>> +
>>> + /* Select ring oscillator for this corner */
>>> + val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
>>> + CPRH_CORNER_RO_SEL_MASK;
>>> +
>>> + /* Open loop corner is usually APM/ACC crossover */
>>> + if (thread->corners[i].is_open_loop) {
>>> + dev_dbg(drv->dev, "Disabling Closed-Loop on corner %d\n", i);
>>> + val |= CPRH_CORNER_CPR_CL_DISABLE;
>>> + }
>>> + cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, i), val);
>>> +
>>> + dev_dbg(drv->dev, "steps [%d]: open-loop %d, floor %d, delta_quot %d\n",
>>> + i, volt_oloop_steps, volt_floor_steps,
>>> + delta_quot_steps);
>>> + }
>>> +
>>> + /* YAY! Setup is done! Enable the internal loop to start CPR. */
>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>>> +
>>> + /*
>>> + * All the writes are going through before enabling internal
>>> + * communication between the OSM and the CPRh controllers
>>> + * because we are never using relaxed accessors, but should
>>> + * we use them, it would be critical to issue a barrier here,
>>> + * otherwise there is a high risk of hardware lockups due to
>>> + * under-voltage for the selected CPU clock.
>>> + *
>>> + * Please note that the CPR-hardened gets set-up in Linux but
>>> + * then gets actually used in firmware (and only by the OSM);
>>> + * after handing it off we will have no more control on it.
>>> + */
>>> +
>>> + /* Enable the interface between OSM and CPRh */
>>> + cpr_masked_write(thread, drv->reg_ctl,
>>> + CPRH_CTL_OSM_ENABLED,
>>> + CPRH_CTL_OSM_ENABLED);
>>> +
>>> + /* On success, free cdata manually */
>>> + devm_kfree(drv->dev, cdata);
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr3_init_parameters() - Initialize CPR global parameters
>>> + * @drv: Main driver structure
>>> + *
>>> + * Initial "integrity" checks and setup for the thread-independent parameters.
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr3_init_parameters(struct cpr_drv *drv)
>>> +{
>>> + const struct cpr_desc *desc = drv->desc;
>>> + struct clk *clk;
>>> +
>>> + clk = devm_clk_get(drv->dev, "ref");
>>> + if (IS_ERR(clk))
>>> + return PTR_ERR(clk);
>>> +
>>> + drv->ref_clk_khz = clk_get_rate(clk);
>>> + do_div(drv->ref_clk_khz, 1000);
>>> +
>>> + /* On CPRh this clock is not always-on... */
>>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>>> + clk_prepare_enable(clk);
>>> + else
>>> + devm_clk_put(drv->dev, clk);
>>> +
>>> + if (desc->timer_cons_up > CPR3_THRESH_CONS_UP_MASK ||
>>> + desc->timer_cons_down > CPR3_THRESH_CONS_DOWN_MASK ||
>>> + desc->up_threshold > CPR3_THRESH_UP_THRESH_MASK ||
>>> + desc->down_threshold > CPR3_THRESH_DOWN_THRESH_MASK ||
>>> + desc->idle_clocks > CPR3_CPR_CTL_IDLE_CLOCKS_MASK ||
>>> + desc->count_mode > CPR3_CPR_CTL_COUNT_MODE_MASK ||
>>> + desc->count_repeat > CPR3_CPR_CTL_COUNT_REPEAT_MASK)
>>> + return -EINVAL;
>>> +
>>> + /*
>>> + * Read the CPR version register only from CPR3 onwards:
>>> + * this is needed to get the additional register offsets.
>>> + *
>>> + * Note: When threaded, even if multi-controller, there
>>> + * is no chance to have different versions at the
>>> + * same time in the same domain, so it is safe to
>>> + * check this only on the first controller/thread.
>>> + */
>>> + drv->cpr_hw_rev = cpr_read(&drv->threads[0],
>>> + CPR3_REG_CPR_VERSION);
>>> + dev_dbg(drv->dev, "CPR hardware revision: 0x%x\n", drv->cpr_hw_rev);
>>> +
>>> + if (drv->cpr_hw_rev >= CPRH_CPR_VERSION_4P5) {
>>> + drv->reg_corner = 0x3500;
>>> + drv->reg_corner_tid = 0xa0;
>>> + drv->reg_ctl = 0x3a80;
>>> + drv->reg_status = 0x3a84;
>>> + } else {
>>> + drv->reg_corner = 0x3a00;
>>> + drv->reg_corner_tid = 0;
>>> + drv->reg_ctl = 0x3aa0;
>>> + drv->reg_status = 0x3aa4;
>>> + }
>>> +
>>> + dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n",
>>> + desc->up_threshold, desc->down_threshold);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr3_find_initial_corner() - Finds boot-up p-state and enables CPR
>>> + * @thread: Structure holding CPR thread-specific parameters
>>> + *
>>> + * Differently from CPRv1, from CPRv3 onwards when we successfully find
>>> + * the target boot-up performance state, we must refresh the HW
>>> + * immediately to guarantee system stability and to avoid overheating
>>> + * during the boot process, thing that would more likely happen without
>>> + * this driver doing its job.
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr3_find_initial_corner(struct cpr_thread *thread)
>>> +{
>>> + struct cpr_drv *drv = thread->drv;
>>> + struct corner *corner;
>>> + int uV, idx;
>>> +
>>> + idx = cpr_find_initial_corner(drv->dev, thread->cpu_clk,
>>> + thread->corners,
>>> + thread->num_corners);
>>> + if (idx < 0)
>>> + return idx;
>>> +
>>> + cpr_ctl_disable(thread);
>>> +
>>> + corner = &thread->corners[idx];
>>> + cpr_corner_restore(thread, corner);
>>> +
>>> + uV = regulator_get_voltage(drv->vreg);
>>> + uV = clamp(uV, corner->min_uV, corner->max_uV);
>>> +
>>> + corner->last_uV = uV;
>>> + if (!drv->last_uV)
>>> + drv->last_uV = uV;
>>> +
>>> + cpr_commit_state(thread);
>>> + thread->enabled = true;
>>> + cpr_switch(drv);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static const int msm8998_gold_scaling_factor[][CPR3_RO_COUNT] = {
>>> + /* Fuse Corner 0 */
>>> + {
>>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>>> + },
>>> + /* Fuse Corner 1 */
>>> + {
>>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>>> + },
>>> + /* Fuse Corner 2 */
>>> + {
>>> + 2603, 2755, 2676, 2777, 2573, 2685, 2465, 2610,
>>> + 2312, 2423, 2243, 3104, 3022, 3036, 2740, 2303
>>> + },
>>> + /* Fuse Corner 3 */
>>> + {
>>> + 1901, 2016, 2096, 2228, 2034, 2161, 2077, 2188,
>>> + 1565, 1870, 1925, 2235, 2205, 2413, 1762, 1478
>>> + }
>>> +};
>>> +
>>> +static const int msm8998_silver_scaling_factor[][CPR3_RO_COUNT] = {
>>> + /* Fuse Corner 0 */
>>> + {
>>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>>> + },
>>> + /* Fuse Corner 1 */
>>> + {
>>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>>> + },
>>> + /* Fuse Corner 2 */
>>> + {
>>> + 2391, 2550, 2483, 2638, 2382, 2564, 2259, 2555,
>>> + 2766, 3041, 2988, 2935, 2873, 2688, 2013, 2784
>>> + },
>>> + /* Fuse Corner 3 */
>>> + {
>>> + 2066, 2153, 2300, 2434, 2220, 2386, 2288, 2465,
>>> + 2028, 2511, 2487, 2734, 2554, 2117, 1892, 2377
>>> + }
>>> +};
>>> +
>>> +static const struct cpr_thread_desc msm8998_thread_gold = {
>>> + .controller_id = 1,
>>> + .hw_tid = 0,
>>> + .ro_scaling_factor = msm8998_gold_scaling_factor,
>>> + .ro_avail_corners = ARRAY_SIZE(msm8998_gold_scaling_factor),
>>> + .sensor_range_start = 0,
>>> + .sensor_range_end = 9,
>>> + .init_voltage_step = 10000,
>>> + .init_voltage_width = 6,
>>> + .step_quot_init_min = 9,
>>> + .step_quot_init_max = 14,
>>> + .num_fuse_corners = 4,
>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>> + /* fuse corner 0 */
>>> + {
>>> + .ref_uV = 756000,
>>> + .max_uV = 828000,
>>> + .min_uV = 568000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 0,
>>> + .volt_oloop_adjust = 8000,
>>> + .max_volt_scale = 4,
>>> + .max_quot_scale = 10,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 1 */
>>> + {
>>> + .ref_uV = 756000,
>>> + .max_uV = 900000,
>>> + .min_uV = 624000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 0,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 320,
>>> + .max_quot_scale = 350,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 2 */
>>> + {
>>> + .ref_uV = 828000,
>>> + .max_uV = 952000,
>>> + .min_uV = 632000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 12000,
>>> + .volt_oloop_adjust = 12000,
>>> + .max_volt_scale = 620,
>>> + .max_quot_scale = 750,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 3 */
>>> + {
>>> + .ref_uV = 1056000,
>>> + .max_uV = 1136000,
>>> + .min_uV = 772000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = 50000,
>>> + .volt_oloop_adjust = 52000,
>>> + .max_volt_scale = 580,
>>> + .max_quot_scale = 1040,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_thread_desc msm8998_thread_silver = {
>>> + .controller_id = 0,
>>> + .hw_tid = 0,
>>> + .ro_scaling_factor = msm8998_silver_scaling_factor,
>>> + .ro_avail_corners = ARRAY_SIZE(msm8998_silver_scaling_factor),
>>> + .sensor_range_start = 0,
>>> + .sensor_range_end = 6,
>>> + .init_voltage_step = 10000,
>>> + .init_voltage_width = 6,
>>> + .step_quot_init_min = 11,
>>> + .step_quot_init_max = 12,
>>> + .num_fuse_corners = 4,
>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>> + /* fuse corner 0 */
>>> + {
>>> + .ref_uV = 688000,
>>> + .max_uV = 828000,
>>> + .min_uV = 568000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 20000,
>>> + .volt_oloop_adjust = 40000,
>>> + .max_volt_scale = 4,
>>> + .max_quot_scale = 10,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 1 */
>>> + {
>>> + .ref_uV = 756000,
>>> + .max_uV = 900000,
>>> + .min_uV = 632000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 26000,
>>> + .volt_oloop_adjust = 24000,
>>> + .max_volt_scale = 500,
>>> + .max_quot_scale = 800,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 2 */
>>> + {
>>> + .ref_uV = 828000,
>>> + .max_uV = 952000,
>>> + .min_uV = 664000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = 12000,
>>> + .volt_oloop_adjust = 12000,
>>> + .max_volt_scale = 280,
>>> + .max_quot_scale = 650,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> +
>>> + },
>>> + /* fuse corner 3 */
>>> + {
>>> + .ref_uV = 1056000,
>>> + .max_uV = 1056000,
>>> + .min_uV = 772000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = 30000,
>>> + .volt_oloop_adjust = 30000,
>>> + .max_volt_scale = 430,
>>> + .max_quot_scale = 800,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_desc msm8998_cpr_desc = {
>>> + .cpr_type = CTRL_TYPE_CPRH,
>>> + .num_threads = 2,
>>> + .mem_acc_threshold = 852000,
>>> + .apm_threshold = 800000,
>>> + .apm_crossover = 880000,
>>> + .apm_hysteresis = 0,
>>> + .cpr_base_voltage = 352000,
>>> + .cpr_max_voltage = 1200000,
>>> + .timer_delay_us = 5000,
>>> + .timer_cons_up = 0,
>>> + .timer_cons_down = 2,
>>> + .up_threshold = 2,
>>> + .down_threshold = 2,
>>> + .idle_clocks = 15,
>>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>>> + .count_repeat = 14,
>>> + .gcnt_us = 1,
>>> + .vreg_step_fixed = 4000,
>>> + .vreg_step_up_limit = 1,
>>> + .vreg_step_down_limit = 1,
>>> + .vdd_settle_time_us = 34,
>>> + .corner_settle_time_us = 6,
>>> + .reduce_to_corner_uV = true,
>>> + .hw_closed_loop_en = true,
>>> + .threads = (const struct cpr_thread_desc *[]) {
>>> + &msm8998_thread_silver,
>>> + &msm8998_thread_gold,
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_acc_desc msm8998_cpr_acc_desc = {
>>> + .cpr_desc = &msm8998_cpr_desc,
>>> +};
>>> +
>>> +static const int sdm630_gold_scaling_factor[][CPR3_RO_COUNT] = {
>>> + /* Same RO factors for all fuse corners */
>>> + {
>>> + 4040, 3230, 0, 2210, 2560, 2450, 2230, 2220,
>>> + 2410, 2300, 2560, 2470, 1600, 3120, 2620, 2280
>>> + }
>>> +};
>>> +
>>> +static const int sdm630_silver_scaling_factor[][CPR3_RO_COUNT] = {
>>> + /* Same RO factors for all fuse corners */
>>> + {
>>> + 3600, 3600, 3830, 2430, 2520, 2700, 1790, 1760,
>>> + 1970, 1880, 2110, 2010, 2510, 4900, 4370, 4780,
>>> + }
>>> +};
>>> +
>>> +static const struct cpr_thread_desc sdm630_thread_gold = {
>>> + .controller_id = 0,
>>> + .hw_tid = 0,
>>> + .ro_scaling_factor = sdm630_gold_scaling_factor,
>>> + .ro_avail_corners = ARRAY_SIZE(sdm630_gold_scaling_factor),
>>> + .sensor_range_start = 0,
>>> + .sensor_range_end = 6,
>>> + .init_voltage_step = 10000,
>>> + .init_voltage_width = 6,
>>> + .step_quot_init_min = 12,
>>> + .step_quot_init_max = 14,
>>> + .num_fuse_corners = 5,
>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>> + /* fuse corner 0 */
>>> + {
>>> + .ref_uV = 644000,
>>> + .max_uV = 724000,
>>> + .min_uV = 588000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 15000,
>>> + .max_volt_scale = 10,
>>> + .max_quot_scale = 300,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 1 */
>>> + {
>>> + .ref_uV = 788000,
>>> + .max_uV = 788000,
>>> + .min_uV = 652000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 5000,
>>> + .max_volt_scale = 320,
>>> + .max_quot_scale = 275,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 2 */
>>> + {
>>> + .ref_uV = 868000,
>>> + .max_uV = 868000,
>>> + .min_uV = 712000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 5000,
>>> + .max_volt_scale = 350,
>>> + .max_quot_scale = 800,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 3 */
>>> + {
>>> + .ref_uV = 988000,
>>> + .max_uV = 988000,
>>> + .min_uV = 784000,
>>> + .range_uV = 66000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 868,
>>> + .max_quot_scale = 980,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 4 */
>>> + {
>>> + .ref_uV = 1068000,
>>> + .max_uV = 1068000,
>>> + .min_uV = 844000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 868,
>>> + .max_quot_scale = 980,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_thread_desc sdm630_thread_silver = {
>>> + .controller_id = 1,
>>> + .hw_tid = 0,
>>> + .ro_scaling_factor = sdm630_silver_scaling_factor,
>>> + .ro_avail_corners = ARRAY_SIZE(sdm630_silver_scaling_factor),
>>> + .sensor_range_start = 0,
>>> + .sensor_range_end = 6,
>>> + .init_voltage_step = 10000,
>>> + .init_voltage_width = 6,
>>> + .step_quot_init_min = 12,
>>> + .step_quot_init_max = 14,
>>> + .num_fuse_corners = 3,
>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>> + /* fuse corner 0 */
>>> + {
>>> + .ref_uV = 644000,
>>> + .max_uV = 724000,
>>> + .min_uV = 588000,
>>> + .range_uV = 32000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 10,
>>> + .max_quot_scale = 360,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 1 */
>>> + {
>>> + .ref_uV = 788000,
>>> + .max_uV = 788000,
>>> + .min_uV = 652000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 500,
>>> + .max_quot_scale = 550,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + /* fuse corner 2 */
>>> + {
>>> + .ref_uV = 1068000,
>>> + .max_uV = 1068000,
>>> + .min_uV = 800000,
>>> + .range_uV = 40000,
>>> + .volt_cloop_adjust = -30000,
>>> + .volt_oloop_adjust = 0,
>>> + .max_volt_scale = 2370,
>>> + .max_quot_scale = 550,
>>> + .quot_offset = 0,
>>> + .quot_scale = 1,
>>> + .quot_adjust = 0,
>>> + .quot_offset_scale = 5,
>>> + .quot_offset_adjust = 0,
>>> + },
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_desc sdm630_cpr_desc = {
>>> + .cpr_type = CTRL_TYPE_CPRH,
>>> + .num_threads = 2,
>>> + .apm_threshold = 872000,
>>> + .apm_crossover = 872000,
>>> + .apm_hysteresis = 20000,
>>> + .cpr_base_voltage = 400000,
>>> + .cpr_max_voltage = 1300000,
>>> + .timer_delay_us = 5000,
>>> + .timer_cons_up = 0,
>>> + .timer_cons_down = 2,
>>> + .up_threshold = 2,
>>> + .down_threshold = 2,
>>> + .idle_clocks = 15,
>>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>>> + .count_repeat = 14,
>>> + .gcnt_us = 1,
>>> + .vreg_step_fixed = 4000,
>>> + .vreg_step_up_limit = 1,
>>> + .vreg_step_down_limit = 1,
>>> + .vdd_settle_time_us = 34,
>>> + .corner_settle_time_us = 5,
>>> + .reduce_to_corner_uV = true,
>>> + .hw_closed_loop_en = true,
>>> + .threads = (const struct cpr_thread_desc *[]) {
>>> + &sdm630_thread_gold,
>>> + &sdm630_thread_silver,
>>> + },
>>> +};
>>> +
>>> +static const struct cpr_acc_desc sdm630_cpr_acc_desc = {
>>> + .cpr_desc = &sdm630_cpr_desc,
>>> +};
>>> +
>>> +static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
>>> + struct dev_pm_opp *opp)
>>> +{
>>> + return dev_pm_opp_get_level(opp);
>>> +}
>>> +
>>> +static int cpr_power_off(struct generic_pm_domain *domain)
>>> +{
>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>> +
>>> + return cpr_disable(thread);
>>> +}
>>> +
>>> +static int cpr_power_on(struct generic_pm_domain *domain)
>>> +{
>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>> +
>>> + return cpr_enable(thread);
>>> +}
>>> +
>>> +static void cpr_pd_detach_dev(struct generic_pm_domain *domain,
>>> + struct device *dev)
>>> +{
>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>> + struct cpr_drv *drv = thread->drv;
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + dev_dbg(drv->dev, "detach callback for: %s\n", dev_name(dev));
>>> + thread->attached_cpu_dev = NULL;
>>> +
>>> + mutex_unlock(&drv->lock);
>>> +}
>>> +
>>> +static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
>>> + struct device *dev)
>>> +{
>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>> + struct cpr_drv *drv = thread->drv;
>>> + const struct acc_desc *acc_desc = drv->acc_desc;
>>> + bool cprh_opp_remove_table = false;
>>> + int ret = 0;
>>> +
>>> + mutex_lock(&drv->lock);
>>> +
>>> + dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev));
>>> +
>>> + /*
>>> + * This driver only supports scaling voltage for a CPU cluster
>>> + * where all CPUs in the cluster share a single regulator.
>>> + * Therefore, save the struct device pointer only for the first
>>> + * CPU device that gets attached. There is no need to do any
>>> + * additional initialization when further CPUs get attached.
>>> + * This is not an error condition.
>>> + */
>>> + if (thread->attached_cpu_dev)
>>> + goto unlock;
>>> +
>>> + /*
>>> + * cpr_scale_voltage() requires the direction (if we are changing
>>> + * to a higher or lower OPP). The first time
>>> + * cpr_set_performance_state() is called, there is no previous
>>> + * performance state defined. Therefore, we call
>>> + * cpr_find_initial_corner() that gets the CPU clock frequency
>>> + * set by the bootloader, so that we can determine the direction
>>> + * the first time cpr_set_performance_state() is called.
>>> + */
>>> + thread->cpu_clk = devm_clk_get(dev, NULL);
>>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH && IS_ERR(thread->cpu_clk)) {
>>> + ret = PTR_ERR(thread->cpu_clk);
>>> + if (ret != -EPROBE_DEFER)
>>> + dev_err(drv->dev, "could not get cpu clk: %d\n", ret);
>>> + goto unlock;
>>> + }
>>> + thread->attached_cpu_dev = dev;
>>> +
>>> + /*
>>> + * We are exporting the APM and MEM-ACC thresholds to the caller;
>>> + * while APM is necessary in the CPU CPR case, MEM-ACC may not be,
>>> + * depending on the SoC and on fuses.
>>> + * Initialize both to an invalid value, so that the caller can check
>>> + * if they got calculated or read from fuses in this driver.
>>> + */
>>> + thread->ext_data.apm_threshold_uV = -1;
>>> + thread->ext_data.mem_acc_threshold_uV = -1;
>>> + dev_set_drvdata(thread->attached_cpu_dev, &thread->ext_data);
>>> +
>>> + dev_dbg(drv->dev, "using cpu clk from: %s\n",
>>> + dev_name(thread->attached_cpu_dev));
>>> +
>>> + /*
>>> + * Everything related to (virtual) corners has to be initialized
>>> + * here, when attaching to the power domain, since we need to know
>>> + * the maximum frequency for each fuse corner, and this is only
>>> + * available after the cpufreq driver has attached to us.
>>> + * The reason for this is that we need to know the highest
>>> + * frequency associated with each fuse corner.
>>> + */
>>> + ret = dev_pm_opp_get_opp_count(&thread->pd.dev);
>>> + if (ret < 0) {
>>> + dev_err(drv->dev, "could not get OPP count\n");
>>> + thread->attached_cpu_dev = NULL;
>>> + goto unlock;
>>> + }
>>> + thread->num_corners = ret;
>>> +
>>> + thread->corners = devm_kcalloc(drv->dev,
>>> + thread->num_corners +
>>> + drv->extra_corners,
>>> + sizeof(*thread->corners),
>>> + GFP_KERNEL);
>>> + if (!thread->corners) {
>>> + ret = -ENOMEM;
>>> + goto unlock;
>>> + }
>>> +
>>> + /*
>>> + * If we are on CPR-Hardened we have to make sure that the attached
>>> + * device has a OPP table installed, as we're going to modify it here
>>> + * with our calculations based on qfprom values.
>>> + */
>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH) {
>>> + ret = dev_pm_opp_of_add_table(dev);
>>> + if (ret && ret != -EEXIST) {
>>> + dev_err(drv->dev, "Cannot add table: %d\n", ret);
>>> + goto unlock;
>>> + }
>>> + cprh_opp_remove_table = true;
>>> + }
>>> +
>>> + ret = cpr3_corner_init(thread);
>>> + if (ret)
>>> + goto exit;
>>> +
>>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH) {
>>> + ret = cpr3_find_initial_corner(thread);
>>> + if (ret)
>>> + goto exit;
>>> +
>>> + if (acc_desc->config)
>>> + regmap_multi_reg_write(drv->tcsr, acc_desc->config,
>>> + acc_desc->num_regs_per_fuse);
>>> +
>>> + /* Enable ACC if required */
>>> + if (acc_desc->enable_mask)
>>> + regmap_update_bits(drv->tcsr, acc_desc->enable_reg,
>>> + acc_desc->enable_mask,
>>> + acc_desc->enable_mask);
>>> + }
>>> + dev_info(drv->dev, "thread %d initialized with %u OPPs\n",
>>> + thread->id, thread->num_corners);
>>> +exit:
>>> + /*
>>> + * If we are on CPRh and we reached an error condition, we installed
>>> + * the OPP table but we haven't done any setup on it, nor we ever will.
>>> + * In order to leave a clean state, remove the table.
>>> + */
>>> + if (ret && cprh_opp_remove_table)
>>> + dev_pm_opp_of_remove_table(thread->attached_cpu_dev);
>>> +unlock:
>>> + mutex_unlock(&drv->lock);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +static int cpr3_debug_info_show(struct seq_file *s, void *unused)
>>> +{
>>> + u32 ro_sel, ctl, irq_status, reg, quot;
>>> + struct cpr_thread *thread = s->private;
>>> + struct corner *corner = thread->corners;
>>> + struct fuse_corner *fuse = thread->fuse_corners;
>>> + unsigned int i;
>>> +
>>> + const struct {
>>> + const char *name;
>>> + uint32_t mask;
>>> + uint8_t shift;
>>> + } result0_fields[] = {
>>> + { "busy", 1, 0 },
>>> + { "step_dn", 1, 1 },
>>> + { "step_up", 1, 2 },
>>> + { "error_steps", CPR3_RESULT0_ERROR_STEPS_MASK,
>>> + CPR3_RESULT0_ERROR_STEPS_SHIFT },
>>> + { "error", CPR3_RESULT0_ERROR_MASK, CPR3_RESULT0_ERROR_SHIFT },
>>> + { "negative", 1, 20 },
>>> + }, result1_fields[] = {
>>> + { "quot_min", CPR3_RESULT1_QUOT_MIN_MASK,
>>> + CPR3_RESULT1_QUOT_MIN_SHIFT },
>>> + { "quot_max", CPR3_RESULT1_QUOT_MAX_MASK,
>>> + CPR3_RESULT1_QUOT_MAX_SHIFT },
>>> + { "ro_min", CPR3_RESULT1_RO_MIN_MASK,
>>> + CPR3_RESULT1_RO_MIN_SHIFT },
>>> + { "ro_max", CPR3_RESULT1_RO_MAX_MASK,
>>> + CPR3_RESULT1_RO_MAX_SHIFT },
>>> + }, result2_fields[] = {
>>> + { "qout_step_min", CPR3_RESULT2_STEP_QUOT_MIN_MASK,
>>> + CPR3_RESULT2_STEP_QUOT_MIN_SHIFT },
>>> + { "qout_step_max", CPR3_RESULT2_STEP_QUOT_MAX_MASK,
>>> + CPR3_RESULT2_STEP_QUOT_MAX_SHIFT },
>>> + { "sensor_min", CPR3_RESULT2_SENSOR_MIN_MASK,
>>> + CPR3_RESULT2_SENSOR_MIN_SHIFT },
>>> + { "sensor_max", CPR3_RESULT2_SENSOR_MAX_MASK,
>>> + CPR3_RESULT2_SENSOR_MAX_SHIFT },
>>> + };
>>> +
>>> + if (thread->drv->desc->cpr_type < CTRL_TYPE_CPRH)
>>> + seq_printf(s, "current_volt = %d uV\n", thread->drv->last_uV);
>>> +
>>> + irq_status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>> + seq_printf(s, "irq_status = %#02X\n", irq_status);
>>> +
>>> + ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>>> + seq_printf(s, "cpr_ctl = %#02X\n", ctl);
>>> +
>>> + seq_printf(s, "thread %d - hw tid: %u - enabled: %d:\n",
>>> + thread->id, thread->desc->hw_tid, thread->enabled);
>>> + seq_printf(s, "%d corners, derived from %d fuse corners\n",
>>> + thread->num_corners, thread->desc->num_fuse_corners);
>>> +
>>> + for (i = 0; i < thread->num_corners; i++, corner++)
>>> + seq_printf(s, "corner %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>>> + i, corner->min_uV, corner->uV, corner->max_uV,
>>> + corner->quot_adjust, corner->freq);
>>> +
>>> + for (i = 0; i < thread->desc->num_fuse_corners; i++, fuse++)
>>> + seq_printf(s, "fuse %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>>> + fuse->quot, corner->freq);
>>> +
>>> + seq_printf(s, "requested voltage: %d uV\n", thread->corner->last_uV);
>>> +
>>> + ro_sel = corner->fuse_corner->ring_osc_idx;
>>> + quot = cpr_read(thread, CPR3_REG_TARGET_QUOT(i, ro_sel));
>>> + seq_printf(s, "quot_target (%u) = %#02X\n", ro_sel, quot);
>>> +
>>> + reg = cpr_read(thread, CPR3_REG_RESULT0(i));
>>> + seq_printf(s, "cpr_result_0 = %#02X\n [", reg);
>>> + for (i = 0; i < ARRAY_SIZE(result0_fields); i++)
>>> + seq_printf(s, "%s%s = %u",
>>> + i ? ", " : "",
>>> + result0_fields[i].name,
>>> + (reg >> result0_fields[i].shift) &
>>> + result0_fields[i].mask);
>>> + seq_puts(s, "]\n");
>>> + reg = cpr_read(thread, CPR3_REG_RESULT1(i));
>>> + seq_printf(s, "cpr_result_1 = %#02X\n [", reg);
>>> + for (i = 0; i < ARRAY_SIZE(result1_fields); i++)
>>> + seq_printf(s, "%s%s = %u",
>>> + i ? ", " : "",
>>> + result1_fields[i].name,
>>> + (reg >> result1_fields[i].shift) &
>>> + result1_fields[i].mask);
>>> + seq_puts(s, "]\n");
>>> + reg = cpr_read(thread, CPR3_REG_RESULT2(i));
>>> + seq_printf(s, "cpr_result_2 = %#02X\n [", reg);
>>> + for (i = 0; i < ARRAY_SIZE(result2_fields); i++)
>>> + seq_printf(s, "%s%s = %u",
>>> + i ? ", " : "",
>>> + result2_fields[i].name,
>>> + (reg >> result2_fields[i].shift) &
>>> + result2_fields[i].mask);
>>> + seq_puts(s, "]\n");
>>> +
>>> + return 0;
>>> +}
>>> +DEFINE_SHOW_ATTRIBUTE(cpr3_debug_info);
>>> +
>>> +static void cpr3_debugfs_init(struct cpr_drv *drv)
>>> +{
>>> + int i;
>>> +
>>> + drv->debugfs = debugfs_create_dir("qcom_cpr3", NULL);
>>> +
>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>> + char buf[50];
>>> +
>>> + snprintf(buf, sizeof(buf), "thread%d", i);
>>> +
>>> + debugfs_create_file(buf, 0444, drv->debugfs, &drv->threads[i],
>>> + &cpr3_debug_info_fops);
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * cpr_thread_init() - Initialize CPR thread related parameters
>>> + * @drv: Main driver structure
>>> + * @tid: Thread ID
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr_thread_init(struct cpr_drv *drv, int tid)
>>> +{
>>> + const struct cpr_desc *desc = drv->desc;
>>> + const struct cpr_thread_desc *tdesc = desc->threads[tid];
>>> + struct cpr_thread *thread = &drv->threads[tid];
>>> + int ret;
>>> +
>>> + if (tdesc->step_quot_init_min > CPR3_CPR_STEP_QUOT_MIN_MASK ||
>>> + tdesc->step_quot_init_max > CPR3_CPR_STEP_QUOT_MAX_MASK)
>>> + return -EINVAL;
>>> +
>>> + thread->id = tid;
>>> + thread->drv = drv;
>>> + thread->desc = tdesc;
>>> + thread->fuse_corners = devm_kcalloc(drv->dev,
>>> + tdesc->num_fuse_corners +
>>> + drv->extra_corners,
>>> + sizeof(*thread->fuse_corners),
>>> + GFP_KERNEL);
>>> + if (!thread->fuse_corners)
>>> + return -ENOMEM;
>>> +
>>> + thread->cpr_fuses = cpr_get_fuses(drv->dev, tid,
>>> + tdesc->num_fuse_corners);
>>> + if (IS_ERR(thread->cpr_fuses))
>>> + return PTR_ERR(thread->cpr_fuses);
>>> +
>>> + ret = cpr_populate_ring_osc_idx(thread->drv->dev, thread->fuse_corners,
>>> + thread->cpr_fuses,
>>> + tdesc->num_fuse_corners);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = cpr_fuse_corner_init(thread);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + thread->pd.name = devm_kasprintf(drv->dev, GFP_KERNEL,
>>> + "%s_thread%d",
>>> + drv->dev->of_node->full_name,
>>> + thread->id);
>>> + if (!thread->pd.name)
>>> + return -EINVAL;
>>> +
>>> + thread->pd.power_off = cpr_power_off;
>>> + thread->pd.power_on = cpr_power_on;
>>> + thread->pd.opp_to_performance_state = cpr_get_performance_state;
>>> + thread->pd.attach_dev = cpr_pd_attach_dev;
>>> + thread->pd.detach_dev = cpr_pd_detach_dev;
>>> +
>>> + /* CPR-Hardened performance states are managed in firmware */
>>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>>> + thread->pd.set_performance_state = cprh_dummy_set_performance_state;
>>> + else
>>> + thread->pd.set_performance_state = cpr_set_performance_state;
>>> +
>>> + /* Anything later than CPR1 must be always-on for now */
>>> + thread->pd.flags = GENPD_FLAG_ALWAYS_ON;
>>> +
>>> + drv->cell_data.domains[tid] = &thread->pd;
>>> +
>>> + ret = pm_genpd_init(&thread->pd, NULL, false);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /* On CPRhardened, the interrupts are managed in firmware */
>>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>>> + INIT_WORK(&thread->restart_work, cpr_restart_worker);
>>> +
>>> + ret = devm_request_threaded_irq(drv->dev, drv->irq,
>>> + NULL, cpr_irq_handler,
>>> + IRQF_ONESHOT |
>>> + IRQF_TRIGGER_RISING,
>>> + "cpr", drv);
>>> + if (ret)
>>> + return ret;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + * cpr3_resources_init() - Initialize resources used by this driver
>>> + * @pdev: Platform device
>>> + * @drv: Main driver structure
>>> + *
>>> + * Return: Zero for success, negative number on error
>>> + */
>>> +static int cpr3_resources_init(struct platform_device *pdev,
>>> + struct cpr_drv *drv)
>>> +{
>>> + const struct cpr_desc *desc = drv->desc;
>>> + struct cpr_thread *threads = drv->threads;
>>> + unsigned int i;
>>> + u8 cid_mask = 0;
>>> +
>>> + /*
>>> + * Here, we are accounting for the following usecases:
>>> + * - One controller
>>> + * - One or multiple threads on the same iospace
>>> + *
>>> + * - Multiple controllers
>>> + * - Each controller has its own iospace and each
>>> + * may have one or multiple threads in their
>>> + * parent controller's iospace
>>> + *
>>> + * Then, to avoid complicating the code for no reason,
>>> + * this also needs a mandatory order in the list of
>>> + * threads which implies that all of them from the same
>>> + * controllers are specified sequentially. As an example:
>>> + *
>>> + * C0-T0, C0-T1...C0-Tn, C1-T0, C1-T1...C1-Tn
>>> + */
>>> + for (i = 0; i < desc->num_threads; i++) {
>>> + u8 cid = desc->threads[i]->controller_id;
>>> +
>>> + if (cid_mask & BIT(cid)) {
>>> + if (desc->threads[i - 1]->controller_id != cid) {
>>> + dev_err(drv->dev, "Bad threads order. Please fix!\n");
>>> + return -EINVAL;
>>> + }
>>> + threads[i].base = threads[i - 1].base;
>>> + continue;
>>> + }
>>> + threads[i].base = devm_platform_ioremap_resource(pdev, cid);
>>> + if (IS_ERR(threads[i].base))
>>> + return PTR_ERR(threads[i].base);
>>> + cid_mask |= BIT(cid);
>>> + }
>>> + return 0;
>>> +}
>>> +
>>> +static int cpr_probe(struct platform_device *pdev)
>>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct cpr_drv *drv;
>>> + const struct cpr_desc *desc;
>>> + const struct cpr_acc_desc *data;
>>> + struct device_node *np;
>>> + unsigned int i;
>>> + int ret;
>>> +
>>> + data = of_device_get_match_data(dev);
>>> + if (!data || !data->cpr_desc)
>>> + return -EINVAL;
>>> +
>>> + desc = data->cpr_desc;
>>> +
>>> + /* CPRh disallows MEM-ACC access from the HLOS */
>>> + if (!data->acc_desc && desc->cpr_type < CTRL_TYPE_CPRH)
>>> + return -EINVAL;
>>> +
>>> + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
>>> + if (!drv)
>>> + return -ENOMEM;
>>> +
>>> + drv->dev = dev;
>>> + drv->desc = desc;
>>> + drv->threads = devm_kcalloc(dev, desc->num_threads,
>>> + sizeof(*drv->threads), GFP_KERNEL);
>>> + if (!drv->threads)
>>> + return -ENOMEM;
>>> +
>>> + drv->cell_data.num_domains = desc->num_threads;
>>> + drv->cell_data.domains = devm_kcalloc(drv->dev,
>>> + drv->cell_data.num_domains,
>>> + sizeof(*drv->cell_data.domains),
>>> + GFP_KERNEL);
>>> + if (!drv->cell_data.domains)
>>> + return -ENOMEM;
>>> +
>>> + if (data->acc_desc)
>>> + drv->acc_desc = data->acc_desc;
>>> +
>>> + mutex_init(&drv->lock);
>>> +
>>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>>> + np = of_parse_phandle(dev->of_node, "acc-syscon", 0);
>>> + if (!np)
>>> + return -ENODEV;
>>> +
>>> + drv->tcsr = syscon_node_to_regmap(np);
>>> + of_node_put(np);
>>> + if (IS_ERR(drv->tcsr))
>>> + return PTR_ERR(drv->tcsr);
>>> + }
>>> +
>>> + ret = cpr3_resources_init(pdev, drv);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + drv->irq = platform_get_irq_optional(pdev, 0);
>>> + if (desc->cpr_type != CTRL_TYPE_CPRH && drv->irq < 0)
>>> + return -EINVAL;
>>> +
>>> + /* On CPRhardened, vreg access it not allowed */
>>> + drv->vreg = devm_regulator_get_optional(dev, "vdd");
>>> + if (desc->cpr_type != CTRL_TYPE_CPRH && IS_ERR(drv->vreg))
>>> + return PTR_ERR(drv->vreg);
>>> +
>>> + /*
>>> + * On at least CPRhardened, vreg is unaccessible and there is no
>>> + * way to read linear step from that regulator, hence it is hardcoded
>>> + * in the driver;
>>> + * When the vreg_step is not declared in the cpr data (or is zero),
>>> + * then having access to the vreg regulator is mandatory, as this
>>> + * will be retrieved through the regulator API.
>>> + */
>>> + if (desc->vreg_step_fixed)
>>> + drv->vreg_step = desc->vreg_step_fixed;
>>> + else
>>> + drv->vreg_step = regulator_get_linear_step(drv->vreg);
>>> +
>>> + if (!drv->vreg_step)
>>> + return -EINVAL;
>>> +
>>> + /*
>>> + * Initialize fuse corners, since it simply depends
>>> + * on data in efuses.
>>> + * Everything related to (virtual) corners has to be
>>> + * initialized after attaching to the power domain,
>>> + * since it depends on the CPU's OPP table.
>>> + */
>>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &drv->fusing_rev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_speed_bin", &drv->speed_bin);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /*
>>> + * Some SoCs require extra corners for MEM-ACC or APM: if
>>> + * the related parameters have been specified, then reserve
>>> + * a corner for the APM and/or MEM-ACC crossover, used by
>>> + * OSM and CPRh HW to set the supply voltage during the APM
>>> + * and/or MEM-ACC switch routine.
>>> + */
>>> + if (desc->cpr_type == CTRL_TYPE_CPRH) {
>>> + if (desc->apm_crossover && desc->apm_hysteresis >= 0)
>>> + drv->extra_corners++;
>>> +
>>> + if (desc->mem_acc_threshold)
>>> + drv->extra_corners++;
>>> + }
>>> +
>>> + /* Initialize all threads */
>>> + for (i = 0; i < desc->num_threads; i++) {
>>> + ret = cpr_thread_init(drv, i);
>>> + if (ret)
>>> + return ret;
>>> + }
>>> +
>>> + /* Initialize global parameters */
>>> + ret = cpr3_init_parameters(drv);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /* Write initial configuration on all threads */
>>> + for (i = 0; i < desc->num_threads; i++) {
>>> + ret = cpr_configure(&drv->threads[i]);
>>> + if (ret)
>>> + return ret;
>>> + }
>>> +
>>> + ret = of_genpd_add_provider_onecell(dev->of_node, &drv->cell_data);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + platform_set_drvdata(pdev, drv);
>>> + cpr3_debugfs_init(drv);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int cpr_remove(struct platform_device *pdev)
>>> +{
>>> + struct cpr_drv *drv = platform_get_drvdata(pdev);
>>> + int i;
>>> +
>>> + of_genpd_del_provider(pdev->dev.of_node);
>>> +
>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>> + cpr_ctl_disable(&drv->threads[i]);
>>> + cpr_irq_set(&drv->threads[i], 0);
>>> + pm_genpd_remove(&drv->threads[i].pd);
>>> + }
>>> +
>>> + debugfs_remove_recursive(drv->debugfs);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static const struct of_device_id cpr3_match_table[] = {
>>> + { .compatible = "qcom,msm8998-cprh", .data = &msm8998_cpr_acc_desc },
>>> + { .compatible = "qcom,sdm630-cprh", .data = &sdm630_cpr_acc_desc },
>>> + { }
>>> +};
>>> +MODULE_DEVICE_TABLE(of, cpr3_match_table);
>>> +
>>> +static struct platform_driver cpr3_driver = {
>>> + .probe = cpr_probe,
>>> + .remove = cpr_remove,
>>> + .driver = {
>>> + .name = "qcom-cpr3",
>>> + .of_match_table = cpr3_match_table,
>>> + },
>>> +};
>>> +module_platform_driver(cpr3_driver)
>>> +
>>> +MODULE_DESCRIPTION("Core Power Reduction (CPR) v3/v4 driver");
>>> +MODULE_LICENSE("GPL v2");
>>> \ No newline at end of file
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
2023-01-10 18:42 ` Robert Marko
@ 2023-01-10 18:43 ` Konrad Dybcio
0 siblings, 0 replies; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 18:43 UTC (permalink / raw)
To: Robert Marko, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
linux-kernel
On 10.01.2023 19:42, Robert Marko wrote:
>
> On 10. 01. 2023. 19:29, Konrad Dybcio wrote:
>>
>> On 10.01.2023 19:27, Robert Marko wrote:
>>> On 10. 01. 2023. 18:56, Konrad Dybcio wrote:
>>>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>>
>>>> This commit introduces a new driver, based on the one for cpr v1,
>>>> to enable support for the newer Qualcomm Core Power Reduction
>>>> hardware, known downstream as CPR3, CPR4 and CPRh, and support
>>>> for MSM8998 and SDM630 CPU power reduction.
>>>>
>>>> In these new versions of the hardware, support for various new
>>>> features was introduced, including voltage reduction for the GPU,
>>>> security hardening and a new way of controlling CPU DVFS,
>>>> consisting in internal communication between microcontrollers,
>>>> specifically the CPR-Hardened and the Operating State Manager.
>>>>
>>>> The CPR v3, v4 and CPRh are present in a broad range of SoCs,
>>>> from the mid-range to the high end ones including, but not limited
>>>> to, MSM8953/8996/8998, SDM630/636/660/845.
>>>>
>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>> [Konrad: rebase, apply review comments]
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>>> Hi Konrad, great to see the series is alive again.
>>> I am working on IPQ8074 which uses CPRv4 and its the last piece for
>>> upstream CPU scaling that is missing so this is really interesting for me.
>>>
>>> However, I think you forgot to include the <soc/qcom/cpr.h> header so
>>> it wont currently compile.
>>>
>>> Regards,
>>> Robert
>> Right, that's rather embarassing..
>>
>> Here's the contents of the file, I will hold on with resending
>> until there are some more reviwew comments..
>
> Thanks, that gets it mostly compiling, however it seems that common
> CPR code is not getting selected to the symbols will be missing.
> Adding select QCOM_CPR_COMMON to QCOM_CPR3 sorts that out, so I
> assume it was just forgotten as QCOM_CPR has it selected.
Totally, thanks for pointing that out!
Konrad
>
> Regards,
> Robert
>
>>
>>
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
>> * Copyright (c) 2019 Linaro Limited
>> * Copyright (c) 2021, AngeloGioacchino Del Regno
>> * <angelogioacchino.delregno@somainline.org>
>> */
>>
>> #ifndef __CPR_H__
>> #define __CPR_H__
>>
>> struct cpr_ext_data {
>> int mem_acc_threshold_uV;
>> int apm_threshold_uV;
>> };
>>
>> #endif /* __CPR_H__ */
>>
>>
>> Konrad
>>>> ---
>>>> drivers/soc/qcom/Kconfig | 21 +
>>>> drivers/soc/qcom/Makefile | 4 +-
>>>> drivers/soc/qcom/cpr-common.h | 2 +
>>>> drivers/soc/qcom/cpr3.c | 2923 +++++++++++++++++++++++++++++++++
>>>> 4 files changed, 2949 insertions(+), 1 deletion(-)
>>>> create mode 100644 drivers/soc/qcom/cpr3.c
>>>>
>>>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>>>> index 21c4ce2315ba..303e958d9432 100644
>>>> --- a/drivers/soc/qcom/Kconfig
>>>> +++ b/drivers/soc/qcom/Kconfig
>>>> @@ -29,6 +29,7 @@ config QCOM_COMMAND_DB
>>>> config QCOM_CPR
>>>> tristate "QCOM Core Power Reduction (CPR) support"
>>>> depends on ARCH_QCOM && HAS_IOMEM
>>>> + select QCOM_CPR_COMMON
>>>> select PM_OPP
>>>> select REGMAP
>>>> help
>>>> @@ -42,6 +43,26 @@ config QCOM_CPR
>>>> To compile this driver as a module, choose M here: the module will
>>>> be called qcom-cpr
>>>> +config QCOM_CPR_COMMON
>>>> + tristate
>>>> +
>>>> +config QCOM_CPR3
>>>> + tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
>>>> + depends on ARCH_QCOM && HAS_IOMEM
>>>> + select PM_OPP
>>>> + select REGMAP
>>>> + help
>>>> + Say Y here to enable support for the CPR hardware found on a broad
>>>> + variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
>>>> + SDM845 and others.
>>>> +
>>>> + This driver populates OPP tables and makes adjustments to them
>>>> + based on feedback from the CPR hardware. If you want to do CPU
>>>> + and/or GPU frequency scaling say Y here.
>>>> +
>>>> + To compile this driver as a module, choose M here: the module will
>>>> + be called qcom-cpr3
>>>> +
>>>> config QCOM_GENI_SE
>>>> tristate "QCOM GENI Serial Engine Driver"
>>>> depends on ARCH_QCOM || COMPILE_TEST
>>>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>>>> index ba2b55dd94ff..362e9b712a68 100644
>>>> --- a/drivers/soc/qcom/Makefile
>>>> +++ b/drivers/soc/qcom/Makefile
>>>> @@ -3,7 +3,9 @@ CFLAGS_rpmh-rsc.o := -I$(src)
>>>> obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
>>>> obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
>>>> obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
>>>> -obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
>>>> +obj-$(CONFIG_QCOM_CPR) += cpr.o
>>>> +obj-$(CONFIG_QCOM_CPR_COMMON) += cpr-common.o
>>>> +obj-$(CONFIG_QCOM_CPR3) += cpr3.o
>>>> obj-$(CONFIG_QCOM_DCC) += dcc.o
>>>> obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
>>>> obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
>>>> diff --git a/drivers/soc/qcom/cpr-common.h b/drivers/soc/qcom/cpr-common.h
>>>> index 2cd15f7eac90..a90f6351d022 100644
>>>> --- a/drivers/soc/qcom/cpr-common.h
>>>> +++ b/drivers/soc/qcom/cpr-common.h
>>>> @@ -65,6 +65,8 @@ struct corner {
>>>> struct corner_data {
>>>> unsigned int fuse_corner;
>>>> unsigned long freq;
>>>> + int oloop_vadj;
>>>> + int cloop_vadj;
>>>> };
>>>> struct acc_desc {
>>>> diff --git a/drivers/soc/qcom/cpr3.c b/drivers/soc/qcom/cpr3.c
>>>> new file mode 100644
>>>> index 000000000000..14a1163d37eb
>>>> --- /dev/null
>>>> +++ b/drivers/soc/qcom/cpr3.c
>>>> @@ -0,0 +1,2923 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
>>>> + * Copyright (c) 2019 Linaro Limited
>>>> + * Copyright (c) 2021, AngeloGioacchino Del Regno
>>>> + * <angelogioacchino.delregno@somainline.org>
>>>> + */
>>>> +
>>>> +#include <linux/bitops.h>
>>>> +#include <linux/clk.h>
>>>> +#include <linux/debugfs.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/init.h>
>>>> +#include <linux/interrupt.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/mfd/syscon.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/nvmem-consumer.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/pm_domain.h>
>>>> +#include <linux/pm_opp.h>
>>>> +#include <linux/regmap.h>
>>>> +#include <linux/regulator/consumer.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/string.h>
>>>> +#include <linux/workqueue.h>
>>>> +#include <soc/qcom/cpr.h>
>>>> +
>>>> +#include "cpr-common.h"
>>>> +
>>>> +#define CPR3_RO_COUNT 16
>>>> +#define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0)
>>>> +
>>>> +/* CPR3 registers */
>>>> +#define CPR3_REG_CPR_VERSION 0x0
>>>> +#define CPRH_CPR_VERSION_4P5 0x40050000
>>>> +
>>>> +#define CPR3_REG_CPR_CTL 0x4
>>>> +#define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0)
>>>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK GENMASK(5, 1)
>>>> +#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT 1
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_MASK GENMASK(7, 6)
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_SHIFT 6
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN 0
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX 1
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED 2
>>>> +#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE 3
>>>> +#define CPR3_CPR_CTL_COUNT_REPEAT_MASK GENMASK(31, 9)
>>>> +#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT 9
>>>> +
>>>> +#define CPR3_REG_CPR_STATUS 0x8
>>>> +#define CPR3_CPR_STATUS_BUSY_MASK BIT(0)
>>>> +
>>>> +/*
>>>> + * This register is not present on controllers that support HW closed-loop
>>>> + * except CPR4 APSS controller.
>>>> + */
>>>> +#define CPR3_REG_CPR_TIMER_AUTO_CONT 0xC
>>>> +
>>>> +#define CPR3_REG_CPR_STEP_QUOT 0x14
>>>> +#define CPR3_CPR_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>>>> +#define CPR3_CPR_STEP_QUOT_MIN_SHIFT 0
>>>> +#define CPR3_CPR_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>>>> +#define CPR3_CPR_STEP_QUOT_MAX_SHIFT 6
>>>> +#define CPRH_DELTA_QUOT_STEP_FACTOR 4
>>>> +
>>>> +#define CPR3_REG_GCNT(ro) (0xA0 + 0x4 * (ro))
>>>> +#define CPR3_REG_SENSOR_OWNER(sensor) (0x200 + 0x4 * (sensor))
>>>> +
>>>> +#define CPR3_REG_CONT_CMD 0x800
>>>> +#define CPR3_CONT_CMD_ACK 0x1
>>>> +#define CPR3_CONT_CMD_NACK 0x0
>>>> +
>>>> +#define CPR3_REG_THRESH(thread) (0x808 + 0x440 * (thread))
>>>> +#define CPR3_THRESH_CONS_DOWN_MASK GENMASK(3, 0)
>>>> +#define CPR3_THRESH_CONS_DOWN_SHIFT 0
>>>> +#define CPR3_THRESH_CONS_UP_MASK GENMASK(7, 4)
>>>> +#define CPR3_THRESH_CONS_UP_SHIFT 4
>>>> +#define CPR3_THRESH_DOWN_THRESH_MASK GENMASK(12, 8)
>>>> +#define CPR3_THRESH_DOWN_THRESH_SHIFT 8
>>>> +#define CPR3_THRESH_UP_THRESH_MASK GENMASK(17, 13)
>>>> +#define CPR3_THRESH_UP_THRESH_SHIFT 13
>>>> +
>>>> +#define CPR3_REG_RO_MASK(thread) (0x80C + 0x440 * (thread))
>>>> +
>>>> +#define CPR3_REG_RESULT0(thread) (0x810 + 0x440 * (thread))
>>>> +#define CPR3_RESULT0_BUSY_MASK BIT(0)
>>>> +#define CPR3_RESULT0_STEP_DN_MASK BIT(1)
>>>> +#define CPR3_RESULT0_STEP_UP_MASK BIT(2)
>>>> +#define CPR3_RESULT0_ERROR_STEPS_MASK GENMASK(7, 3)
>>>> +#define CPR3_RESULT0_ERROR_STEPS_SHIFT 3
>>>> +#define CPR3_RESULT0_ERROR_MASK GENMASK(19, 8)
>>>> +#define CPR3_RESULT0_ERROR_SHIFT 8
>>>> +
>>>> +#define CPR3_REG_RESULT1(thread) (0x814 + 0x440 * (thread))
>>>> +#define CPR3_RESULT1_QUOT_MIN_MASK GENMASK(11, 0)
>>>> +#define CPR3_RESULT1_QUOT_MIN_SHIFT 0
>>>> +#define CPR3_RESULT1_QUOT_MAX_MASK GENMASK(23, 12)
>>>> +#define CPR3_RESULT1_QUOT_MAX_SHIFT 12
>>>> +#define CPR3_RESULT1_RO_MIN_MASK GENMASK(27, 24)
>>>> +#define CPR3_RESULT1_RO_MIN_SHIFT 24
>>>> +#define CPR3_RESULT1_RO_MAX_MASK GENMASK(31, 28)
>>>> +#define CPR3_RESULT1_RO_MAX_SHIFT 28
>>>> +
>>>> +#define CPR3_REG_RESULT2(thread) (0x818 + 0x440 * (thread))
>>>> +#define CPR3_RESULT2_STEP_QUOT_MIN_MASK GENMASK(5, 0)
>>>> +#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT 0
>>>> +#define CPR3_RESULT2_STEP_QUOT_MAX_MASK GENMASK(11, 6)
>>>> +#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT 6
>>>> +#define CPR3_RESULT2_SENSOR_MIN_MASK GENMASK(23, 16)
>>>> +#define CPR3_RESULT2_SENSOR_MIN_SHIFT 16
>>>> +#define CPR3_RESULT2_SENSOR_MAX_MASK GENMASK(31, 24)
>>>> +#define CPR3_RESULT2_SENSOR_MAX_SHIFT 24
>>>> +
>>>> +#define CPR3_REG_IRQ_EN 0x81C
>>>> +#define CPR3_REG_IRQ_CLEAR 0x820
>>>> +#define CPR3_REG_IRQ_STATUS 0x824
>>>> +#define CPR3_IRQ_UP BIT(3)
>>>> +#define CPR3_IRQ_MID BIT(2)
>>>> +#define CPR3_IRQ_DOWN BIT(1)
>>>> +#define CPR3_IRQ_ALL (CPR3_IRQ_UP | CPR3_IRQ_MID | CPR3_IRQ_DOWN)
>>>> +
>>>> +#define CPR3_REG_TARGET_QUOT(thread, ro) (0x840 + 0x440 * (thread) + 0x4 * (ro))
>>>> +
>>>> +/* Registers found only on controllers that support HW closed-loop. */
>>>> +#define CPR3_REG_PD_THROTTLE 0xE8
>>>> +
>>>> +#define CPR3_REG_HW_CLOSED_LOOP_DISABLED 0x3000
>>>> +#define CPR3_REG_CPR_TIMER_MID_CONT 0x3004
>>>> +#define CPR3_REG_CPR_TIMER_UP_DN_CONT 0x3008
>>>> +
>>>> +/* CPR4 controller specific registers and bit definitions */
>>>> +#define CPR4_REG_CPR_TIMER_CLAMP 0x10
>>>> +#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27)
>>>> +
>>>> +#define CPR4_REG_MISC 0x700
>>>> +#define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2)
>>>> +#define CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN BIT(3)
>>>> +
>>>> +#define CPR4_REG_SAW_ERROR_STEP_LIMIT 0x7A4
>>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK GENMASK(4, 0)
>>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT 0
>>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK GENMASK(9, 5)
>>>> +#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT 5
>>>> +
>>>> +#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS 0x7A8
>>>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK GENMASK(28, 18)
>>>> +#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT 18
>>>> +
>>>> +#define CPR4_REG_MARGIN_ADJ_CTL 0x7F8
>>>> +#define CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN BIT(4)
>>>> +#define CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN BIT(7)
>>>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK GENMASK(16, 12)
>>>> +#define CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT 12
>>>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_MASK GENMASK(31, 26)
>>>> +#define CPR4_MARGIN_ADJ_KV_MARGIN_ADJ_STEP_QUOT_SHIFT 26
>>>> +
>>>> +#define CPR4_REG_CPR_MASK_THREAD(thread) (0x80C + 0x440 * (thread))
>>>> +#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD BIT(31)
>>>> +#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0)
>>>> +
>>>> +/* CPRh controller specific registers and bit definitions */
>>>> +#define __CPRH_REG_CORNER(rbase, tbase, tid, cnum) (rbase + (tbase * tid) + (0x4 * cnum))
>>>> +#define CPRH_REG_CORNER(d, t, c) __CPRH_REG_CORNER(d->reg_corner, d->reg_corner_tid, t, c)
>>>> +
>>>> +#define CPRH_CTL_OSM_ENABLED BIT(0)
>>>> +#define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1)
>>>> +#define CPRH_CTL_BASE_VOLTAGE_SHIFT 1
>>>> +#define CPRH_CTL_MODE_SWITCH_DELAY_MASK GENMASK(24, 17)
>>>> +#define CPRH_CTL_MODE_SWITCH_DELAY_SHIFT 17
>>>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_MASK GENMASK(28, 25)
>>>> +#define CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT 25
>>>> +
>>>> +#define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0)
>>>> +#define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0
>>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8)
>>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_SHIFT 8
>>>> +#define CPRH_CORNER_QUOT_DELTA_MASK GENMASK(24, 16)
>>>> +#define CPRH_CORNER_QUOT_DELTA_SHIFT 16
>>>> +#define CPRH_CORNER_RO_SEL_MASK GENMASK(28, 25)
>>>> +#define CPRH_CORNER_RO_SEL_SHIFT 25
>>>> +#define CPRH_CORNER_CPR_CL_DISABLE BIT(29)
>>>> +
>>>> +#define CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE 255
>>>> +#define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255
>>>> +#define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511
>>>> +
>>>> +enum cpr_type {
>>>> + CTRL_TYPE_CPR3,
>>>> + CTRL_TYPE_CPR4,
>>>> + CTRL_TYPE_CPRH,
>>>> + CTRL_TYPE_MAX,
>>>> +};
>>>> +
>>>> +/*
>>>> + * struct cpr_thread_desc - CPR Thread-specific parameters
>>>> + *
>>>> + * @controller_id: Identifier of the CPR controller expected by the HW
>>>> + * @ro_scaling_factor: Scaling factor for each ring oscillator entry
>>>> + * @hw_tid: Identifier of the CPR thread expected by the HW
>>>> + * @init_voltage_step: Voltage in uV for number of steps read from fuse array
>>>> + * @init_voltage_width: Bit-width of the voltage read from the fuse array
>>>> + * @sensor_range_start: First sensor ID used by a thread
>>>> + * @sensor_range_end: Last sensor ID used by a thread
>>>> + * @num_fuse_corners: Number of valid entries in fuse_corner_data
>>>> + * @step_quot_init_min: Minimum achievable step quotient for this corner
>>>> + * @step_quot_init_max: Maximum achievable step quotient for this corner
>>>> + * @fuse_corner_data: Parameters for calculation of each fuse corner
>>>> + */
>>>> +struct cpr_thread_desc {
>>>> + u8 controller_id;
>>>> + u8 hw_tid;
>>>> + const int (*ro_scaling_factor)[CPR3_RO_COUNT];
>>>> + int ro_avail_corners;
>>>> + int init_voltage_step;
>>>> + int init_voltage_width;
>>>> + u8 sensor_range_start;
>>>> + u8 sensor_range_end;
>>>> + u8 step_quot_init_min;
>>>> + u8 step_quot_init_max;
>>>> + unsigned int num_fuse_corners;
>>>> + struct fuse_corner_data *fuse_corner_data;
>>>> +};
>>>> +
>>>> +/*
>>>> + * struct cpr_desc - Driver instance-wide CPR parameters
>>>> + *
>>>> + * @cpr_type: Type (base version) of the CPR controller
>>>> + * @num_threads: Max. number of threads supported by this controller
>>>> + * @timer_delay_us: Loop delay time in uS
>>>> + * @timer_updn_delay_us: Voltage after-up/before-down delay time in uS
>>>> + * @timer_cons_up: Wait between consecutive up requests in uS
>>>> + * @timer_cons_down: Wait between consecutive down requests in uS
>>>> + * @up_threshold: Generic corner up threshold
>>>> + * @down_threshold: Generic corner down threshold
>>>> + * @idle_clocks: CPR Sensor: idle timer in cpr clocks unit
>>>> + * @count_mode: CPR Sensor: counting mode
>>>> + * @count_repeat: CPR Sensor: number of times to repeat reading
>>>> + * @gcnt_us: CPR measurement interval in uS
>>>> + * @vreg_step_fixed: Regulator voltage per step (if vreg unusable)
>>>> + * @vreg_step_up_limit: Num. of steps up at once before re-measuring sensors
>>>> + * @vreg_step_down_limit: Num. of steps dn at once before re-measuring sensors
>>>> + * @vdd_settle_time_us: Settling timer to account for one VDD supply step
>>>> + * @corner_settle_time_us: Settle time for corner switch request
>>>> + * @mem_acc_threshold: Memory Accelerator (MEM-ACC) voltage threshold
>>>> + * @apm_threshold: Array Power Mux (APM) voltage threshold
>>>> + * @apm_crossover: Array Power Mux (APM) corner crossover voltage
>>>> + * @apm_hysteresis: Hysteresis for APM V-threshold related calculations
>>>> + * @cpr_base_voltage: Safety: Absolute minimum voltage (uV) on this CPR
>>>> + * @cpr_max_voltage: Safety: Absolute maximum voltage (uV) on this CPR
>>>> + * @pd_throttle_val: CPR Power Domain throttle during voltage switch
>>>> + * @threads: Array containing "CPR Thread" specific parameters
>>>> + * @reduce_to_fuse_uV: Reduce corner max volts (if higher) to fuse ceiling
>>>> + * @reduce_to_corner_uV: Reduce corner max volts (if higher) to corner ceil.
>>>> + * @hw_closed_loop_en: Enable CPR HW Closed-Loop voltage auto-adjustment
>>>> + */
>>>> +struct cpr_desc {
>>>> + enum cpr_type cpr_type;
>>>> + unsigned int num_threads;
>>>> + unsigned int timer_delay_us;
>>>> + u8 timer_updn_delay_us;
>>>> + u8 timer_cons_up;
>>>> + u8 timer_cons_down;
>>>> + u8 up_threshold;
>>>> + u8 down_threshold;
>>>> + u8 idle_clocks;
>>>> + u8 count_mode;
>>>> + u8 count_repeat;
>>>> + u8 gcnt_us;
>>>> + u16 vreg_step_fixed;
>>>> + u8 vreg_step_up_limit;
>>>> + u8 vreg_step_down_limit;
>>>> + u8 vdd_settle_time_us;
>>>> + u8 corner_settle_time_us;
>>>> + int mem_acc_threshold;
>>>> + int apm_threshold;
>>>> + int apm_crossover;
>>>> + int apm_hysteresis;
>>>> + u32 cpr_base_voltage;
>>>> + u32 cpr_max_voltage;
>>>> + u32 pd_throttle_val;
>>>> +
>>>> + const struct cpr_thread_desc **threads;
>>>> + bool reduce_to_fuse_uV;
>>>> + bool reduce_to_corner_uV;
>>>> + bool hw_closed_loop_en;
>>>> +};
>>>> +
>>>> +struct cpr_drv;
>>>> +struct cpr_thread {
>>>> + int num_corners;
>>>> + int id;
>>>> + bool enabled;
>>>> + void __iomem *base;
>>>> + struct clk *cpu_clk;
>>>> + struct corner *corner;
>>>> + struct corner *corners;
>>>> + struct fuse_corner *fuse_corners;
>>>> + struct cpr_drv *drv;
>>>> + struct cpr_ext_data ext_data;
>>>> + struct generic_pm_domain pd;
>>>> + struct device *attached_cpu_dev;
>>>> + struct work_struct restart_work;
>>>> + bool restarting;
>>>> +
>>>> + const struct cpr_fuse *cpr_fuses;
>>>> + const struct cpr_thread_desc *desc;
>>>> +};
>>>> +
>>>> +struct cpr_drv {
>>>> + int irq;
>>>> + unsigned int ref_clk_khz;
>>>> + struct device *dev;
>>>> + struct mutex lock;
>>>> + struct regulator *vreg;
>>>> + struct regmap *tcsr;
>>>> + u32 gcnt;
>>>> + u32 speed_bin;
>>>> + u32 fusing_rev;
>>>> + u32 last_uV;
>>>> + u32 cpr_hw_rev;
>>>> + u32 reg_corner;
>>>> + u32 reg_corner_tid;
>>>> + u32 reg_ctl;
>>>> + u32 reg_status;
>>>> + int fuse_level_set;
>>>> + int extra_corners;
>>>> + unsigned int vreg_step;
>>>> + bool enabled;
>>>> +
>>>> + struct cpr_thread *threads;
>>>> + struct genpd_onecell_data cell_data;
>>>> +
>>>> + const struct cpr_desc *desc;
>>>> + const struct acc_desc *acc_desc;
>>>> + struct dentry *debugfs;
>>>> +};
>>>> +
>>>> +/**
>>>> + * cpr_get_corner_post_vadj() - Get corner post-voltage adjustment values
>>>> + * @opp: Pointer to the corresponding OPP struct
>>>> + * @tid: CPR thread ID
>>>> + * @open_loop: Pointer to the closed-loop adjustment value
>>>> + * @closed_loop: Pointer to the open-loop adjustment value
>>>> + */
>>>> +void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
>>>> + s32 *open_loop, s32 *closed_loop)
>>>> +{
>>>> + struct device_node *np;
>>>> +
>>>> + /*
>>>> + * There is no of_property_read_s32_index, so we just store the
>>>> + * result into a s32 variable. After all, the OF API is doing
>>>> + * the exact same for of_property_read_s32...
>>>> + */
>>>> + np = dev_pm_opp_get_of_node(opp);
>>>> + if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid, open_loop))
>>>> + *open_loop = 0;
>>>> +
>>>> + if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid, closed_loop))
>>>> + *closed_loop = 0;
>>>> +
>>>> + of_node_put(np);
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_get_ro_factor() - Get fuse corner ring oscillator factor
>>>> + * @tdesc: CPR Thread-specific parameters
>>>> + * @fnum: Fuse corner
>>>> + * @ro_idx: Ring Oscillator fuse number
>>>> + *
>>>> + * Not all threads have different scaling factors for each
>>>> + * Fuse Corner: if the RO factors are the same for all corners,
>>>> + * then only one is specified, instead of uselessly repeating
>>>> + * the same array for FC-times.
>>>> + * This function checks for the same and gives back the right
>>>> + * factor for the requested ring oscillator.
>>>> + *
>>>> + * Return: Ring oscillator factor
>>>> + */
>>>> +static int cpr_get_ro_factor(const struct cpr_thread_desc *tdesc,
>>>> + int fnum, int ro_idx)
>>>> +{
>>>> + int ro_fnum;
>>>> +
>>>> + if (tdesc->ro_avail_corners == tdesc->num_fuse_corners)
>>>> + ro_fnum = fnum;
>>>> + else
>>>> + ro_fnum = 0;
>>>> +
>>>> + return tdesc->ro_scaling_factor[ro_fnum][ro_idx];
>>>> +}
>>>> +
>>>> +static void cpr_write(struct cpr_thread *thread, u32 offset, u32 value)
>>>> +{
>>>> + writel(value, thread->base + offset);
>>>> +}
>>>> +
>>>> +static u32 cpr_read(struct cpr_thread *thread, u32 offset)
>>>> +{
>>>> + return readl(thread->base + offset);
>>>> +}
>>>> +
>>>> +static void
>>>> +cpr_masked_write(struct cpr_thread *thread, u32 offset, u32 mask, u32 value)
>>>> +{
>>>> + u32 val;
>>>> +
>>>> + val = readl(thread->base + offset);
>>>> + val &= ~mask;
>>>> + val |= value & mask;
>>>> + writel(val, thread->base + offset);
>>>> +}
>>>> +
>>>> +static void cpr_irq_clr(struct cpr_thread *thread)
>>>> +{
>>>> + cpr_write(thread, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_ALL);
>>>> +}
>>>> +
>>>> +static void cpr_irq_clr_nack(struct cpr_thread *thread)
>>>> +{
>>>> + cpr_irq_clr(thread);
>>>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
>>>> +}
>>>> +
>>>> +static void cpr_irq_clr_ack(struct cpr_thread *thread)
>>>> +{
>>>> + cpr_irq_clr(thread);
>>>> + cpr_write(thread, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_ACK);
>>>> +}
>>>> +
>>>> +static void cpr_irq_set(struct cpr_thread *thread, u32 int_bits)
>>>> +{
>>>> + /* On CPR-hardened, interrupts are managed by and on firmware */
>>>> + if (thread->drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + return;
>>>> +
>>>> + cpr_write(thread, CPR3_REG_IRQ_EN, int_bits);
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_ctl_enable() - Enable CPR thread
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + */
>>>> +static void cpr_ctl_enable(struct cpr_thread *thread)
>>>> +{
>>>> + if (thread->drv->enabled && !thread->restarting) {
>>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>>>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>>>> + }
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_ctl_disable() - Disable CPR thread
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + */
>>>> +static void cpr_ctl_disable(struct cpr_thread *thread)
>>>> +{
>>>> + const struct cpr_desc *desc = thread->drv->desc;
>>>> +
>>>> + if (desc->cpr_type != CTRL_TYPE_CPRH) {
>>>> + cpr_irq_set(thread, 0);
>>>> + cpr_irq_clr(thread);
>>>> + }
>>>> +
>>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>>> + CPR3_CPR_CTL_LOOP_EN_MASK, 0);
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_ctl_is_enabled() - Check if thread is enabled
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Return: true if the CPR is enabled, false if it is disabled.
>>>> + */
>>>> +static bool cpr_ctl_is_enabled(struct cpr_thread *thread)
>>>> +{
>>>> + u32 reg_val;
>>>> +
>>>> + reg_val = cpr_read(thread, CPR3_REG_CPR_CTL);
>>>> + return reg_val & CPR3_CPR_CTL_LOOP_EN_MASK;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_check_any_thread_busy() - Check if HW is done processing
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Return: true if the CPR is busy, false if it is ready.
>>>> + */
>>>> +static bool cpr_check_any_thread_busy(struct cpr_thread *thread)
>>>> +{
>>>> + int i;
>>>> +
>>>> + for (i = 0; i < thread->drv->desc->num_threads; i++)
>>>> + if (cpr_read(thread, CPR3_REG_RESULT0(i)) &
>>>> + CPR3_RESULT0_BUSY_MASK)
>>>> + return true;
>>>> +
>>>> + return false;
>>>> +}
>>>> +
>>>> +static void cpr_restart_worker(struct work_struct *work)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(work, struct cpr_thread,
>>>> + restart_work);
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + int i;
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + thread->restarting = true;
>>>> + cpr_ctl_disable(thread);
>>>> + disable_irq(drv->irq);
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + for (i = 0; i < 20; i++) {
>>>> + u32 cpr_status = cpr_read(thread, CPR3_REG_CPR_STATUS);
>>>> + u32 ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>>>> +
>>>> + if ((cpr_status & CPR3_CPR_STATUS_BUSY_MASK) &&
>>>> + !(ctl & CPR3_CPR_CTL_LOOP_EN_MASK))
>>>> + break;
>>>> +
>>>> + udelay(10);
>>>> + }
>>>> +
>>>> + cpr_irq_clr(thread);
>>>> +
>>>> + for (i = 0; i < 20; i++) {
>>>> + u32 status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>>> +
>>>> + if (!(status & CPR3_IRQ_ALL))
>>>> + break;
>>>> + udelay(10);
>>>> + }
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + thread->restarting = false;
>>>> + enable_irq(drv->irq);
>>>> + cpr_ctl_enable(thread);
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_corner_restore() - Restore saved corner level
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + * @corner: Structure holding the saved corner level
>>>> + */
>>>> +static void cpr_corner_restore(struct cpr_thread *thread,
>>>> + struct corner *corner)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + struct fuse_corner *fuse = corner->fuse_corner;
>>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>>> + u32 ro_sel = fuse->ring_osc_idx;
>>>> +
>>>> + cpr_write(thread, CPR3_REG_GCNT(ro_sel), drv->gcnt);
>>>> +
>>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid),
>>>> + CPR3_RO_MASK & ~BIT(ro_sel));
>>>> +
>>>> + cpr_write(thread, CPR3_REG_TARGET_QUOT(tdesc->hw_tid, ro_sel),
>>>> + fuse->quot - corner->quot_adjust);
>>>> +
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR4)
>>>> + cpr_masked_write(thread,
>>>> + CPR4_REG_CPR_MASK_THREAD(tdesc->hw_tid),
>>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK, 0);
>>>> +
>>>> + thread->corner = corner;
>>>> + corner->last_uV = corner->uV;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_set_acc() - Set fuse level to the mem-acc
>>>> + * @drv: Main driver structure
>>>> + * @f:�� Fuse level
>>>> + */
>>>> +static void cpr_set_acc(struct cpr_drv *drv, int f)
>>>> +{
>>>> + const struct acc_desc *desc = drv->acc_desc;
>>>> + struct reg_sequence *s = desc->settings;
>>>> + int n = desc->num_regs_per_fuse;
>>>> +
>>>> + if (!s || f == drv->fuse_level_set)
>>>> + return;
>>>> +
>>>> + regmap_multi_reg_write(drv->tcsr, s + (n * f), n);
>>>> + drv->fuse_level_set = f;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_pre_voltage() - Actions to execute before setting voltage
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + * @dir: Enumeration for voltage change direction
>>>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>>>> + *
>>>> + * Return: Zero for success or negative number on errors.
>>>> + */
>>>> +static int cpr_pre_voltage(struct cpr_thread *thread,
>>>> + enum voltage_change_dir dir,
>>>> + int fuse_level)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> +
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3 &&
>>>> + drv->desc->pd_throttle_val)
>>>> + cpr_write(thread, CPR3_REG_PD_THROTTLE,
>>>> + drv->desc->pd_throttle_val);
>>>> +
>>>> + if (drv->tcsr && dir == DOWN)
>>>> + cpr_set_acc(drv, fuse_level);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_post_voltage() - Actions to execute after setting voltage
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + * @dir: Enumeration for voltage change direction
>>>> + * @fuse_level: Fuse corner for mem-acc, if supported.
>>>> + *
>>>> + * Return: Zero for success or negative number on errors.
>>>> + */
>>>> +static int cpr_post_voltage(struct cpr_thread *thread,
>>>> + enum voltage_change_dir dir,
>>>> + int fuse_level)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> +
>>>> + if (drv->tcsr && dir == UP)
>>>> + cpr_set_acc(drv, fuse_level);
>>>> +
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPR3)
>>>> + cpr_write(thread, CPR3_REG_PD_THROTTLE, 0);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_commit_state() - Set the newly requested voltage
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>>>> + */
>>>> +static int cpr_commit_state(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + int min_uV = 0, max_uV = 0, new_uV = 0, fuse_level = 0;
>>>> + enum voltage_change_dir dir;
>>>> + u32 next_irqmask = 0;
>>>> + int ret, i;
>>>> +
>>>> + /* On CPRhardened, control states are managed in firmware */
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + return 0;
>>>> +
>>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>>> + struct cpr_thread *thread = &drv->threads[i];
>>>> +
>>>> + if (!thread->corner)
>>>> + continue;
>>>> +
>>>> + fuse_level = max(fuse_level,
>>>> + (int) (thread->corner->fuse_corner -
>>>> + &thread->fuse_corners[0]));
>>>> +
>>>> + max_uV = max(max_uV, thread->corner->max_uV);
>>>> + min_uV = max(min_uV, thread->corner->min_uV);
>>>> + new_uV = max(new_uV, thread->corner->last_uV);
>>>> + }
>>>> + dev_vdbg(drv->dev, "%s: new uV: %d, last uV: %d\n",
>>>> + __func__, new_uV, drv->last_uV);
>>>> +
>>>> + /*
>>>> + * Safety measure: if the voltage is out of the globally allowed
>>>> + * range, then go out and warn the user.
>>>> + * This should *never* happen.
>>>> + */
>>>> + if (new_uV > drv->desc->cpr_max_voltage ||
>>>> + new_uV < drv->desc->cpr_base_voltage) {
>>>> + dev_warn(drv->dev, "Voltage (%u uV) out of range.", new_uV);
>>>> + return -EINVAL;
>>>> + }
>>>> +
>>>> + if (new_uV == drv->last_uV || fuse_level == drv->fuse_level_set)
>>>> + goto out;
>>>> +
>>>> + if (fuse_level > drv->fuse_level_set)
>>>> + dir = UP;
>>>> + else
>>>> + dir = DOWN;
>>>> +
>>>> + ret = cpr_pre_voltage(thread, fuse_level, dir);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + dev_vdbg(drv->dev, "setting voltage: %d\n", new_uV);
>>>> +
>>>> + ret = regulator_set_voltage(drv->vreg, new_uV, new_uV);
>>>> + if (ret) {
>>>> + dev_err_ratelimited(drv->dev, "failed to set voltage %d: %d\n", new_uV, ret);
>>>> + return ret;
>>>> + }
>>>> +
>>>> + ret = cpr_post_voltage(thread, fuse_level, dir);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + drv->last_uV = new_uV;
>>>> +out:
>>>> + if (new_uV > min_uV)
>>>> + next_irqmask |= CPR3_IRQ_DOWN;
>>>> + if (new_uV < max_uV)
>>>> + next_irqmask |= CPR3_IRQ_UP;
>>>> +
>>>> + cpr_irq_set(thread, next_irqmask);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static unsigned int cpr_get_cur_perf_state(struct cpr_thread *thread)
>>>> +{
>>>> + return thread->corner ? thread->corner - thread->corners + 1 : 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_scale() - Calculate new voltage for the received direction
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + * @dir: Enumeration for voltage change direction
>>>> + *
>>>> + * The CPR scales one by one: this function calculates the new
>>>> + * voltage to set when a voltage-UP or voltage-DOWN request comes
>>>> + * and stores it into the per-thread structure that gets passed.
>>>> + */
>>>> +static void cpr_scale(struct cpr_thread *thread, enum voltage_change_dir dir)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>>> + u32 val, error_steps;
>>>> + int last_uV, new_uV;
>>>> + struct corner *corner;
>>>> +
>>>> + if (dir != UP && dir != DOWN)
>>>> + return;
>>>> +
>>>> + corner = thread->corner;
>>>> + val = cpr_read(thread, CPR3_REG_RESULT0(tdesc->hw_tid));
>>>> + error_steps = val >> CPR3_RESULT0_ERROR_STEPS_SHIFT;
>>>> + error_steps &= CPR3_RESULT0_ERROR_STEPS_MASK;
>>>> +
>>>> + last_uV = corner->last_uV;
>>>> +
>>>> + if (dir == UP) {
>>>> + if (!(val & CPR3_RESULT0_STEP_UP_MASK))
>>>> + return;
>>>> +
>>>> + /* Calculate new voltage */
>>>> + new_uV = last_uV + drv->vreg_step;
>>>> + new_uV = min(new_uV, corner->max_uV);
>>>> +
>>>> + dev_vdbg(drv->dev, "[T%u] UP - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>>>> + thread->id, new_uV, last_uV,
>>>> + cpr_get_cur_perf_state(thread), error_steps);
>>>> + } else {
>>>> + if (!(val & CPR3_RESULT0_STEP_DN_MASK))
>>>> + return;
>>>> +
>>>> + /* Calculate new voltage */
>>>> + new_uV = last_uV - drv->vreg_step;
>>>> + new_uV = max(new_uV, corner->min_uV);
>>>> + dev_vdbg(drv->dev, "[T%u] DOWN - new_uV=%d last_uV=%d p-state=%u st=%u\n",
>>>> + thread->id, new_uV, last_uV,
>>>> + cpr_get_cur_perf_state(thread), error_steps);
>>>> + }
>>>> + corner->last_uV = new_uV;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_irq_handler() - Handle CPR3/CPR4 status interrupts
>>>> + * @irq: Number of the interrupt
>>>> + * @dev: Pointer to the cpr_thread structure
>>>> + *
>>>> + * Handle the interrupts coming from non-hardened CPR HW as to get
>>>> + * an ok to scale voltages immediately, or to pass error status to
>>>> + * the hardware (either success/ACK or failure/NACK).
>>>> + *
>>>> + * Return: IRQ_SUCCESS for success, IRQ_NONE if the CPR is disabled.
>>>> + */
>>>> +static irqreturn_t cpr_irq_handler(int irq, void *dev)
>>>> +{
>>>> + struct cpr_thread *thread = dev;
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + irqreturn_t ret = IRQ_HANDLED;
>>>> + int i, rc;
>>>> + enum voltage_change_dir dir = NO_CHANGE;
>>>> + u32 val;
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + val = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>>> +
>>>> + dev_vdbg(drv->dev, "IRQ_STATUS = %#02x\n", val);
>>>> +
>>>> + if (!cpr_ctl_is_enabled(thread)) {
>>>> + dev_vdbg(drv->dev, "CPR is disabled\n");
>>>> + ret = IRQ_NONE;
>>>> + } else if (cpr_check_any_thread_busy(thread)) {
>>>> + cpr_irq_clr_nack(thread);
>>>> + dev_dbg(drv->dev, "CPR measurement is not ready\n");
>>>> + } else {
>>>> + /*
>>>> + * Following sequence of handling is as per each IRQ's
>>>> + * priority
>>>> + */
>>>> + if (val & CPR3_IRQ_UP)
>>>> + dir = UP;
>>>> + else if (val & CPR3_IRQ_DOWN)
>>>> + dir = DOWN;
>>>> +
>>>> + if (dir != NO_CHANGE) {
>>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>>> + thread = &drv->threads[i];
>>>> + cpr_scale(thread, dir);
>>>> + }
>>>> +
>>>> + rc = cpr_commit_state(thread);
>>>> + if (rc)
>>>> + cpr_irq_clr_nack(thread);
>>>> + else
>>>> + cpr_irq_clr_ack(thread);
>>>> + } else if (val & CPR3_IRQ_MID) {
>>>> + dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n");
>>>> + } else {
>>>> + dev_warn(drv->dev, "IRQ occurred for unknown flag (%#08x)\n", val);
>>>> + schedule_work(&thread->restart_work);
>>>> + }
>>>> + }
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +static int cpr_switch(struct cpr_drv *drv)
>>>> +{
>>>> + int i, ret;
>>>> + bool enabled = false;
>>>> +
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + return 0;
>>>> +
>>>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>>>> + enabled = drv->threads[i].enabled;
>>>> +
>>>> + dev_vdbg(drv->dev, "%s: enabled = %d\n", __func__, enabled);
>>>> +
>>>> + if (enabled == drv->enabled)
>>>> + return 0;
>>>> +
>>>> + if (enabled) {
>>>> + ret = regulator_enable(drv->vreg);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + drv->enabled = enabled;
>>>> +
>>>> + for (i = 0; i < drv->desc->num_threads; i++)
>>>> + if (drv->threads[i].corner)
>>>> + break;
>>>> +
>>>> + if (i < drv->desc->num_threads) {
>>>> + cpr_irq_clr(&drv->threads[i]);
>>>> +
>>>> + cpr_commit_state(&drv->threads[i]);
>>>> + cpr_ctl_enable(&drv->threads[i]);
>>>> + }
>>>> + } else {
>>>> + for (i = 0; i < drv->desc->num_threads && !enabled; i++)
>>>> + cpr_ctl_disable(&drv->threads[i]);
>>>> +
>>>> + drv->enabled = enabled;
>>>> +
>>>> + ret = regulator_disable(drv->vreg);
>>>> + if (ret < 0)
>>>> + return ret;
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_enable() - Enables a CPR thread
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Return: Zero for success or negative number on errors.
>>>> + */
>>>> +static int cpr_enable(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + int ret;
>>>> +
>>>> + dev_dbg(drv->dev, "Enabling thread %d\n", thread->id);
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + thread->enabled = true;
>>>> + ret = cpr_switch(thread->drv);
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_disable() - Disables a CPR thread
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Return: Zero for success or negative number on errors.
>>>> + */
>>>> +static int cpr_disable(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + int ret;
>>>> +
>>>> + dev_dbg(drv->dev, "Disabling thread %d\n", thread->id);
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + thread->enabled = false;
>>>> + ret = cpr_switch(thread->drv);
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_configure() - Configure main HW parameters
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * This function configures the main CPR hardware parameters, such as
>>>> + * internal timers (and delays), sensor ownerships, activates and/or
>>>> + * deactivates cpr-threads and others, as one sequence for all of the
>>>> + * versions supported in this driver. By design, the function may
>>>> + * return a success earlier if the sequence for "a previous version"
>>>> + * has ended.
>>>> + *
>>>> + * Context: The CPR must be clocked before calling this function!
>>>> + *
>>>> + * Return: Zero for success or negative number on errors.
>>>> + */
>>>> +static int cpr_configure(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + const struct cpr_desc *desc = drv->desc;
>>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>>> + u32 val;
>>>> + int i;
>>>> +
>>>> + /* Disable interrupt and CPR */
>>>> + cpr_irq_set(thread, 0);
>>>> + cpr_write(thread, CPR3_REG_CPR_CTL, 0);
>>>> +
>>>> + /* Init and save gcnt */
>>>> + drv->gcnt = drv->ref_clk_khz * desc->gcnt_us;
>>>> + do_div(drv->gcnt, 1000);
>>>> +
>>>> + /* Program the delay count for the timer */
>>>> + val = drv->ref_clk_khz * desc->timer_delay_us;
>>>> + do_div(val, 1000);
>>>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_MID_CONT, val);
>>>> +
>>>> + val = drv->ref_clk_khz * desc->timer_updn_delay_us;
>>>> + do_div(val, 1000);
>>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_UP_DN_CONT, val);
>>>> + } else {
>>>> + cpr_write(thread, CPR3_REG_CPR_TIMER_AUTO_CONT, val);
>>>> + }
>>>> + dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val,
>>>> + desc->timer_delay_us);
>>>> +
>>>> + /* Program the control register */
>>>> + val = desc->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT;
>>>> + val |= desc->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT;
>>>> + val |= desc->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT;
>>>> + cpr_write(thread, CPR3_REG_CPR_CTL, val);
>>>> +
>>>> + /* Configure CPR default step quotients */
>>>> + val = tdesc->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT;
>>>> + val |= tdesc->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT;
>>>> +
>>>> + cpr_write(thread, CPR3_REG_CPR_STEP_QUOT, val);
>>>> +
>>>> + /*
>>>> + * Configure the CPR sensor ownership always on thread 0
>>>> + * TODO: SDM845 has different ownership for sensors!!
>>>> + */
>>>> + for (i = tdesc->sensor_range_start; i < tdesc->sensor_range_end; i++)
>>>> + cpr_write(thread, CPR3_REG_SENSOR_OWNER(i), 0);
>>>> +
>>>> + /* Program Consecutive Up & Down */
>>>> + val = desc->timer_cons_up << CPR3_THRESH_CONS_UP_SHIFT;
>>>> + val |= desc->timer_cons_down << CPR3_THRESH_CONS_DOWN_SHIFT;
>>>> + val |= desc->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT;
>>>> + val |= desc->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT;
>>>> + cpr_write(thread, CPR3_REG_THRESH(tdesc->hw_tid), val);
>>>> +
>>>> + /* Mask all ring oscillators for all threads initially */
>>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), CPR3_RO_MASK);
>>>> +
>>>> + /* HW Closed-loop control */
>>>> + if (desc->cpr_type == CTRL_TYPE_CPR3) {
>>>> + cpr_write(thread, CPR3_REG_HW_CLOSED_LOOP_DISABLED,
>>>> + !desc->hw_closed_loop_en);
>>>> + } else {
>>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN,
>>>> + desc->hw_closed_loop_en ?
>>>> + CPR4_MARGIN_ADJ_HW_CLOSED_LOOP_EN : 0);
>>>> + }
>>>> +
>>>> + /* Additional configuration for CPR4 and beyond */
>>>> + if (desc->cpr_type < CTRL_TYPE_CPR4)
>>>> + return 0;
>>>> +
>>>> + /* Disable threads initially only on non-hardened CPR4 */
>>>> + if (desc->cpr_type == CTRL_TYPE_CPR4)
>>>> + cpr_masked_write(thread, CPR4_REG_CPR_MASK_THREAD(1),
>>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
>>>> + CPR4_CPR_MASK_THREAD_DISABLE_THREAD |
>>>> + CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
>>>> +
>>>> + if (tdesc->hw_tid > 0)
>>>> + cpr_masked_write(thread, CPR4_REG_MISC,
>>>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>>>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN,
>>>> + CPR4_MISC_RESET_STEP_QUOT_LOOP_EN |
>>>> + CPR4_MISC_THREAD_HAS_ALWAYS_VOTE_EN);
>>>> +
>>>> + val = drv->vreg_step;
>>>> + do_div(val, 1000);
>>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>>> + CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_MASK,
>>>> + val << CPR4_MARGIN_ADJ_PMIC_STEP_SIZE_SHIFT);
>>>> +
>>>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>>>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
>>>> + desc->vreg_step_down_limit <<
>>>> + CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT);
>>>> +
>>>> + cpr_masked_write(thread, CPR4_REG_SAW_ERROR_STEP_LIMIT,
>>>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
>>>> + desc->vreg_step_up_limit <<
>>>> + CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT);
>>>> +
>>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_ADJ_CTL,
>>>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN,
>>>> + CPR4_MARGIN_ADJ_PER_RO_KV_MARGIN_EN);
>>>> +
>>>> + if (tdesc->hw_tid > 0)
>>>> + cpr_masked_write(thread, CPR4_REG_CPR_TIMER_CLAMP,
>>>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
>>>> + CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
>>>> +
>>>> + /* Settling timer to account for one VDD supply step */
>>>> + if (desc->vdd_settle_time_us > 0) {
>>>> + u32 m = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK;
>>>> + u32 s = CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHFT;
>>>> +
>>>> + cpr_masked_write(thread, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
>>>> + m, desc->vdd_settle_time_us << s);
>>>> + }
>>>> +
>>>> + /* Additional configuration for CPR-hardened */
>>>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>>>> + return 0;
>>>> +
>>>> + /* Settling timer to account for one corner-switch request */
>>>> + if (desc->corner_settle_time_us > 0)
>>>> + cpr_masked_write(thread, drv->reg_ctl,
>>>> + CPRH_CTL_MODE_SWITCH_DELAY_MASK,
>>>> + desc->corner_settle_time_us <<
>>>> + CPRH_CTL_MODE_SWITCH_DELAY_SHIFT);
>>>> +
>>>> + /* Base voltage and multiplier values for CPRh internal calculations */
>>>> + cpr_masked_write(thread, drv->reg_ctl,
>>>> + CPRH_CTL_BASE_VOLTAGE_MASK,
>>>> + (DIV_ROUND_UP(desc->cpr_base_voltage,
>>>> + drv->vreg_step) <<
>>>> + CPRH_CTL_BASE_VOLTAGE_SHIFT));
>>>> +
>>>> + cpr_masked_write(thread, drv->reg_ctl,
>>>> + CPRH_CTL_VOLTAGE_MULTIPLIER_MASK,
>>>> + DIV_ROUND_UP(drv->vreg_step, 1000) <<
>>>> + CPRH_CTL_VOLTAGE_MULTIPLIER_SHIFT);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int cprh_dummy_set_performance_state(struct generic_pm_domain *domain,
>>>> + unsigned int state)
>>>> +{
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int cpr_set_performance_state(struct generic_pm_domain *domain,
>>>> + unsigned int state)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + struct corner *corner, *end;
>>>> + int ret = 0;
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + dev_dbg(drv->dev, "setting perf state: %u (prev state: %u thread: %u)\n",
>>>> + state, cpr_get_cur_perf_state(thread), thread->id);
>>>> +
>>>> + /*
>>>> + * Determine new corner we're going to.
>>>> + * Remove one since lowest performance state is 1.
>>>> + */
>>>> + corner = thread->corners + state - 1;
>>>> + end = &thread->corners[thread->num_corners - 1];
>>>> + if (corner > end || corner < thread->corners) {
>>>> + ret = -EINVAL;
>>>> + goto unlock;
>>>> + }
>>>> +
>>>> + cpr_ctl_disable(thread);
>>>> +
>>>> + cpr_irq_clr(thread);
>>>> + if (thread->corner != corner)
>>>> + cpr_corner_restore(thread, corner);
>>>> +
>>>> + ret = cpr_commit_state(thread);
>>>> + if (ret)
>>>> + goto unlock;
>>>> +
>>>> + cpr_ctl_enable(thread);
>>>> +unlock:
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + dev_dbg(drv->dev, "set perf state %u on thread %u\n", state, thread->id);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr3_adjust_quot - Adjust the closed-loop quotients
>>>> + * @ring_osc_factor: Ring oscillator adjustment factor
>>>> + * @volt_closed_loop: Closed-loop voltage adjustment factor
>>>> + *
>>>> + * Calculates the quotient adjustment factor based on closed-loop
>>>> + * quotients and ring oscillator factor.
>>>> + *
>>>> + * Return: Adjusted quotient
>>>> + */
>>>> +static int cpr3_adjust_quot(int ring_osc_factor, int volt_closed_loop)
>>>> +{
>>>> + s64 temp;
>>>> +
>>>> + if (ring_osc_factor == 0 || volt_closed_loop == 0)
>>>> + return 0;
>>>> +
>>>> + temp = (s64)(ring_osc_factor * volt_closed_loop);
>>>> + return (int)div_s64(temp, 1000000);
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_fuse_corner_init() - Calculate fuse corner table
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * This function populates the fuse corners table by reading the
>>>> + * values from the fuses, eventually adjusting them with a fixed
>>>> + * per-corner offset and doing basic checks about them being
>>>> + * supported by the regulator that is assigned to this CPR - if
>>>> + * it is available (on CPR-Hardened, there is no usable vreg, as
>>>> + * that is protected by the hypervisor).
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr_fuse_corner_init(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + const struct cpr_thread_desc *desc = thread->desc;
>>>> + const struct cpr_fuse *cpr_fuse = thread->cpr_fuses;
>>>> + struct fuse_corner_data *fdata;
>>>> + struct fuse_corner *fuse, *prev_fuse, *end;
>>>> + int i, ret;
>>>> +
>>>> + /* Populate fuse_corner members */
>>>> + fuse = thread->fuse_corners;
>>>> + prev_fuse = &fuse[0];
>>>> + end = &fuse[desc->num_fuse_corners - 1];
>>>> + fdata = desc->fuse_corner_data;
>>>> +
>>>> + for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
>>>> + int factor = cpr_get_ro_factor(desc, i, fuse->ring_osc_idx);
>>>> +
>>>> + ret = cpr_populate_fuse_common(drv->dev, fdata, cpr_fuse,
>>>> + fuse, drv->vreg_step,
>>>> + desc->init_voltage_width,
>>>> + desc->init_voltage_step);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + /*
>>>> + * Adjust the fuse quot with per-fuse-corner closed-loop
>>>> + * voltage adjustment parameters.
>>>> + */
>>>> + fuse->quot += cpr3_adjust_quot(factor, fdata->volt_cloop_adjust);
>>>> +
>>>> + /* CPRh: no regulator access... */
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + goto skip_pvs_restrict;
>>>> +
>>>> + /* Re-check if corner voltage range is supported by regulator */
>>>> + ret = cpr_check_vreg_constraints(drv->dev, drv->vreg, fuse);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> +skip_pvs_restrict:
>>>> + if (fuse->uV < prev_fuse->uV)
>>>> + fuse->uV = prev_fuse->uV;
>>>> + prev_fuse = fuse;
>>>> + dev_dbg(drv->dev, "fuse corner %d: [%d %d %d] RO%hhu quot %d\n",
>>>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>>>> + fuse->ring_osc_idx, fuse->quot);
>>>> +
>>>> + /* Check if constraints are valid */
>>>> + if (fuse->uV < fuse->min_uV || fuse->uV > fuse->max_uV) {
>>>> + dev_err(drv->dev, "fuse corner %d: Bad voltage range.\n", i);
>>>> + return -EINVAL;
>>>> + }
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static void cpr3_restrict_corner(struct corner *corner, int threshold,
>>>> + int hysteresis, int step)
>>>> +{
>>>> + if (threshold > corner->min_uV && threshold <= corner->max_uV) {
>>>> + if (corner->uV >= threshold) {
>>>> + corner->min_uV = max(corner->min_uV,
>>>> + threshold - hysteresis);
>>>> + if (corner->min_uV > corner->uV)
>>>> + corner->uV = corner->min_uV;
>>>> + } else {
>>>> + corner->max_uV = threshold;
>>>> + corner->max_uV -= step;
>>>> + }
>>>> + }
>>>> +}
>>>> +
>>>> +/*
>>>> + * cprh_corner_adjust_opps() - Set voltage on each CPU OPP table entry
>>>> + *
>>>> + * On CPR-Hardened, the voltage level is controlled internally through
>>>> + * the OSM hardware: in order to initialize the latter, we have to
>>>> + * communicate the voltage to its driver, so that it will be able to
>>>> + * write the right parameters (as they have to be set both on the CPRh
>>>> + * and on the OSM) on it.
>>>> + * This function is called only for CPRh.
>>>> + *
>>>> + * Return: Zero for success, negative number for error.
>>>> + */
>>>> +static int cprh_corner_adjust_opps(struct cpr_thread *thread)
>>>> +{
>>>> + struct corner *corner = thread->corners;
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + int i, ret;
>>>> +
>>>> + for (i = 0; i < thread->num_corners; i++) {
>>>> + ret = dev_pm_opp_adjust_voltage(thread->attached_cpu_dev,
>>>> + corner[i].freq,
>>>> + corner[i].uV,
>>>> + corner[i].min_uV,
>>>> + corner[i].max_uV);
>>>> + if (ret)
>>>> + break;
>>>> +
>>>> + dev_dbg(drv->dev, "OPP voltage adjusted for %lu kHz, %d uV\n",
>>>> + corner[i].freq, corner[i].uV);
>>>> + }
>>>> +
>>>> + /* If we couldn't adjust voltage for all corners, something went wrong */
>>>> + if (i < thread->num_corners)
>>>> + return -EINVAL;
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr3_corner_init() - Calculate and set-up corners for the CPR HW
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * This function calculates all the corner parameters by comparing
>>>> + * and interpolating the values read from the various set-points
>>>> + * read from the fuses (also called "fuse corners") to generate and
>>>> + * program to the CPR a lookup table that describes each voltage
>>>> + * step, mapped to a performance level (or corner number).
>>>> + *
>>>> + * It also programs other essential parameters on the CPR and - if
>>>> + * we are dealing with CPR-Hardened, it will also enable the internal
>>>> + * interface between the Operating State Manager (OSM) and the CPRh
>>>> + * in order to achieve CPU DVFS.
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr3_corner_init(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + const struct cpr_desc *desc = drv->desc;
>>>> + const struct cpr_thread_desc *tdesc = thread->desc;
>>>> + const struct cpr_fuse *fuses = thread->cpr_fuses;
>>>> + int i, ret, total_corners, extra_corners, level, scaling = 0;
>>>> + unsigned int fnum, fc;
>>>> + const char *quot_offset;
>>>> + const struct fuse_corner_data *fdata;
>>>> + struct fuse_corner *fuse, *prev_fuse;
>>>> + struct corner *corner, *prev_corner, *end;
>>>> + struct corner_data *cdata;
>>>> + struct dev_pm_opp *opp;
>>>> + unsigned long freq;
>>>> + u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
>>>> +
>>>> + corner = thread->corners;
>>>> + prev_corner = &thread->corners[0];
>>>> + end = &corner[thread->num_corners - 1];
>>>> +
>>>> + cdata = devm_kcalloc(drv->dev, thread->num_corners + drv->extra_corners,
>>>> + sizeof(struct corner_data), GFP_KERNEL);
>>>> + if (!cdata)
>>>> + return -ENOMEM;
>>>> +
>>>> + for (level = 1; level <= thread->num_corners; level++) {
>>>> + opp = dev_pm_opp_find_level_exact(&thread->pd.dev, level);
>>>> + if (IS_ERR(opp))
>>>> + return -EINVAL;
>>>> +
>>>> + /*
>>>> + * If there is only one specified qcom,opp-fuse-level, then
>>>> + * it is assumed that this only one is global and valid for
>>>> + * all IDs, so try to get the specific one but, on failure,
>>>> + * go for the global one.
>>>> + */
>>>> + fc = cpr_get_fuse_corner(opp, thread->id);
>>>> + if (fc == 0) {
>>>> + fc = cpr_get_fuse_corner(opp, 0);
>>>> + if (fc == 0) {
>>>> + �� dev_err(drv->dev, "qcom,opp-fuse-level is missing!\n");
>>>> + dev_pm_opp_put(opp);
>>>> + return -EINVAL;
>>>> + }
>>>> + }
>>>> + fnum = fc - 1;
>>>> +
>>>> + freq = cpr_get_opp_hz_for_req(opp, thread->attached_cpu_dev);
>>>> + if (!freq) {
>>>> + thread->num_corners = max(level - 1, 0);
>>>> + end = &thread->corners[thread->num_corners - 1];
>>>> + break;
>>>> + }
>>>> +
>>>> + /*
>>>> + * If any post-vadj (open/closed loop) is not specified, then
>>>> + * it's zero, meaning that it is not required for this corner.
>>>> + */
>>>> + cpr_get_corner_post_vadj(opp, thread->id,
>>>> + &cdata[level - 1].oloop_vadj,
>>>> + &cdata[level - 1].cloop_vadj);
>>>> + cdata[level - 1].fuse_corner = fnum;
>>>> + cdata[level - 1].freq = freq;
>>>> +
>>>> + fuse = &thread->fuse_corners[fnum];
>>>> + dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n",
>>>> + freq, dev_pm_opp_get_level(opp) - 1, fnum);
>>>> + if (freq > fuse->max_freq)
>>>> + fuse->max_freq = freq;
>>>> + dev_pm_opp_put(opp);
>>>> +
>>>> + /*
>>>> + * Make sure that the frequencies in the table are in ascending
>>>> + * order, as this is critical for the algorithm to work.
>>>> + */
>>>> + if (cdata[level - 2].freq > freq) {
>>>> + dev_err(drv->dev, "Frequency table not in ascending order.\n");
>>>> + return -EINVAL;
>>>> + }
>>>> + }
>>>> +
>>>> + if (thread->num_corners < 2) {
>>>> + dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
>>>> + return -EINVAL;
>>>> + }
>>>> +
>>>> + /*
>>>> + * Get the quotient adjustment scaling factor, according to:
>>>> + *
>>>> + * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
>>>> + * / (freq(corner_N) - freq(corner_N-1)), max_factor)
>>>> + *
>>>> + * QUOT(corner_N): quotient read from fuse for fuse corner N
>>>> + * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1)
>>>> + * freq(corner_N): max frequency in MHz supported by fuse corner N
>>>> + * freq(corner_N-1): max frequency in MHz supported by fuse corner
>>>> + * (N - 1)
>>>> + *
>>>> + * Then walk through the corners mapped to each fuse corner
>>>> + * and calculate the quotient adjustment for each one using the
>>>> + * following formula:
>>>> + *
>>>> + * quot_adjust = (freq_max - freq_corner) * scaling / 1000
>>>> + *
>>>> + * freq_max: max frequency in MHz supported by the fuse corner
>>>> + * freq_corner: frequency in MHz corresponding to the corner
>>>> + * scaling: calculated from above equation
>>>> + *
>>>> + *
>>>> + * + +
>>>> + * | v |
>>>> + * q | f c o | f c
>>>> + * u | c l | c
>>>> + * o | f t | f
>>>> + * t | c a | c
>>>> + * | c f g | c f
>>>> + * | e |
>>>> + * +--------------- +----------------
>>>> + * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
>>>> + * corner corner
>>>> + *
>>>> + * c = corner
>>>> + * f = fuse corner
>>>> + *
>>>> + */
>>>> + for (i = 0; corner <= end; corner++, i++) {
>>>> + unsigned long freq_diff_mhz;
>>>> + int ro_fac, vadj, prev_quot;
>>>> +
>>>> + fnum = cdata[i].fuse_corner;
>>>> + fdata = &tdesc->fuse_corner_data[fnum];
>>>> + quot_offset = fuses[fnum].quotient_offset;
>>>> + fuse = &thread->fuse_corners[fnum];
>>>> + ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
>>>> + if (fnum)
>>>> + prev_fuse = &thread->fuse_corners[fnum - 1];
>>>> + else
>>>> + prev_fuse = NULL;
>>>> +
>>>> + corner->fuse_corner = fuse;
>>>> + corner->freq = cdata[i].freq;
>>>> + corner->uV = fuse->uV;
>>>> +
>>>> + if (prev_fuse) {
>>>> + if (prev_fuse->ring_osc_idx == fuse->ring_osc_idx)
>>>> + quot_offset = NULL;
>>>> +
>>>> + scaling = cpr_calculate_scaling(drv->dev, quot_offset,
>>>> + fdata, corner);
>>>> + if (scaling < 0)
>>>> + return scaling;
>>>> +
>>>> + freq_diff_mhz = fuse->max_freq - corner->freq;
>>>> + do_div(freq_diff_mhz, 1000000); /* now in MHz */
>>>> +
>>>> + corner->quot_adjust = scaling * freq_diff_mhz;
>>>> + do_div(corner->quot_adjust, 1000);
>>>> +
>>>> + /* Fine-tune QUOT (closed-loop) based on fixed values */
>>>> + ro_fac = cpr_get_ro_factor(tdesc, fnum, fuse->ring_osc_idx);
>>>> + vadj = cdata[i].cloop_vadj;
>>>> + corner->quot_adjust -= cpr3_adjust_quot(ro_fac, vadj);
>>>> + dev_vdbg(drv->dev, "Quot fine-tuning to %d for post-vadj=%d\n",
>>>> + corner->quot_adjust, vadj);
>>>> +
>>>> + /*
>>>> + * Make sure that we scale (up) monotonically.
>>>> + * P.S.: Fuse quots can never be descending.
>>>> + */
>>>> + prev_quot = prev_corner->fuse_corner->quot;
>>>> + prev_quot -= prev_corner->quot_adjust;
>>>> + if (fuse->quot - corner->quot_adjust < prev_quot) {
>>>> + int new_adj = prev_corner->fuse_corner->quot;
>>>> +
>>>> + new_adj -= fuse->quot;
>>>> + dev_vdbg(drv->dev, "Monotonic increase forced: %d->%d\n",
>>>> + corner->quot_adjust, new_adj);
>>>> + corner->quot_adjust = new_adj;
>>>> + }
>>>> +
>>>> + corner->uV = cpr_interpolate(corner,
>>>> + drv->vreg_step, fdata);
>>>> + }
>>>> + /* Negative fuse quotients are nonsense. */
>>>> + if (fuse->quot < corner->quot_adjust)
>>>> + return -EINVAL;
>>>> +
>>>> + min_quotient = min(min_quotient,
>>>> + (u32)(fuse->quot - corner->quot_adjust));
>>>> +
>>>> + /* Fine-tune voltages (open-loop) based on fixed values */
>>>> + corner->uV += cdata[i].oloop_vadj;
>>>> + dev_dbg(drv->dev, "Voltage fine-tuning to %d for post-vadj=%d\n",
>>>> + corner->uV, cdata[i].oloop_vadj);
>>>> +
>>>> + corner->max_uV = fuse->max_uV;
>>>> + corner->min_uV = fuse->min_uV;
>>>> + corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV);
>>>> + dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d %d]\n",
>>>> + corner->min_uV, corner->uV, corner->max_uV);
>>>> +
>>>> + /* Make sure that we scale monotonically here, too. */
>>>> + if (corner->uV < prev_corner->uV)
>>>> + corner->uV = prev_corner->uV;
>>>> +
>>>> + corner->last_uV = corner->uV;
>>>> +
>>>> + /* Reduce the ceiling voltage if needed */
>>>> + if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV)
>>>> + corner->max_uV = corner->uV;
>>>> + else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV)
>>>> + corner->max_uV = max(corner->min_uV, fuse->uV);
>>>> +
>>>> + corner->min_uV = max(corner->max_uV - fdata->range_uV,
>>>> + corner->min_uV);
>>>> +
>>>> + /*
>>>> + * Adjust per-corner floor and ceiling voltages so that
>>>> + * they do not overlap the memory Array Power Mux (APM)
>>>> + * nor the Memory Accelerator (MEM-ACC) threshold voltages.
>>>> + */
>>>> + if (desc->apm_threshold)
>>>> + cpr3_restrict_corner(corner, desc->apm_threshold,
>>>> + desc->apm_hysteresis,
>>>> + drv->vreg_step);
>>>> + if (desc->mem_acc_threshold)
>>>> + cpr3_restrict_corner(corner, desc->mem_acc_threshold,
>>>> + 0, drv->vreg_step);
>>>> +
>>>> + prev_corner = corner;
>>>> + dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d quot %d\n", i,
>>>> + corner->min_uV, corner->uV, corner->max_uV, scaling,
>>>> + fuse->quot - corner->quot_adjust);
>>>> + }
>>>> +
>>>> + /* Additional setup for CPRh only */
>>>> + if (desc->cpr_type < CTRL_TYPE_CPRH)
>>>> + return 0;
>>>> +
>>>> + /* If the OPPs can't be adjusted, programming the CPRh is useless */
>>>> + ret = cprh_corner_adjust_opps(thread);
>>>> + if (ret) {
>>>> + dev_err(drv->dev, "Cannot adjust CPU OPP voltages: %d\n", ret);
>>>> + return ret;
>>>> + }
>>>> +
>>>> + total_corners = thread->num_corners;
>>>> + extra_corners = drv->extra_corners;
>>>> +
>>>> + /* If the APM extra corner exists, add it now. */
>>>> + if (desc->apm_crossover && desc->apm_threshold && extra_corners) {
>>>> + /* Program the APM crossover corner on the CPR-Hardened */
>>>> + thread->corners[total_corners].uV = desc->apm_crossover;
>>>> + thread->corners[total_corners].min_uV = desc->apm_crossover;
>>>> + thread->corners[total_corners].max_uV = desc->apm_crossover;
>>>> + thread->corners[total_corners].is_open_loop = true;
>>>> +
>>>> + /*
>>>> + * We have calculated the APM parameters for this clock plan:
>>>> + * make the APM *threshold* available to external callers.
>>>> + * The crossover is used only internally in the CPR.
>>>> + */
>>>> + thread->ext_data.apm_threshold_uV = desc->apm_threshold;
>>>> +
>>>> + dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] Open-Loop\n",
>>>> + total_corners, desc->apm_crossover,
>>>> + desc->apm_crossover, desc->apm_crossover);
>>>> +
>>>> + total_corners++;
>>>> + extra_corners--;
>>>> + }
>>>> +
>>>> + if (desc->mem_acc_threshold && extra_corners) {
>>>> + /* Program the Memory Accelerator threshold corner to CPRh */
>>>> + thread->corners[total_corners].uV = desc->mem_acc_threshold;
>>>> + thread->corners[total_corners].min_uV = desc->mem_acc_threshold;
>>>> + thread->corners[total_corners].max_uV = desc->mem_acc_threshold;
>>>> + thread->corners[total_corners].is_open_loop = true;
>>>> +
>>>> + /*
>>>> + * We have calculated a mem-acc threshold for this clock plan:
>>>> + * make it available to external callers.
>>>> + */
>>>> + thread->ext_data.mem_acc_threshold_uV = desc->mem_acc_threshold;
>>>> +
>>>> + dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] Open-Loop\n",
>>>> + total_corners, desc->mem_acc_threshold,
>>>> + desc->mem_acc_threshold, desc->mem_acc_threshold);
>>>> +
>>>> + total_corners++;
>>>> + extra_corners--;
>>>> + }
>>>> +
>>>> + /*
>>>> + * If there are any extra corners left, it means that even though we
>>>> + * expect to fill in both APM and MEM-ACC crossovers, one couldn't
>>>> + * satisfy requirements, which means that the specified parameters
>>>> + * are wrong: in this case, inform the user and bail out, otherwise
>>>> + * if we go on writing the (invalid) table to the CPR-Hardened, the
>>>> + * hardware (in this case, the CPU) will surely freeze and crash.
>>>> + */
>>>> + if (unlikely(extra_corners)) {
>>>> + dev_err(drv->dev, "APM/MEM-ACC corners: bad parameters.\n");
>>>> + return -EINVAL;
>>>> + }
>>>> + /* Reassign extra_corners, as we have to exclude delta_quot for them */
>>>> + extra_corners = drv->extra_corners;
>>>> +
>>>> + /* Disable the interface between OSM and CPRh */
>>>> + cpr_masked_write(thread, drv->reg_ctl,
>>>> + CPRH_CTL_OSM_ENABLED, 0);
>>>> +
>>>> + /* Program the GCNT before unmasking ring oscillator(s) */
>>>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>>>> + if (!(ring_osc_mask & BIT(i))) {
>>>> + cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
>>>> + dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, drv->gcnt);
>>>> + }
>>>> + }
>>>> +
>>>> + /*
>>>> + * Unmask the ring oscillator(s) that we're going to use: it seems
>>>> + * to be mandatory to do this *before* sending the rest of the
>>>> + * CPRhardened specific configuration.
>>>> + */
>>>> + dev_dbg(drv->dev, "Unmasking ring oscillators with mask 0x%x\n", ring_osc_mask);
>>>> + cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), ring_osc_mask);
>>>> +
>>>> + /* Setup minimum quotients for ring oscillators */
>>>> + for (i = 0; i < CPR3_RO_COUNT; i++) {
>>>> + u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, i);
>>>> + u32 tgt_quot_val = 0;
>>>> +
>>>> + if (!(ring_osc_mask & BIT(i)))
>>>> + tgt_quot_val = min_quotient;
>>>> +
>>>> + cpr_write(thread, tgt_quot_reg, tgt_quot_val);
>>>> + dev_vdbg(drv->dev, "Programmed min quotient %u for Ring Oscillator %d\n",
>>>> + tgt_quot_val, tgt_quot_reg);
>>>> + }
>>>> +
>>>> + for (i = 0; i < total_corners; i++) {
>>>> + int volt_oloop_steps, volt_floor_steps, delta_quot_steps;
>>>> + int ring_osc;
>>>> + u32 val;
>>>> +
>>>> + fnum = cdata[i].fuse_corner;
>>>> + fuse = &thread->fuse_corners[fnum];
>>>> +
>>>> + val = thread->corners[i].uV - desc->cpr_base_voltage;
>>>> + volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
>>>> +
>>>> + val = thread->corners[i].min_uV - desc->cpr_base_voltage;
>>>> + volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
>>>> +
>>>> + /*
>>>> + * If we are accessing corners that are not used as
>>>> + * an active DCVS set-point, then always select RO 0
>>>> + * and zero out the delta quotient.
>>>> + */
>>>> + if (i >= thread->num_corners) {
>>>> + ring_osc = 0;
>>>> + delta_quot_steps = 0;
>>>> + } else {
>>>> + ring_osc = fuse->ring_osc_idx;
>>>> + val = fuse->quot - thread->corners[i].quot_adjust;
>>>> + val -= min_quotient;
>>>> + delta_quot_steps = DIV_ROUND_UP(val,
>>>> + CPRH_DELTA_QUOT_STEP_FACTOR);
>>>> + }
>>>> +
>>>> + if (volt_oloop_steps > CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE ||
>>>> + volt_floor_steps > CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
>>>> + delta_quot_steps > CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
>>>> + dev_err(drv->dev, "Invalid cfg: oloop=%d, floor=%d, delta=%d\n",
>>>> + volt_oloop_steps, volt_floor_steps,
>>>> + delta_quot_steps);
>>>> + return -EINVAL;
>>>> + }
>>>> + /* Green light: Go, Go, Go! */
>>>> +
>>>> + /* Set number of open-loop steps */
>>>> + val = volt_oloop_steps << CPRH_CORNER_INIT_VOLTAGE_SHIFT;
>>>> + val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
>>>> +
>>>> + /* Set number of floor voltage steps */
>>>> + val |= (volt_floor_steps << CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
>>>> + CPRH_CORNER_FLOOR_VOLTAGE_MASK;
>>>> +
>>>> + /* Set number of target quotient delta steps */
>>>> + val |= (delta_quot_steps << CPRH_CORNER_QUOT_DELTA_SHIFT) &
>>>> + CPRH_CORNER_QUOT_DELTA_MASK;
>>>> +
>>>> + /* Select ring oscillator for this corner */
>>>> + val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
>>>> + CPRH_CORNER_RO_SEL_MASK;
>>>> +
>>>> + /* Open loop corner is usually APM/ACC crossover */
>>>> + if (thread->corners[i].is_open_loop) {
>>>> + dev_dbg(drv->dev, "Disabling Closed-Loop on corner %d\n", i);
>>>> + val |= CPRH_CORNER_CPR_CL_DISABLE;
>>>> + }
>>>> + cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, i), val);
>>>> +
>>>> + dev_dbg(drv->dev, "steps [%d]: open-loop %d, floor %d, delta_quot %d\n",
>>>> + i, volt_oloop_steps, volt_floor_steps,
>>>> + delta_quot_steps);
>>>> + }
>>>> +
>>>> + /* YAY! Setup is done! Enable the internal loop to start CPR. */
>>>> + cpr_masked_write(thread, CPR3_REG_CPR_CTL,
>>>> + CPR3_CPR_CTL_LOOP_EN_MASK,
>>>> + CPR3_CPR_CTL_LOOP_EN_MASK);
>>>> +
>>>> + /*
>>>> + * All the writes are going through before enabling internal
>>>> + * communication between the OSM and the CPRh controllers
>>>> + * because we are never using relaxed accessors, but should
>>>> + * we use them, it would be critical to issue a barrier here,
>>>> + * otherwise there is a high risk of hardware lockups due to
>>>> + * under-voltage for the selected CPU clock.
>>>> + *
>>>> + * Please note that the CPR-hardened gets set-up in Linux but
>>>> + * then gets actually used in firmware (and only by the OSM);
>>>> + * after handing it off we will have no more control on it.
>>>> + */
>>>> +
>>>> + /* Enable the interface between OSM and CPRh */
>>>> + cpr_masked_write(thread, drv->reg_ctl,
>>>> + CPRH_CTL_OSM_ENABLED,
>>>> + CPRH_CTL_OSM_ENABLED);
>>>> +
>>>> + /* On success, free cdata manually */
>>>> + devm_kfree(drv->dev, cdata);
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr3_init_parameters() - Initialize CPR global parameters
>>>> + * @drv: Main driver structure
>>>> + *
>>>> + * Initial "integrity" checks and setup for the thread-independent parameters.
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr3_init_parameters(struct cpr_drv *drv)
>>>> +{
>>>> + const struct cpr_desc *desc = drv->desc;
>>>> + struct clk *clk;
>>>> +
>>>> + clk = devm_clk_get(drv->dev, "ref");
>>>> + if (IS_ERR(clk))
>>>> + return PTR_ERR(clk);
>>>> +
>>>> + drv->ref_clk_khz = clk_get_rate(clk);
>>>> + do_div(drv->ref_clk_khz, 1000);
>>>> +
>>>> + /* On CPRh this clock is not always-on... */
>>>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + clk_prepare_enable(clk);
>>>> + else
>>>> + devm_clk_put(drv->dev, clk);
>>>> +
>>>> + if (desc->timer_cons_up > CPR3_THRESH_CONS_UP_MASK ||
>>>> + desc->timer_cons_down > CPR3_THRESH_CONS_DOWN_MASK ||
>>>> + desc->up_threshold > CPR3_THRESH_UP_THRESH_MASK ||
>>>> + desc->down_threshold > CPR3_THRESH_DOWN_THRESH_MASK ||
>>>> + desc->idle_clocks > CPR3_CPR_CTL_IDLE_CLOCKS_MASK ||
>>>> + desc->count_mode > CPR3_CPR_CTL_COUNT_MODE_MASK ||
>>>> + desc->count_repeat > CPR3_CPR_CTL_COUNT_REPEAT_MASK)
>>>> + return -EINVAL;
>>>> +
>>>> + /*
>>>> + * Read the CPR version register only from CPR3 onwards:
>>>> + * this is needed to get the additional register offsets.
>>>> + *
>>>> + * Note: When threaded, even if multi-controller, there
>>>> + * is no chance to have different versions at the
>>>> + * same time in the same domain, so it is safe to
>>>> + * check this only on the first controller/thread.
>>>> + */
>>>> + drv->cpr_hw_rev = cpr_read(&drv->threads[0],
>>>> + CPR3_REG_CPR_VERSION);
>>>> + dev_dbg(drv->dev, "CPR hardware revision: 0x%x\n", drv->cpr_hw_rev);
>>>> +
>>>> + if (drv->cpr_hw_rev >= CPRH_CPR_VERSION_4P5) {
>>>> + drv->reg_corner = 0x3500;
>>>> + drv->reg_corner_tid = 0xa0;
>>>> + drv->reg_ctl = 0x3a80;
>>>> + drv->reg_status = 0x3a84;
>>>> + } else {
>>>> + drv->reg_corner = 0x3a00;
>>>> + drv->reg_corner_tid = 0;
>>>> + drv->reg_ctl = 0x3aa0;
>>>> + drv->reg_status = 0x3aa4;
>>>> + }
>>>> +
>>>> + dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n",
>>>> + desc->up_threshold, desc->down_threshold);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr3_find_initial_corner() - Finds boot-up p-state and enables CPR
>>>> + * @thread: Structure holding CPR thread-specific parameters
>>>> + *
>>>> + * Differently from CPRv1, from CPRv3 onwards when we successfully find
>>>> + * the target boot-up performance state, we must refresh the HW
>>>> + * immediately to guarantee system stability and to avoid overheating
>>>> + * during the boot process, thing that would more likely happen without
>>>> + * this driver doing its job.
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr3_find_initial_corner(struct cpr_thread *thread)
>>>> +{
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + struct corner *corner;
>>>> + int uV, idx;
>>>> +
>>>> + idx = cpr_find_initial_corner(drv->dev, thread->cpu_clk,
>>>> + thread->corners,
>>>> + thread->num_corners);
>>>> + if (idx < 0)
>>>> + return idx;
>>>> +
>>>> + cpr_ctl_disable(thread);
>>>> +
>>>> + corner = &thread->corners[idx];
>>>> + cpr_corner_restore(thread, corner);
>>>> +
>>>> + uV = regulator_get_voltage(drv->vreg);
>>>> + uV = clamp(uV, corner->min_uV, corner->max_uV);
>>>> +
>>>> + corner->last_uV = uV;
>>>> + if (!drv->last_uV)
>>>> + drv->last_uV = uV;
>>>> +
>>>> + cpr_commit_state(thread);
>>>> + thread->enabled = true;
>>>> + cpr_switch(drv);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static const int msm8998_gold_scaling_factor[][CPR3_RO_COUNT] = {
>>>> + /* Fuse Corner 0 */
>>>> + {
>>>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>>>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>>>> + },
>>>> + /* Fuse Corner 1 */
>>>> + {
>>>> + 2857, 3057, 2828, 2952, 2699, 2798, 2446, 2631,
>>>> + 2629, 2578, 2244, 3344, 3289, 3137, 3164, 2655
>>>> + },
>>>> + /* Fuse Corner 2 */
>>>> + {
>>>> + 2603, 2755, 2676, 2777, 2573, 2685, 2465, 2610,
>>>> + 2312, 2423, 2243, 3104, 3022, 3036, 2740, 2303
>>>> + },
>>>> + /* Fuse Corner 3 */
>>>> + {
>>>> + 1901, 2016, 2096, 2228, 2034, 2161, 2077, 2188,
>>>> + 1565, 1870, 1925, 2235, 2205, 2413, 1762, 1478
>>>> + }
>>>> +};
>>>> +
>>>> +static const int msm8998_silver_scaling_factor[][CPR3_RO_COUNT] = {
>>>> + /* Fuse Corner 0 */
>>>> + {
>>>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>>>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>>>> + },
>>>> + /* Fuse Corner 1 */
>>>> + {
>>>> + 2595, 2794, 2577, 2762, 2471, 2674, 2199, 2553,
>>>> + 3189, 3255, 3192, 2962, 3054, 2982, 2042, 2945
>>>> + },
>>>> + /* Fuse Corner 2 */
>>>> + {
>>>> + 2391, 2550, 2483, 2638, 2382, 2564, 2259, 2555,
>>>> + 2766, 3041, 2988, 2935, 2873, 2688, 2013, 2784
>>>> + },
>>>> + /* Fuse Corner 3 */
>>>> + {
>>>> + 2066, 2153, 2300, 2434, 2220, 2386, 2288, 2465,
>>>> + 2028, 2511, 2487, 2734, 2554, 2117, 1892, 2377
>>>> + }
>>>> +};
>>>> +
>>>> +static const struct cpr_thread_desc msm8998_thread_gold = {
>>>> + .controller_id = 1,
>>>> + .hw_tid = 0,
>>>> + .ro_scaling_factor = msm8998_gold_scaling_factor,
>>>> + .ro_avail_corners = ARRAY_SIZE(msm8998_gold_scaling_factor),
>>>> + .sensor_range_start = 0,
>>>> + .sensor_range_end = 9,
>>>> + .init_voltage_step = 10000,
>>>> + .init_voltage_width = 6,
>>>> + .step_quot_init_min = 9,
>>>> + .step_quot_init_max = 14,
>>>> + .num_fuse_corners = 4,
>>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>>> + /* fuse corner 0 */
>>>> + {
>>>> + .ref_uV = 756000,
>>>> + .max_uV = 828000,
>>>> + .min_uV = 568000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 0,
>>>> + .volt_oloop_adjust = 8000,
>>>> + .max_volt_scale = 4,
>>>> + .max_quot_scale = 10,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 1 */
>>>> + {
>>>> + .ref_uV = 756000,
>>>> + .max_uV = 900000,
>>>> + .min_uV = 624000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 0,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 320,
>>>> + .max_quot_scale = 350,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 2 */
>>>> + {
>>>> + .ref_uV = 828000,
>>>> + .max_uV = 952000,
>>>> + .min_uV = 632000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 12000,
>>>> + .volt_oloop_adjust = 12000,
>>>> + .max_volt_scale = 620,
>>>> + .max_quot_scale = 750,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 3 */
>>>> + {
>>>> + .ref_uV = 1056000,
>>>> + .max_uV = 1136000,
>>>> + .min_uV = 772000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = 50000,
>>>> + .volt_oloop_adjust = 52000,
>>>> + .max_volt_scale = 580,
>>>> + .max_quot_scale = 1040,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_thread_desc msm8998_thread_silver = {
>>>> + .controller_id = 0,
>>>> + .hw_tid = 0,
>>>> + .ro_scaling_factor = msm8998_silver_scaling_factor,
>>>> + .ro_avail_corners = ARRAY_SIZE(msm8998_silver_scaling_factor),
>>>> + .sensor_range_start = 0,
>>>> + .sensor_range_end = 6,
>>>> + .init_voltage_step = 10000,
>>>> + .init_voltage_width = 6,
>>>> + .step_quot_init_min = 11,
>>>> + .step_quot_init_max = 12,
>>>> + .num_fuse_corners = 4,
>>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>>> + /* fuse corner 0 */
>>>> + {
>>>> + .ref_uV = 688000,
>>>> + .max_uV = 828000,
>>>> + .min_uV = 568000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 20000,
>>>> + .volt_oloop_adjust = 40000,
>>>> + .max_volt_scale = 4,
>>>> + .max_quot_scale = 10,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 1 */
>>>> + {
>>>> + .ref_uV = 756000,
>>>> + .max_uV = 900000,
>>>> + .min_uV = 632000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 26000,
>>>> + .volt_oloop_adjust = 24000,
>>>> + .max_volt_scale = 500,
>>>> + .max_quot_scale = 800,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 2 */
>>>> + {
>>>> + .ref_uV = 828000,
>>>> + .max_uV = 952000,
>>>> + .min_uV = 664000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = 12000,
>>>> + .volt_oloop_adjust = 12000,
>>>> + .max_volt_scale = 280,
>>>> + .max_quot_scale = 650,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> +
>>>> + },
>>>> + /* fuse corner 3 */
>>>> + {
>>>> + .ref_uV = 1056000,
>>>> + .max_uV = 1056000,
>>>> + .min_uV = 772000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = 30000,
>>>> + .volt_oloop_adjust = 30000,
>>>> + .max_volt_scale = 430,
>>>> + .max_quot_scale = 800,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_desc msm8998_cpr_desc = {
>>>> + .cpr_type = CTRL_TYPE_CPRH,
>>>> + .num_threads = 2,
>>>> + .mem_acc_threshold = 852000,
>>>> + .apm_threshold = 800000,
>>>> + .apm_crossover = 880000,
>>>> + .apm_hysteresis = 0,
>>>> + .cpr_base_voltage = 352000,
>>>> + .cpr_max_voltage = 1200000,
>>>> + .timer_delay_us = 5000,
>>>> + .timer_cons_up = 0,
>>>> + .timer_cons_down = 2,
>>>> + .up_threshold = 2,
>>>> + .down_threshold = 2,
>>>> + .idle_clocks = 15,
>>>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>>>> + .count_repeat = 14,
>>>> + .gcnt_us = 1,
>>>> + .vreg_step_fixed = 4000,
>>>> + .vreg_step_up_limit = 1,
>>>> + .vreg_step_down_limit = 1,
>>>> + .vdd_settle_time_us = 34,
>>>> + .corner_settle_time_us = 6,
>>>> + .reduce_to_corner_uV = true,
>>>> + .hw_closed_loop_en = true,
>>>> + .threads = (const struct cpr_thread_desc *[]) {
>>>> + &msm8998_thread_silver,
>>>> + &msm8998_thread_gold,
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_acc_desc msm8998_cpr_acc_desc = {
>>>> + .cpr_desc = &msm8998_cpr_desc,
>>>> +};
>>>> +
>>>> +static const int sdm630_gold_scaling_factor[][CPR3_RO_COUNT] = {
>>>> + /* Same RO factors for all fuse corners */
>>>> + {
>>>> + 4040, 3230, 0, 2210, 2560, 2450, 2230, 2220,
>>>> + 2410, 2300, 2560, 2470, 1600, 3120, 2620, 2280
>>>> + }
>>>> +};
>>>> +
>>>> +static const int sdm630_silver_scaling_factor[][CPR3_RO_COUNT] = {
>>>> + /* Same RO factors for all fuse corners */
>>>> + {
>>>> + 3600, 3600, 3830, 2430, 2520, 2700, 1790, 1760,
>>>> + 1970, 1880, 2110, 2010, 2510, 4900, 4370, 4780,
>>>> + }
>>>> +};
>>>> +
>>>> +static const struct cpr_thread_desc sdm630_thread_gold = {
>>>> + .controller_id = 0,
>>>> + .hw_tid = 0,
>>>> + .ro_scaling_factor = sdm630_gold_scaling_factor,
>>>> + .ro_avail_corners = ARRAY_SIZE(sdm630_gold_scaling_factor),
>>>> + .sensor_range_start = 0,
>>>> + .sensor_range_end = 6,
>>>> + .init_voltage_step = 10000,
>>>> + .init_voltage_width = 6,
>>>> + .step_quot_init_min = 12,
>>>> + .step_quot_init_max = 14,
>>>> + .num_fuse_corners = 5,
>>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>>> + /* fuse corner 0 */
>>>> + {
>>>> + .ref_uV = 644000,
>>>> + .max_uV = 724000,
>>>> + .min_uV = 588000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 15000,
>>>> + .max_volt_scale = 10,
>>>> + .max_quot_scale = 300,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 1 */
>>>> + {
>>>> + .ref_uV = 788000,
>>>> + .max_uV = 788000,
>>>> + .min_uV = 652000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 5000,
>>>> + .max_volt_scale = 320,
>>>> + .max_quot_scale = 275,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 2 */
>>>> + {
>>>> + .ref_uV = 868000,
>>>> + .max_uV = 868000,
>>>> + .min_uV = 712000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 5000,
>>>> + .max_volt_scale = 350,
>>>> + .max_quot_scale = 800,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 3 */
>>>> + {
>>>> + .ref_uV = 988000,
>>>> + .max_uV = 988000,
>>>> + .min_uV = 784000,
>>>> + .range_uV = 66000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 868,
>>>> + .max_quot_scale = 980,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 4 */
>>>> + {
>>>> + .ref_uV = 1068000,
>>>> + .max_uV = 1068000,
>>>> + .min_uV = 844000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 868,
>>>> + .max_quot_scale = 980,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_thread_desc sdm630_thread_silver = {
>>>> + .controller_id = 1,
>>>> + .hw_tid = 0,
>>>> + .ro_scaling_factor = sdm630_silver_scaling_factor,
>>>> + .ro_avail_corners = ARRAY_SIZE(sdm630_silver_scaling_factor),
>>>> + .sensor_range_start = 0,
>>>> + .sensor_range_end = 6,
>>>> + .init_voltage_step = 10000,
>>>> + .init_voltage_width = 6,
>>>> + .step_quot_init_min = 12,
>>>> + .step_quot_init_max = 14,
>>>> + .num_fuse_corners = 3,
>>>> + .fuse_corner_data = (struct fuse_corner_data[]){
>>>> + /* fuse corner 0 */
>>>> + {
>>>> + .ref_uV = 644000,
>>>> + .max_uV = 724000,
>>>> + .min_uV = 588000,
>>>> + .range_uV = 32000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 10,
>>>> + .max_quot_scale = 360,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 1 */
>>>> + {
>>>> + .ref_uV = 788000,
>>>> + .max_uV = 788000,
>>>> + .min_uV = 652000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 500,
>>>> + .max_quot_scale = 550,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + /* fuse corner 2 */
>>>> + {
>>>> + .ref_uV = 1068000,
>>>> + .max_uV = 1068000,
>>>> + .min_uV = 800000,
>>>> + .range_uV = 40000,
>>>> + .volt_cloop_adjust = -30000,
>>>> + .volt_oloop_adjust = 0,
>>>> + .max_volt_scale = 2370,
>>>> + .max_quot_scale = 550,
>>>> + .quot_offset = 0,
>>>> + .quot_scale = 1,
>>>> + .quot_adjust = 0,
>>>> + .quot_offset_scale = 5,
>>>> + .quot_offset_adjust = 0,
>>>> + },
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_desc sdm630_cpr_desc = {
>>>> + .cpr_type = CTRL_TYPE_CPRH,
>>>> + .num_threads = 2,
>>>> + .apm_threshold = 872000,
>>>> + .apm_crossover = 872000,
>>>> + .apm_hysteresis = 20000,
>>>> + .cpr_base_voltage = 400000,
>>>> + .cpr_max_voltage = 1300000,
>>>> + .timer_delay_us = 5000,
>>>> + .timer_cons_up = 0,
>>>> + .timer_cons_down = 2,
>>>> + .up_threshold = 2,
>>>> + .down_threshold = 2,
>>>> + .idle_clocks = 15,
>>>> + .count_mode = CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN,
>>>> + .count_repeat = 14,
>>>> + .gcnt_us = 1,
>>>> + .vreg_step_fixed = 4000,
>>>> + .vreg_step_up_limit = 1,
>>>> + .vreg_step_down_limit = 1,
>>>> + .vdd_settle_time_us = 34,
>>>> + .corner_settle_time_us = 5,
>>>> + .reduce_to_corner_uV = true,
>>>> + .hw_closed_loop_en = true,
>>>> + .threads = (const struct cpr_thread_desc *[]) {
>>>> + &sdm630_thread_gold,
>>>> + &sdm630_thread_silver,
>>>> + },
>>>> +};
>>>> +
>>>> +static const struct cpr_acc_desc sdm630_cpr_acc_desc = {
>>>> + .cpr_desc = &sdm630_cpr_desc,
>>>> +};
>>>> +
>>>> +static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
>>>> + struct dev_pm_opp *opp)
>>>> +{
>>>> + return dev_pm_opp_get_level(opp);
>>>> +}
>>>> +
>>>> +static int cpr_power_off(struct generic_pm_domain *domain)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>>> +
>>>> + return cpr_disable(thread);
>>>> +}
>>>> +
>>>> +static int cpr_power_on(struct generic_pm_domain *domain)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>>> +
>>>> + return cpr_enable(thread);
>>>> +}
>>>> +
>>>> +static void cpr_pd_detach_dev(struct generic_pm_domain *domain,
>>>> + struct device *dev)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>>> + struct cpr_drv *drv = thread->drv;
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + dev_dbg(drv->dev, "detach callback for: %s\n", dev_name(dev));
>>>> + thread->attached_cpu_dev = NULL;
>>>> +
>>>> + mutex_unlock(&drv->lock);
>>>> +}
>>>> +
>>>> +static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
>>>> + struct device *dev)
>>>> +{
>>>> + struct cpr_thread *thread = container_of(domain, struct cpr_thread, pd);
>>>> + struct cpr_drv *drv = thread->drv;
>>>> + const struct acc_desc *acc_desc = drv->acc_desc;
>>>> + bool cprh_opp_remove_table = false;
>>>> + int ret = 0;
>>>> +
>>>> + mutex_lock(&drv->lock);
>>>> +
>>>> + dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev));
>>>> +
>>>> + /*
>>>> + * This driver only supports scaling voltage for a CPU cluster
>>>> + * where all CPUs in the cluster share a single regulator.
>>>> + * Therefore, save the struct device pointer only for the first
>>>> + * CPU device that gets attached. There is no need to do any
>>>> + * additional initialization when further CPUs get attached.
>>>> + * This is not an error condition.
>>>> + */
>>>> + if (thread->attached_cpu_dev)
>>>> + goto unlock;
>>>> +
>>>> + /*
>>>> + * cpr_scale_voltage() requires the direction (if we are changing
>>>> + * to a higher or lower OPP). The first time
>>>> + * cpr_set_performance_state() is called, there is no previous
>>>> + * performance state defined. Therefore, we call
>>>> + * cpr_find_initial_corner() that gets the CPU clock frequency
>>>> + * set by the bootloader, so that we can determine the direction
>>>> + * the first time cpr_set_performance_state() is called.
>>>> + */
>>>> + thread->cpu_clk = devm_clk_get(dev, NULL);
>>>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH && IS_ERR(thread->cpu_clk)) {
>>>> + ret = PTR_ERR(thread->cpu_clk);
>>>> + if (ret != -EPROBE_DEFER)
>>>> + dev_err(drv->dev, "could not get cpu clk: %d\n", ret);
>>>> + goto unlock;
>>>> + }
>>>> + thread->attached_cpu_dev = dev;
>>>> +
>>>> + /*
>>>> + * We are exporting the APM and MEM-ACC thresholds to the caller;
>>>> + * while APM is necessary in the CPU CPR case, MEM-ACC may not be,
>>>> + * depending on the SoC and on fuses.
>>>> + * Initialize both to an invalid value, so that the caller can check
>>>> + * if they got calculated or read from fuses in this driver.
>>>> + */
>>>> + thread->ext_data.apm_threshold_uV = -1;
>>>> + thread->ext_data.mem_acc_threshold_uV = -1;
>>>> + dev_set_drvdata(thread->attached_cpu_dev, &thread->ext_data);
>>>> +
>>>> + dev_dbg(drv->dev, "using cpu clk from: %s\n",
>>>> + dev_name(thread->attached_cpu_dev));
>>>> +
>>>> + /*
>>>> + * Everything related to (virtual) corners has to be initialized
>>>> + * here, when attaching to the power domain, since we need to know
>>>> + * the maximum frequency for each fuse corner, and this is only
>>>> + * available after the cpufreq driver has attached to us.
>>>> + * The reason for this is that we need to know the highest
>>>> + * frequency associated with each fuse corner.
>>>> + */
>>>> + ret = dev_pm_opp_get_opp_count(&thread->pd.dev);
>>>> + if (ret < 0) {
>>>> + dev_err(drv->dev, "could not get OPP count\n");
>>>> + thread->attached_cpu_dev = NULL;
>>>> + goto unlock;
>>>> + }
>>>> + thread->num_corners = ret;
>>>> +
>>>> + thread->corners = devm_kcalloc(drv->dev,
>>>> + thread->num_corners +
>>>> + drv->extra_corners,
>>>> + sizeof(*thread->corners),
>>>> + GFP_KERNEL);
>>>> + if (!thread->corners) {
>>>> + ret = -ENOMEM;
>>>> + goto unlock;
>>>> + }
>>>> +
>>>> + /*
>>>> + * If we are on CPR-Hardened we have to make sure that the attached
>>>> + * device has a OPP table installed, as we're going to modify it here
>>>> + * with our calculations based on qfprom values.
>>>> + */
>>>> + if (drv->desc->cpr_type == CTRL_TYPE_CPRH) {
>>>> + ret = dev_pm_opp_of_add_table(dev);
>>>> + if (ret && ret != -EEXIST) {
>>>> + dev_err(drv->dev, "Cannot add table: %d\n", ret);
>>>> + goto unlock;
>>>> + }
>>>> + cprh_opp_remove_table = true;
>>>> + }
>>>> +
>>>> + ret = cpr3_corner_init(thread);
>>>> + if (ret)
>>>> + goto exit;
>>>> +
>>>> + if (drv->desc->cpr_type < CTRL_TYPE_CPRH) {
>>>> + ret = cpr3_find_initial_corner(thread);
>>>> + if (ret)
>>>> + goto exit;
>>>> +
>>>> + if (acc_desc->config)
>>>> + regmap_multi_reg_write(drv->tcsr, acc_desc->config,
>>>> + acc_desc->num_regs_per_fuse);
>>>> +
>>>> + /* Enable ACC if required */
>>>> + if (acc_desc->enable_mask)
>>>> + regmap_update_bits(drv->tcsr, acc_desc->enable_reg,
>>>> + acc_desc->enable_mask,
>>>> + acc_desc->enable_mask);
>>>> + }
>>>> + dev_info(drv->dev, "thread %d initialized with %u OPPs\n",
>>>> + thread->id, thread->num_corners);
>>>> +exit:
>>>> + /*
>>>> + * If we are on CPRh and we reached an error condition, we installed
>>>> + * the OPP table but we haven't done any setup on it, nor we ever will.
>>>> + * In order to leave a clean state, remove the table.
>>>> + */
>>>> + if (ret && cprh_opp_remove_table)
>>>> + dev_pm_opp_of_remove_table(thread->attached_cpu_dev);
>>>> +unlock:
>>>> + mutex_unlock(&drv->lock);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +static int cpr3_debug_info_show(struct seq_file *s, void *unused)
>>>> +{
>>>> + u32 ro_sel, ctl, irq_status, reg, quot;
>>>> + struct cpr_thread *thread = s->private;
>>>> + struct corner *corner = thread->corners;
>>>> + struct fuse_corner *fuse = thread->fuse_corners;
>>>> + unsigned int i;
>>>> +
>>>> + const struct {
>>>> + const char *name;
>>>> + uint32_t mask;
>>>> + uint8_t shift;
>>>> + } result0_fields[] = {
>>>> + { "busy", 1, 0 },
>>>> + { "step_dn", 1, 1 },
>>>> + { "step_up", 1, 2 },
>>>> + { "error_steps", CPR3_RESULT0_ERROR_STEPS_MASK,
>>>> + CPR3_RESULT0_ERROR_STEPS_SHIFT },
>>>> + { "error", CPR3_RESULT0_ERROR_MASK, CPR3_RESULT0_ERROR_SHIFT },
>>>> + { "negative", 1, 20 },
>>>> + }, result1_fields[] = {
>>>> + { "quot_min", CPR3_RESULT1_QUOT_MIN_MASK,
>>>> + CPR3_RESULT1_QUOT_MIN_SHIFT },
>>>> + { "quot_max", CPR3_RESULT1_QUOT_MAX_MASK,
>>>> + CPR3_RESULT1_QUOT_MAX_SHIFT },
>>>> + { "ro_min", CPR3_RESULT1_RO_MIN_MASK,
>>>> + CPR3_RESULT1_RO_MIN_SHIFT },
>>>> + { "ro_max", CPR3_RESULT1_RO_MAX_MASK,
>>>> + CPR3_RESULT1_RO_MAX_SHIFT },
>>>> + }, result2_fields[] = {
>>>> + { "qout_step_min", CPR3_RESULT2_STEP_QUOT_MIN_MASK,
>>>> + CPR3_RESULT2_STEP_QUOT_MIN_SHIFT },
>>>> + { "qout_step_max", CPR3_RESULT2_STEP_QUOT_MAX_MASK,
>>>> + CPR3_RESULT2_STEP_QUOT_MAX_SHIFT },
>>>> + { "sensor_min", CPR3_RESULT2_SENSOR_MIN_MASK,
>>>> + CPR3_RESULT2_SENSOR_MIN_SHIFT },
>>>> + { "sensor_max", CPR3_RESULT2_SENSOR_MAX_MASK,
>>>> + CPR3_RESULT2_SENSOR_MAX_SHIFT },
>>>> + };
>>>> +
>>>> + if (thread->drv->desc->cpr_type < CTRL_TYPE_CPRH)
>>>> + seq_printf(s, "current_volt = %d uV\n", thread->drv->last_uV);
>>>> +
>>>> + irq_status = cpr_read(thread, CPR3_REG_IRQ_STATUS);
>>>> + seq_printf(s, "irq_status = %#02X\n", irq_status);
>>>> +
>>>> + ctl = cpr_read(thread, CPR3_REG_CPR_CTL);
>>>> + seq_printf(s, "cpr_ctl = %#02X\n", ctl);
>>>> +
>>>> + seq_printf(s, "thread %d - hw tid: %u - enabled: %d:\n",
>>>> + thread->id, thread->desc->hw_tid, thread->enabled);
>>>> + seq_printf(s, "%d corners, derived from %d fuse corners\n",
>>>> + thread->num_corners, thread->desc->num_fuse_corners);
>>>> +
>>>> + for (i = 0; i < thread->num_corners; i++, corner++)
>>>> + seq_printf(s, "corner %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>>>> + i, corner->min_uV, corner->uV, corner->max_uV,
>>>> + corner->quot_adjust, corner->freq);
>>>> +
>>>> + for (i = 0; i < thread->desc->num_fuse_corners; i++, fuse++)
>>>> + seq_printf(s, "fuse %d - uV=[%d %d %d] quot=%d freq=%lu\n",
>>>> + i, fuse->min_uV, fuse->uV, fuse->max_uV,
>>>> + fuse->quot, corner->freq);
>>>> +
>>>> + seq_printf(s, "requested voltage: %d uV\n", thread->corner->last_uV);
>>>> +
>>>> + ro_sel = corner->fuse_corner->ring_osc_idx;
>>>> + quot = cpr_read(thread, CPR3_REG_TARGET_QUOT(i, ro_sel));
>>>> + seq_printf(s, "quot_target (%u) = %#02X\n", ro_sel, quot);
>>>> +
>>>> + reg = cpr_read(thread, CPR3_REG_RESULT0(i));
>>>> + seq_printf(s, "cpr_result_0 = %#02X\n [", reg);
>>>> + for (i = 0; i < ARRAY_SIZE(result0_fields); i++)
>>>> + seq_printf(s, "%s%s = %u",
>>>> + i ? ", " : "",
>>>> + result0_fields[i].name,
>>>> + (reg >> result0_fields[i].shift) &
>>>> + result0_fields[i].mask);
>>>> + seq_puts(s, "]\n");
>>>> + reg = cpr_read(thread, CPR3_REG_RESULT1(i));
>>>> + seq_printf(s, "cpr_result_1 = %#02X\n [", reg);
>>>> + for (i = 0; i < ARRAY_SIZE(result1_fields); i++)
>>>> + seq_printf(s, "%s%s = %u",
>>>> + i ? ", " : "",
>>>> + result1_fields[i].name,
>>>> + (reg >> result1_fields[i].shift) &
>>>> + result1_fields[i].mask);
>>>> + seq_puts(s, "]\n");
>>>> + reg = cpr_read(thread, CPR3_REG_RESULT2(i));
>>>> + seq_printf(s, "cpr_result_2 = %#02X\n [", reg);
>>>> + for (i = 0; i < ARRAY_SIZE(result2_fields); i++)
>>>> + seq_printf(s, "%s%s = %u",
>>>> + i ? ", " : "",
>>>> + result2_fields[i].name,
>>>> + (reg >> result2_fields[i].shift) &
>>>> + result2_fields[i].mask);
>>>> + seq_puts(s, "]\n");
>>>> +
>>>> + return 0;
>>>> +}
>>>> +DEFINE_SHOW_ATTRIBUTE(cpr3_debug_info);
>>>> +
>>>> +static void cpr3_debugfs_init(struct cpr_drv *drv)
>>>> +{
>>>> + int i;
>>>> +
>>>> + drv->debugfs = debugfs_create_dir("qcom_cpr3", NULL);
>>>> +
>>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>>> + char buf[50];
>>>> +
>>>> + snprintf(buf, sizeof(buf), "thread%d", i);
>>>> +
>>>> + debugfs_create_file(buf, 0444, drv->debugfs, &drv->threads[i],
>>>> + &cpr3_debug_info_fops);
>>>> + }
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr_thread_init() - Initialize CPR thread related parameters
>>>> + * @drv: Main driver structure
>>>> + * @tid: Thread ID
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr_thread_init(struct cpr_drv *drv, int tid)
>>>> +{
>>>> + const struct cpr_desc *desc = drv->desc;
>>>> + const struct cpr_thread_desc *tdesc = desc->threads[tid];
>>>> + struct cpr_thread *thread = &drv->threads[tid];
>>>> + int ret;
>>>> +
>>>> + if (tdesc->step_quot_init_min > CPR3_CPR_STEP_QUOT_MIN_MASK ||
>>>> + tdesc->step_quot_init_max > CPR3_CPR_STEP_QUOT_MAX_MASK)
>>>> + return -EINVAL;
>>>> +
>>>> + thread->id = tid;
>>>> + thread->drv = drv;
>>>> + thread->desc = tdesc;
>>>> + thread->fuse_corners = devm_kcalloc(drv->dev,
>>>> + tdesc->num_fuse_corners +
>>>> + drv->extra_corners,
>>>> + sizeof(*thread->fuse_corners),
>>>> + GFP_KERNEL);
>>>> + if (!thread->fuse_corners)
>>>> + return -ENOMEM;
>>>> +
>>>> + thread->cpr_fuses = cpr_get_fuses(drv->dev, tid,
>>>> + tdesc->num_fuse_corners);
>>>> + if (IS_ERR(thread->cpr_fuses))
>>>> + return PTR_ERR(thread->cpr_fuses);
>>>> +
>>>> + ret = cpr_populate_ring_osc_idx(thread->drv->dev, thread->fuse_corners,
>>>> + thread->cpr_fuses,
>>>> + tdesc->num_fuse_corners);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + ret = cpr_fuse_corner_init(thread);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + thread->pd.name = devm_kasprintf(drv->dev, GFP_KERNEL,
>>>> + "%s_thread%d",
>>>> + drv->dev->of_node->full_name,
>>>> + thread->id);
>>>> + if (!thread->pd.name)
>>>> + return -EINVAL;
>>>> +
>>>> + thread->pd.power_off = cpr_power_off;
>>>> + thread->pd.power_on = cpr_power_on;
>>>> + thread->pd.opp_to_performance_state = cpr_get_performance_state;
>>>> + thread->pd.attach_dev = cpr_pd_attach_dev;
>>>> + thread->pd.detach_dev = cpr_pd_detach_dev;
>>>> +
>>>> + /* CPR-Hardened performance states are managed in firmware */
>>>> + if (desc->cpr_type == CTRL_TYPE_CPRH)
>>>> + thread->pd.set_performance_state = cprh_dummy_set_performance_state;
>>>> + else
>>>> + thread->pd.set_performance_state = cpr_set_performance_state;
>>>> +
>>>> + /* Anything later than CPR1 must be always-on for now */
>>>> + thread->pd.flags = GENPD_FLAG_ALWAYS_ON;
>>>> +
>>>> + drv->cell_data.domains[tid] = &thread->pd;
>>>> +
>>>> + ret = pm_genpd_init(&thread->pd, NULL, false);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + /* On CPRhardened, the interrupts are managed in firmware */
>>>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>>>> + INIT_WORK(&thread->restart_work, cpr_restart_worker);
>>>> +
>>>> + ret = devm_request_threaded_irq(drv->dev, drv->irq,
>>>> + NULL, cpr_irq_handler,
>>>> + IRQF_ONESHOT |
>>>> + IRQF_TRIGGER_RISING,
>>>> + "cpr", drv);
>>>> + if (ret)
>>>> + return ret;
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * cpr3_resources_init() - Initialize resources used by this driver
>>>> + * @pdev: Platform device
>>>> + * @drv: Main driver structure
>>>> + *
>>>> + * Return: Zero for success, negative number on error
>>>> + */
>>>> +static int cpr3_resources_init(struct platform_device *pdev,
>>>> + struct cpr_drv *drv)
>>>> +{
>>>> + const struct cpr_desc *desc = drv->desc;
>>>> + struct cpr_thread *threads = drv->threads;
>>>> + unsigned int i;
>>>> + u8 cid_mask = 0;
>>>> +
>>>> + /*
>>>> + * Here, we are accounting for the following usecases:
>>>> + * - One controller
>>>> + * - One or multiple threads on the same iospace
>>>> + *
>>>> + * - Multiple controllers
>>>> + * - Each controller has its own iospace and each
>>>> + * may have one or multiple threads in their
>>>> + * parent controller's iospace
>>>> + *
>>>> + * Then, to avoid complicating the code for no reason,
>>>> + * this also needs a mandatory order in the list of
>>>> + * threads which implies that all of them from the same
>>>> + * controllers are specified sequentially. As an example:
>>>> + *
>>>> + * C0-T0, C0-T1...C0-Tn, C1-T0, C1-T1...C1-Tn
>>>> + */
>>>> + for (i = 0; i < desc->num_threads; i++) {
>>>> + u8 cid = desc->threads[i]->controller_id;
>>>> +
>>>> + if (cid_mask & BIT(cid)) {
>>>> + if (desc->threads[i - 1]->controller_id != cid) {
>>>> + dev_err(drv->dev, "Bad threads order. Please fix!\n");
>>>> + return -EINVAL;
>>>> + }
>>>> + threads[i].base = threads[i - 1].base;
>>>> + continue;
>>>> + }
>>>> + threads[i].base = devm_platform_ioremap_resource(pdev, cid);
>>>> + if (IS_ERR(threads[i].base))
>>>> + return PTR_ERR(threads[i].base);
>>>> + cid_mask |= BIT(cid);
>>>> + }
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int cpr_probe(struct platform_device *pdev)
>>>> +{
>>>> + struct device *dev = &pdev->dev;
>>>> + struct cpr_drv *drv;
>>>> + const struct cpr_desc *desc;
>>>> + const struct cpr_acc_desc *data;
>>>> + struct device_node *np;
>>>> + unsigned int i;
>>>> + int ret;
>>>> +
>>>> + data = of_device_get_match_data(dev);
>>>> + if (!data || !data->cpr_desc)
>>>> + return -EINVAL;
>>>> +
>>>> + desc = data->cpr_desc;
>>>> +
>>>> + /* CPRh disallows MEM-ACC access from the HLOS */
>>>> + if (!data->acc_desc && desc->cpr_type < CTRL_TYPE_CPRH)
>>>> + return -EINVAL;
>>>> +
>>>> + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
>>>> + if (!drv)
>>>> + return -ENOMEM;
>>>> +
>>>> + drv->dev = dev;
>>>> + drv->desc = desc;
>>>> + drv->threads = devm_kcalloc(dev, desc->num_threads,
>>>> + sizeof(*drv->threads), GFP_KERNEL);
>>>> + if (!drv->threads)
>>>> + return -ENOMEM;
>>>> +
>>>> + drv->cell_data.num_domains = desc->num_threads;
>>>> + drv->cell_data.domains = devm_kcalloc(drv->dev,
>>>> + drv->cell_data.num_domains,
>>>> + sizeof(*drv->cell_data.domains),
>>>> + GFP_KERNEL);
>>>> + if (!drv->cell_data.domains)
>>>> + return -ENOMEM;
>>>> +
>>>> + if (data->acc_desc)
>>>> + drv->acc_desc = data->acc_desc;
>>>> +
>>>> + mutex_init(&drv->lock);
>>>> +
>>>> + if (desc->cpr_type < CTRL_TYPE_CPRH) {
>>>> + np = of_parse_phandle(dev->of_node, "acc-syscon", 0);
>>>> + if (!np)
>>>> + return -ENODEV;
>>>> +
>>>> + drv->tcsr = syscon_node_to_regmap(np);
>>>> + of_node_put(np);
>>>> + if (IS_ERR(drv->tcsr))
>>>> + return PTR_ERR(drv->tcsr);
>>>> + }
>>>> +
>>>> + ret = cpr3_resources_init(pdev, drv);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + drv->irq = platform_get_irq_optional(pdev, 0);
>>>> + if (desc->cpr_type != CTRL_TYPE_CPRH && drv->irq < 0)
>>>> + return -EINVAL;
>>>> +
>>>> + /* On CPRhardened, vreg access it not allowed */
>>>> + drv->vreg = devm_regulator_get_optional(dev, "vdd");
>>>> + if (desc->cpr_type != CTRL_TYPE_CPRH && IS_ERR(drv->vreg))
>>>> + return PTR_ERR(drv->vreg);
>>>> +
>>>> + /*
>>>> + * On at least CPRhardened, vreg is unaccessible and there is no
>>>> + * way to read linear step from that regulator, hence it is hardcoded
>>>> + * in the driver;
>>>> + * When the vreg_step is not declared in the cpr data (or is zero),
>>>> + * then having access to the vreg regulator is mandatory, as this
>>>> + * will be retrieved through the regulator API.
>>>> + */
>>>> + if (desc->vreg_step_fixed)
>>>> + drv->vreg_step = desc->vreg_step_fixed;
>>>> + else
>>>> + drv->vreg_step = regulator_get_linear_step(drv->vreg);
>>>> +
>>>> + if (!drv->vreg_step)
>>>> + return -EINVAL;
>>>> +
>>>> + /*
>>>> + * Initialize fuse corners, since it simply depends
>>>> + * on data in efuses.
>>>> + * Everything related to (virtual) corners has to be
>>>> + * initialized after attaching to the power domain,
>>>> + * since it depends on the CPU's OPP table.
>>>> + */
>>>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &drv->fusing_rev);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + ret = nvmem_cell_read_variable_le_u32(dev, "cpr_speed_bin", &drv->speed_bin);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + /*
>>>> + * Some SoCs require extra corners for MEM-ACC or APM: if
>>>> + * the related parameters have been specified, then reserve
>>>> + * a corner for the APM and/or MEM-ACC crossover, used by
>>>> + * OSM and CPRh HW to set the supply voltage during the APM
>>>> + * and/or MEM-ACC switch routine.
>>>> + */
>>>> + if (desc->cpr_type == CTRL_TYPE_CPRH) {
>>>> + if (desc->apm_crossover && desc->apm_hysteresis >= 0)
>>>> + drv->extra_corners++;
>>>> +
>>>> + if (desc->mem_acc_threshold)
>>>> + drv->extra_corners++;
>>>> + }
>>>> +
>>>> + /* Initialize all threads */
>>>> + for (i = 0; i < desc->num_threads; i++) {
>>>> + ret = cpr_thread_init(drv, i);
>>>> + if (ret)
>>>> + return ret;
>>>> + }
>>>> +
>>>> + /* Initialize global parameters */
>>>> + ret = cpr3_init_parameters(drv);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + /* Write initial configuration on all threads */
>>>> + for (i = 0; i < desc->num_threads; i++) {
>>>> + ret = cpr_configure(&drv->threads[i]);
>>>> + if (ret)
>>>> + return ret;
>>>> + }
>>>> +
>>>> + ret = of_genpd_add_provider_onecell(dev->of_node, &drv->cell_data);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + platform_set_drvdata(pdev, drv);
>>>> + cpr3_debugfs_init(drv);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int cpr_remove(struct platform_device *pdev)
>>>> +{
>>>> + struct cpr_drv *drv = platform_get_drvdata(pdev);
>>>> + int i;
>>>> +
>>>> + of_genpd_del_provider(pdev->dev.of_node);
>>>> +
>>>> + for (i = 0; i < drv->desc->num_threads; i++) {
>>>> + cpr_ctl_disable(&drv->threads[i]);
>>>> + cpr_irq_set(&drv->threads[i], 0);
>>>> + pm_genpd_remove(&drv->threads[i].pd);
>>>> + }
>>>> +
>>>> + debugfs_remove_recursive(drv->debugfs);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static const struct of_device_id cpr3_match_table[] = {
>>>> + { .compatible = "qcom,msm8998-cprh", .data = &msm8998_cpr_acc_desc },
>>>> + { .compatible = "qcom,sdm630-cprh", .data = &sdm630_cpr_acc_desc },
>>>> + { }
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, cpr3_match_table);
>>>> +
>>>> +static struct platform_driver cpr3_driver = {
>>>> + .probe = cpr_probe,
>>>> + .remove = cpr_remove,
>>>> + .driver = {
>>>> + .name = "qcom-cpr3",
>>>> + .of_match_table = cpr3_match_table,
>>>> + },
>>>> +};
>>>> +module_platform_driver(cpr3_driver)
>>>> +
>>>> +MODULE_DESCRIPTION("Core Power Reduction (CPR) v3/v4 driver");
>>>> +MODULE_LICENSE("GPL v2");
>>>> \ No newline at end of file
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh
2023-01-10 17:56 ` [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh Konrad Dybcio
@ 2023-01-10 18:45 ` Konrad Dybcio
0 siblings, 0 replies; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 18:45 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Rob Herring, Krzysztof Kozlowski,
devicetree, linux-kernel
On 10.01.2023 18:56, Konrad Dybcio wrote:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>
> Now that the CPR v3/v4/Hardened is ready, enable it on MSM8998.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
> [Konrad: separate from adding cpufreq, sort nodes and use lowercase hex]
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
This patch has many things wrong, please ignore..
Konrad
> arch/arm64/boot/dts/qcom/msm8998.dtsi | 325 ++++++++++++++++++++++++++
> 1 file changed, 325 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
> index af29a4bfd109..84f73484441f 100644
> --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
> @@ -139,6 +139,9 @@ CPU0: cpu@0 {
> capacity-dmips-mhz = <1024>;
> cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
> next-level-cache = <&L2_0>;
> + operating-points-v2 = <&cpu_gold_opp_table>;
> + power-domains = <&apc_cprh 0>;
> + power-domain-names = "cprh";
> L2_0: l2-cache {
> compatible = "cache";
> cache-level = <2>;
> @@ -153,6 +156,9 @@ CPU1: cpu@1 {
> capacity-dmips-mhz = <1024>;
> cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
> next-level-cache = <&L2_0>;
> + operating-points-v2 = <&cpu_gold_opp_table>;
> + power-domains = <&apc_cprh 0>;
> + power-domain-names = "cprh";
> };
>
> CPU2: cpu@2 {
> @@ -163,6 +169,9 @@ CPU2: cpu@2 {
> capacity-dmips-mhz = <1024>;
> cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
> next-level-cache = <&L2_0>;
> + operating-points-v2 = <&cpu_gold_opp_table>;
> + power-domains = <&apc_cprh 0>;
> + power-domain-names = "cprh";
> };
>
> CPU3: cpu@3 {
> @@ -173,6 +182,9 @@ CPU3: cpu@3 {
> capacity-dmips-mhz = <1024>;
> cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
> next-level-cache = <&L2_0>;
> + operating-points-v2 = <&cpu_gold_opp_table>;
> + power-domains = <&apc_cprh 0>;
> + power-domain-names = "cprh";
> };
>
> CPU4: cpu@100 {
> @@ -183,6 +195,9 @@ CPU4: cpu@100 {
> capacity-dmips-mhz = <1536>;
> cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
> next-level-cache = <&L2_1>;
> + operating-points-v2 = <&cpu_silver_opp_table>;
> + power-domains = <&apc_cprh 1>;
> + power-domain-names = "cprh";
> L2_1: l2-cache {
> compatible = "cache";
> cache-level = <2>;
> @@ -197,6 +212,9 @@ CPU5: cpu@101 {
> capacity-dmips-mhz = <1536>;
> cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
> next-level-cache = <&L2_1>;
> + operating-points-v2 = <&cpu_silver_opp_table>;
> + power-domains = <&apc_cprh 1>;
> + power-domain-names = "cprh";
> };
>
> CPU6: cpu@102 {
> @@ -207,6 +225,9 @@ CPU6: cpu@102 {
> capacity-dmips-mhz = <1536>;
> cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
> next-level-cache = <&L2_1>;
> + operating-points-v2 = <&cpu_silver_opp_table>;
> + power-domains = <&apc_cprh 1>;
> + power-domain-names = "cprh";
> };
>
> CPU7: cpu@103 {
> @@ -217,6 +238,9 @@ CPU7: cpu@103 {
> capacity-dmips-mhz = <1536>;
> cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
> next-level-cache = <&L2_1>;
> + operating-points-v2 = <&cpu_silver_opp_table>;
> + power-domains = <&apc_cprh 1>;
> + power-domain-names = "cprh";
> };
>
> cpu-map {
> @@ -310,6 +334,65 @@ scm {
> };
> };
>
> + cpu_gold_opp_table: opp-table-gold {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-2208000000 {
> + opp-hz = /bits/ 64 <2208000000>;
> + required-opps = <&cprh_opp3>;
> + };
> +
> + opp-1113600000 {
> + opp-hz = /bits/ 64 <1113600000>;
> + required-opps = <&cprh_opp2>;
> + };
> +
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&cprh_opp1>;
> + };
> + };
> +
> + cpu_silver_opp_table: opp-table-silver {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-1843200000 {
> + opp-hz = /bits/ 64 <1843200000>;
> + required-opps = <&cprh_opp3>;
> + };
> +
> + opp-1094400000 {
> + opp-hz = /bits/ 64 <1094400000>;
> + required-opps = <&cprh_opp2>;
> + };
> +
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&cprh_opp1>;
> + };
> + };
> +
> + cprh_opp_table: opp-table-cprh {
> + compatible = "operating-points-v2-qcom-level";
> +
> + cprh_opp1: opp1 {
> + opp-level = <1>;
> + qcom,opp-fuse-level = <1>;
> + };
> +
> + cprh_opp2: opp2 {
> + opp-level = <2>;
> + qcom,opp-fuse-level = <2>;
> + };
> +
> + cprh_opp3: opp3 {
> + opp-level = <3>;
> + qcom,opp-fuse-level = <2 3>;
> + };
> + };
> +
> psci {
> compatible = "arm,psci-1.0";
> method = "smc";
> @@ -839,6 +922,174 @@ qfprom: qfprom@784000 {
> #address-cells = <1>;
> #size-cells = <1>;
>
> + cpr_efuse_speedbin: speedbin@133 {
> + reg = <0x133 0x8>;
> + bits = <5 3>;
> + };
> +
> + cpr_fuse_revision: cpr_fusing_rev@13e {
> + reg = <0x13e 0x1>;
> + bits = <3 3>;
> + };
> +
> + /* CPR Ring Oscillator: Power Cluster */
> + cpr_ro_sel3_pwrcl: rosel3_pwrcl@218 {
> + reg = <0x218 0x1>;
> + bits = <0 4>;
> + };
> +
> + cpr_ro_sel2_pwrcl: rosel2_pwrcl@218 {
> + reg = <0x218 0x1>;
> + bits = <4 4>;
> + };
> +
> + cpr_ro_sel1_pwrcl: rosel1_pwrcl@219 {
> + reg = <0x219 0x1>;
> + bits = <0 4>;
> + };
> +
> + cpr_ro_sel0_pwrcl: rosel0_pwrcl@219 {
> + reg = <0x219 0x1>;
> + bits = <4 4>;
> + };
> +
> + /* CPR Init Voltage: Power Cluster */
> + cpr_init_voltage3_pwrcl: ivolt3_pwrcl@21a {
> + reg = <0x21a 0x1>;
> + bits = <0 6>;
> + };
> +
> + cpr_init_voltage2_pwrcl: ivolt2_pwrcl@21a {
> + reg = <0x21a 0x1>;
> + bits = <6 6>;
> + };
> +
> + cpr_init_voltage1_pwrcl: ivolt1_pwrcl@21b {
> + reg = <0x21b 0x1>;
> + bits = <4 6>;
> + };
> +
> + cpr_init_voltage0_pwrcl: ivolt0_pwrcl@21c {
> + reg = <0x21c 0x1>;
> + bits = <2 6>;
> + };
> +
> + /* CPR Target Quotients: Power Cluster */
> + cpr_quot3_pwrcl: quot3_pwrcl@21d {
> + reg = <0x21d 0x2>;
> + bits = <6 12>;
> + };
> +
> + cpr_quot2_pwrcl: quot2_pwrcl@21f {
> + reg = <0x21f 0x2>;
> + bits = <2 11>;
> + };
> +
> + cpr_quot1_pwrcl: quot1_pwrcl@220 {
> + reg = <0x220 0x2>;
> + bits = <6 12>;
> + };
> +
> + cpr_quot0_pwrcl: quot0_pwrcl@222 {
> + reg = <0x222 0x2>;
> + bits = <2 12>;
> + };
> +
> + /* CPR Quotient Offsets: Power Cluster */
> + cpr_quot_offset3_pwrcl: qoff3_pwrcl@226 {
> + reg = <0x226 0x1>;
> + bits = <1 7>;
> + };
> +
> + cpr_quot_offset2_pwrcl: qoff2_pwrcl@227 {
> + reg = <0x227 0x1>;
> + bits = <0 7>;
> + };
> +
> + cpr_quot_offset1_pwrcl: qoff1_pwrcl@227 {
> + reg = <0x227 0x1>;
> + bits = <7 6>;
> + };
> +
> + /* CPR Ring Oscillator: Performance Cluster */
> + cpr_ro_sel3_perfcl: rosel3_perfcl@229 {
> + reg = <0x229 0x1>;
> + bits = <6 4>;
> + };
> +
> + cpr_ro_sel2_perfcl: rosel2_perfcl@22a {
> + reg = <0x22a 0x1>;
> + bits = <2 4>;
> + };
> +
> + cpr_ro_sel1_perfcl: rosel1_perfcl@22a {
> + reg = <0x22a 0x1>;
> + bits = <6 4>;
> + };
> +
> + cpr_ro_sel0_perfcl: rosel0_perfcl@22b {
> + reg = <0x22b 0x1>;
> + bits = <2 4>;
> + };
> +
> + /* CPR Init Voltage: Performance Cluster */
> + cpr_init_voltage3_perfcl: ivolt3_perfcl@22b {
> + reg = <0x22b 0x1>;
> + bits = <6 6>;
> + };
> +
> + cpr_init_voltage2_perfcl: ivolt2_perfcl@22c {
> + reg = <0x22c 0x1>;
> + bits = <4 6>;
> + };
> +
> + cpr_init_voltage1_perfcl: ivolt1_perfcl@22d {
> + reg = <0x22d 0x1>;
> + bits = <2 6>;
> + };
> +
> + cpr_init_voltage0_perfcl: ivolt0_perfcl@22e {
> + reg = <0x22e 0x1>;
> + bits = <0 6>;
> + };
> +
> + /* CPR Target Quotients: Performance Cluster */
> + cpr_quot3_perfcl: quot3_perfcl@22f {
> + reg = <0x22f 0x2>;
> + bits = <4 11>;
> + };
> +
> + cpr_quot2_perfcl: quot2_perfcl@231 {
> + reg = <0x231 0x2>;
> + bits = <0 12>;
> + };
> +
> + cpr_quot1_perfcl: quot1_perfcl@232 {
> + reg = <0x232 0x2>;
> + bits = <4 12>;
> + };
> +
> + cpr_quot0_perfcl: quot0_perfcl@234 {
> + reg = <0x234 0x2>;
> + bits = <0 12>;
> + };
> +
> + /* CPR Quotient Offsets: Performance Cluster */
> + cpr_quot_offset3_perfcl: qoff3_perfcl@237 {
> + reg = <0x237 0x1>;
> + bits = <7 6>;
> + };
> +
> + cpr_quot_offset2_perfcl: qoff2_perfcl@238 {
> + reg = <0x238 0x1>;
> + bits = <6 7>;
> + };
> +
> + cpr_quot_offset1_perfcl: qoff1_perfcl@239 {
> + reg = <0x239 0x1>;
> + bits = <5 3>;
> + };
> +
> qusb2_hstx_trim: hstx-trim@23a {
> reg = <0x23a 0x1>;
> bits = <0 4>;
> @@ -2998,6 +3249,80 @@ frame@17928000 {
> };
> };
>
> + apc_cprh: power-controller@179c8000 {
> + compatible = "qcom,msm8998-cprh", "qcom,cprh";
> + reg = <0x0179c4000 0x4000>, <0x0179c8000 0x4000>;
> + clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
> + clock-names = "ref";
> + operating-points-v2 = <&cprh_opp_table>;
> + #power-domain-cells = <1>;
> +
> + nvmem-cells = <&cpr_efuse_speedbin>,
> + <&cpr_fuse_revision>,
> + <&cpr_quot0_pwrcl>,
> + <&cpr_quot1_pwrcl>,
> + <&cpr_quot2_pwrcl>,
> + <&cpr_quot3_pwrcl>,
> + <&cpr_quot_offset1_pwrcl>,
> + <&cpr_quot_offset2_pwrcl>,
> + <&cpr_quot_offset3_pwrcl>,
> + <&cpr_init_voltage0_pwrcl>,
> + <&cpr_init_voltage1_pwrcl>,
> + <&cpr_init_voltage2_pwrcl>,
> + <&cpr_init_voltage3_pwrcl>,
> + <&cpr_ro_sel0_pwrcl>,
> + <&cpr_ro_sel1_pwrcl>,
> + <&cpr_ro_sel2_pwrcl>,
> + <&cpr_ro_sel3_pwrcl>,
> + <&cpr_quot0_perfcl>,
> + <&cpr_quot1_perfcl>,
> + <&cpr_quot2_perfcl>,
> + <&cpr_quot3_perfcl>,
> + <&cpr_quot_offset1_perfcl>,
> + <&cpr_quot_offset2_perfcl>,
> + <&cpr_quot_offset3_perfcl>,
> + <&cpr_init_voltage0_perfcl>,
> + <&cpr_init_voltage1_perfcl>,
> + <&cpr_init_voltage2_perfcl>,
> + <&cpr_init_voltage3_perfcl>,
> + <&cpr_ro_sel0_perfcl>,
> + <&cpr_ro_sel1_perfcl>,
> + <&cpr_ro_sel2_perfcl>,
> + <&cpr_ro_sel3_perfcl>;
> + nvmem-cell-names = "cpr_speed_bin",
> + "cpr_fuse_revision",
> + "cpr0_quotient1",
> + "cpr0_quotient2",
> + "cpr0_quotient3",
> + "cpr0_quotient4",
> + "cpr0_quotient_offset2",
> + "cpr0_quotient_offset3",
> + "cpr0_quotient_offset4",
> + "cpr0_init_voltage1",
> + "cpr0_init_voltage2",
> + "cpr0_init_voltage3",
> + "cpr0_init_voltage4",
> + "cpr0_ring_osc1",
> + "cpr0_ring_osc2",
> + "cpr0_ring_osc3",
> + "cpr0_ring_osc4",
> + "cpr1_quotient1",
> + "cpr1_quotient2",
> + "cpr1_quotient3",
> + "cpr1_quotient4",
> + "cpr1_quotient_offset2",
> + "cpr1_quotient_offset3",
> + "cpr1_quotient_offset4",
> + "cpr1_init_voltage1",
> + "cpr1_init_voltage2",
> + "cpr1_init_voltage3",
> + "cpr1_init_voltage4",
> + "cpr1_ring_osc1",
> + "cpr1_ring_osc2",
> + "cpr1_ring_osc3",
> + "cpr1_ring_osc4";
> + };
> +
> intc: interrupt-controller@17a00000 {
> compatible = "arm,gic-v3";
> reg = <0x17a00000 0x10000>, /* GICD */
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
2023-01-10 17:56 ` [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver Konrad Dybcio
@ 2023-01-10 18:54 ` Konrad Dybcio
2023-01-11 2:18 ` Dmitry Baryshkov
2023-01-11 1:34 ` Rob Herring
1 sibling, 1 reply; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-10 18:54 UTC (permalink / raw)
To: linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Rob Herring, Rob Herring,
Krzysztof Kozlowski, devicetree, linux-kernel
On 10.01.2023 18:56, Konrad Dybcio wrote:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>
> Add the bindings for the CPR3 driver to the documentation.
>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
> [Konrad: Add type reference to acc-syscon; update AGdR's email]
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
Need to add
qcom,opp-oloop-vadj
qcom,opp-cloop-vadj
in next revision.
Konrad
> .../bindings/soc/qcom/qcom,cpr3.yaml | 242 ++++++++++++++++++
> 1 file changed, 242 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>
> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
> new file mode 100644
> index 000000000000..52e87061a04b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
> @@ -0,0 +1,242 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh)
> +
> +description: |
> + CPR (Core Power Reduction) is a technology to reduce core power on a CPU
> + or other device. Each OPP of a device corresponds to a "corner" that has
> + a range of valid voltages for a particular frequency. While the device is
> + running at a particular frequency, CPR monitors dynamic factors such as
> + temperature, etc. and suggests or, in the CPR-Hardened case performs,
> + adjustments to the voltage to save power and meet silicon characteristic
> + requirements.
> +
> +maintainers:
> + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> +
> +properties:
> + compatible:
> + oneOf:
> + - description: CPRv3 controller
> + items:
> + - const: qcom,cpr3
> + - description: CPRv4 controller
> + items:
> + - const: qcom,cpr4
> + - description: CPRv4-Hardened controller
> + items:
> + - enum:
> + - qcom,msm8998-cprh
> + - qcom,sdm630-cprh
> + - const: qcom,cprh
> +
> + reg:
> + description: Base address and size of the CPR controller(s)
> + minItems: 1
> + maxItems: 2
> +
> + interrupts:
> + maxItems: 1
> +
> + clock-names:
> + items:
> + - const: "ref"
> +
> + clocks:
> + items:
> + - description: CPR reference clock
> +
> + vdd-supply:
> + description: Autonomous Phase Control (APC) or other power supply
> +
> + '#power-domain-cells':
> + const: 1
> +
> + acc-syscon:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description: phandle to syscon for writing ACC settings
> +
> + nvmem-cells:
> + description: Cells containing the fuse corners and revision data
> + minItems: 10
> + maxItems: 32
> +
> + nvmem-cell-names:
> + minItems: 10
> + maxItems: 32
> +
> + operating-points-v2: true
> +
> +required:
> + - compatible
> + - reg
> + - clock-names
> + - clocks
> + - "#power-domain-cells"
> + - nvmem-cells
> + - nvmem-cell-names
> + - operating-points-v2
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/qcom,gcc-msm8998.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> +
> + cpus {
> + #address-cells = <2>;
> + #size-cells = <0>;
> +
> + cpu@0 {
> + compatible = "qcom,kryo280";
> + device_type = "cpu";
> + reg = <0x0 0x0>;
> + operating-points-v2 = <&cpu_gold_opp_table>;
> + power-domains = <&apc_cprh 0>;
> + power-domain-names = "cprh";
> + };
> +
> + cpu@100 {
> + compatible = "qcom,kryo280";
> + device_type = "cpu";
> + reg = <0x0 0x0>;
> + operating-points-v2 = <&cpu_silver_opp_table>;
> + power-domains = <&apc_cprh 1>;
> + power-domain-names = "cprh";
> + };
> + };
> +
> + cpu_gold_opp_table: opp-table-gold {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-2208000000 {
> + opp-hz = /bits/ 64 <2208000000>;
> + required-opps = <&cprh_opp3>;
> + };
> + opp-1113600000 {
> + opp-hz = /bits/ 64 <1113600000>;
> + required-opps = <&cprh_opp2>;
> + };
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&cprh_opp1>;
> + };
> + };
> +
> + cpu_silver_opp_table: opp-table-silver {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-1843200000 {
> + opp-hz = /bits/ 64 <1843200000>;
> + required-opps = <&cprh_opp3>;
> + };
> + opp-1094400000 {
> + opp-hz = /bits/ 64 <1094400000>;
> + required-opps = <&cprh_opp2>;
> + };
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&cprh_opp1>;
> + };
> + };
> +
> + cprh_opp_table: opp-table-cprh {
> + compatible = "operating-points-v2-qcom-level";
> +
> + cprh_opp1: opp1 {
> + opp-level = <1>;
> + qcom,opp-fuse-level = <1>;
> + };
> + cprh_opp2: opp2 {
> + opp-level = <2>;
> + qcom,opp-fuse-level = <2>;
> + };
> + cprh_opp3: opp3 {
> + opp-level = <3>;
> + qcom,opp-fuse-level = <2 3>;
> + };
> + };
> +
> + apc_cprh: power-controller@179c8000 {
> + compatible = "qcom,msm8998-cprh", "qcom,cprh";
> + reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>;
> + clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
> + clock-names = "ref";
> +
> + #power-domain-cells = <1>;
> + operating-points-v2 = <&cprh_opp_table>;
> +
> + nvmem-cells = <&cpr_efuse_speedbin>,
> + <&cpr_fuse_revision>,
> + <&cpr_quot0_pwrcl>,
> + <&cpr_quot1_pwrcl>,
> + <&cpr_quot2_pwrcl>,
> + <&cpr_quot3_pwrcl>,
> + <&cpr_quot_offset1_pwrcl>,
> + <&cpr_quot_offset2_pwrcl>,
> + <&cpr_quot_offset3_pwrcl>,
> + <&cpr_init_voltage0_pwrcl>,
> + <&cpr_init_voltage1_pwrcl>,
> + <&cpr_init_voltage2_pwrcl>,
> + <&cpr_init_voltage3_pwrcl>,
> + <&cpr_ro_sel0_pwrcl>,
> + <&cpr_ro_sel1_pwrcl>,
> + <&cpr_ro_sel2_pwrcl>,
> + <&cpr_ro_sel3_pwrcl>,
> + <&cpr_quot0_perfcl>,
> + <&cpr_quot1_perfcl>,
> + <&cpr_quot2_perfcl>,
> + <&cpr_quot3_perfcl>,
> + <&cpr_quot_offset1_perfcl>,
> + <&cpr_quot_offset2_perfcl>,
> + <&cpr_quot_offset3_perfcl>,
> + <&cpr_init_voltage0_perfcl>,
> + <&cpr_init_voltage1_perfcl>,
> + <&cpr_init_voltage2_perfcl>,
> + <&cpr_init_voltage3_perfcl>,
> + <&cpr_ro_sel0_perfcl>,
> + <&cpr_ro_sel1_perfcl>,
> + <&cpr_ro_sel2_perfcl>,
> + <&cpr_ro_sel3_perfcl>;
> +
> + nvmem-cell-names = "cpr_speed_bin",
> + "cpr_fuse_revision",
> + "cpr0_quotient1",
> + "cpr0_quotient2",
> + "cpr0_quotient3",
> + "cpr0_quotient4",
> + "cpr0_quotient_offset2",
> + "cpr0_quotient_offset3",
> + "cpr0_quotient_offset4",
> + "cpr0_init_voltage1",
> + "cpr0_init_voltage2",
> + "cpr0_init_voltage3",
> + "cpr0_init_voltage4",
> + "cpr0_ring_osc1",
> + "cpr0_ring_osc2",
> + "cpr0_ring_osc3",
> + "cpr0_ring_osc4",
> + "cpr1_quotient1",
> + "cpr1_quotient2",
> + "cpr1_quotient3",
> + "cpr1_quotient4",
> + "cpr1_quotient_offset2",
> + "cpr1_quotient_offset3",
> + "cpr1_quotient_offset4",
> + "cpr1_init_voltage1",
> + "cpr1_init_voltage2",
> + "cpr1_init_voltage3",
> + "cpr1_init_voltage4",
> + "cpr1_ring_osc1",
> + "cpr1_ring_osc2",
> + "cpr1_ring_osc3",
> + "cpr1_ring_osc4";
> + };
> +...
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
2023-01-10 17:56 ` [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver Konrad Dybcio
2023-01-10 18:54 ` Konrad Dybcio
@ 2023-01-11 1:34 ` Rob Herring
1 sibling, 0 replies; 17+ messages in thread
From: Rob Herring @ 2023-01-11 1:34 UTC (permalink / raw)
To: Konrad Dybcio
Cc: marijn.suijten, linux-kernel, AngeloGioacchino Del Regno,
krzysztof.kozlowski, angelogioacchino.delregno, agross,
andersson, Krzysztof Kozlowski, devicetree, linux-arm-msm,
Rob Herring
On Tue, 10 Jan 2023 18:56:01 +0100, Konrad Dybcio wrote:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>
> Add the bindings for the CPR3 driver to the documentation.
>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
> [Konrad: Add type reference to acc-syscon; update AGdR's email]
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
> .../bindings/soc/qcom/qcom,cpr3.yaml | 242 ++++++++++++++++++
> 1 file changed, 242 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.example.dtb: opp-table-cprh: opp3:qcom,opp-fuse-level:0: [2, 3] is too long
From schema: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230110175605.1240188-2-konrad.dybcio@linaro.org
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
2023-01-10 18:54 ` Konrad Dybcio
@ 2023-01-11 2:18 ` Dmitry Baryshkov
2023-01-11 13:30 ` Konrad Dybcio
0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Baryshkov @ 2023-01-11 2:18 UTC (permalink / raw)
To: Konrad Dybcio, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Rob Herring, Rob Herring,
Krzysztof Kozlowski, devicetree, linux-kernel
On 10/01/2023 20:54, Konrad Dybcio wrote:
>
>
> On 10.01.2023 18:56, Konrad Dybcio wrote:
>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>
>> Add the bindings for the CPR3 driver to the documentation.
>>
>> Reviewed-by: Rob Herring <robh@kernel.org>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>> [Konrad: Add type reference to acc-syscon; update AGdR's email]
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>> ---
> Need to add
>
> qcom,opp-oloop-vadj
> qcom,opp-cloop-vadj
And note that at least for CPR3 they are different between fusing
revisions. I see that for CPRh (esp. for 8998v2) they are the same, but
this is not the case for 8996 (CPR3).
>
> in next revision.
>
> Konrad
>> .../bindings/soc/qcom/qcom,cpr3.yaml | 242 ++++++++++++++++++
>> 1 file changed, 242 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>> new file mode 100644
>> index 000000000000..52e87061a04b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>> @@ -0,0 +1,242 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#"
>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>> +
>> +title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh)
>> +
>> +description: |
>> + CPR (Core Power Reduction) is a technology to reduce core power on a CPU
>> + or other device. Each OPP of a device corresponds to a "corner" that has
>> + a range of valid voltages for a particular frequency. While the device is
>> + running at a particular frequency, CPR monitors dynamic factors such as
>> + temperature, etc. and suggests or, in the CPR-Hardened case performs,
>> + adjustments to the voltage to save power and meet silicon characteristic
>> + requirements.
>> +
>> +maintainers:
>> + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> +
>> +properties:
>> + compatible:
>> + oneOf:
>> + - description: CPRv3 controller
>> + items:
>> + - const: qcom,cpr3
>> + - description: CPRv4 controller
>> + items:
>> + - const: qcom,cpr4
>> + - description: CPRv4-Hardened controller
>> + items:
>> + - enum:
>> + - qcom,msm8998-cprh
>> + - qcom,sdm630-cprh
>> + - const: qcom,cprh
>> +
>> + reg:
>> + description: Base address and size of the CPR controller(s)
>> + minItems: 1
>> + maxItems: 2
>> +
>> + interrupts:
>> + maxItems: 1
>> +
>> + clock-names:
>> + items:
>> + - const: "ref"
>> +
>> + clocks:
>> + items:
>> + - description: CPR reference clock
>> +
>> + vdd-supply:
>> + description: Autonomous Phase Control (APC) or other power supply
>> +
>> + '#power-domain-cells':
>> + const: 1
>> +
>> + acc-syscon:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description: phandle to syscon for writing ACC settings
>> +
>> + nvmem-cells:
>> + description: Cells containing the fuse corners and revision data
>> + minItems: 10
>> + maxItems: 32
>> +
>> + nvmem-cell-names:
>> + minItems: 10
>> + maxItems: 32
>> +
>> + operating-points-v2: true
>> +
>> +required:
>> + - compatible
>> + - reg
>> + - clock-names
>> + - clocks
>> + - "#power-domain-cells"
>> + - nvmem-cells
>> + - nvmem-cell-names
>> + - operating-points-v2
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |
>> + #include <dt-bindings/clock/qcom,gcc-msm8998.h>
>> + #include <dt-bindings/interrupt-controller/irq.h>
>> +
>> + cpus {
>> + #address-cells = <2>;
>> + #size-cells = <0>;
>> +
>> + cpu@0 {
>> + compatible = "qcom,kryo280";
>> + device_type = "cpu";
>> + reg = <0x0 0x0>;
>> + operating-points-v2 = <&cpu_gold_opp_table>;
>> + power-domains = <&apc_cprh 0>;
>> + power-domain-names = "cprh";
>> + };
>> +
>> + cpu@100 {
>> + compatible = "qcom,kryo280";
>> + device_type = "cpu";
>> + reg = <0x0 0x0>;
>> + operating-points-v2 = <&cpu_silver_opp_table>;
>> + power-domains = <&apc_cprh 1>;
>> + power-domain-names = "cprh";
>> + };
>> + };
>> +
>> + cpu_gold_opp_table: opp-table-gold {
>> + compatible = "operating-points-v2";
>> + opp-shared;
>> +
>> + opp-2208000000 {
>> + opp-hz = /bits/ 64 <2208000000>;
>> + required-opps = <&cprh_opp3>;
>> + };
>> + opp-1113600000 {
>> + opp-hz = /bits/ 64 <1113600000>;
>> + required-opps = <&cprh_opp2>;
>> + };
>> + opp-300000000 {
>> + opp-hz = /bits/ 64 <300000000>;
>> + required-opps = <&cprh_opp1>;
>> + };
>> + };
>> +
>> + cpu_silver_opp_table: opp-table-silver {
>> + compatible = "operating-points-v2";
>> + opp-shared;
>> +
>> + opp-1843200000 {
>> + opp-hz = /bits/ 64 <1843200000>;
>> + required-opps = <&cprh_opp3>;
>> + };
>> + opp-1094400000 {
>> + opp-hz = /bits/ 64 <1094400000>;
>> + required-opps = <&cprh_opp2>;
>> + };
>> + opp-300000000 {
>> + opp-hz = /bits/ 64 <300000000>;
>> + required-opps = <&cprh_opp1>;
>> + };
>> + };
>> +
>> + cprh_opp_table: opp-table-cprh {
>> + compatible = "operating-points-v2-qcom-level";
>> +
>> + cprh_opp1: opp1 {
>> + opp-level = <1>;
>> + qcom,opp-fuse-level = <1>;
>> + };
>> + cprh_opp2: opp2 {
>> + opp-level = <2>;
>> + qcom,opp-fuse-level = <2>;
>> + };
>> + cprh_opp3: opp3 {
>> + opp-level = <3>;
>> + qcom,opp-fuse-level = <2 3>;
>> + };
>> + };
>> +
>> + apc_cprh: power-controller@179c8000 {
>> + compatible = "qcom,msm8998-cprh", "qcom,cprh";
>> + reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>;
>> + clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
>> + clock-names = "ref";
>> +
>> + #power-domain-cells = <1>;
>> + operating-points-v2 = <&cprh_opp_table>;
>> +
>> + nvmem-cells = <&cpr_efuse_speedbin>,
>> + <&cpr_fuse_revision>,
>> + <&cpr_quot0_pwrcl>,
>> + <&cpr_quot1_pwrcl>,
>> + <&cpr_quot2_pwrcl>,
>> + <&cpr_quot3_pwrcl>,
>> + <&cpr_quot_offset1_pwrcl>,
>> + <&cpr_quot_offset2_pwrcl>,
>> + <&cpr_quot_offset3_pwrcl>,
>> + <&cpr_init_voltage0_pwrcl>,
>> + <&cpr_init_voltage1_pwrcl>,
>> + <&cpr_init_voltage2_pwrcl>,
>> + <&cpr_init_voltage3_pwrcl>,
>> + <&cpr_ro_sel0_pwrcl>,
>> + <&cpr_ro_sel1_pwrcl>,
>> + <&cpr_ro_sel2_pwrcl>,
>> + <&cpr_ro_sel3_pwrcl>,
>> + <&cpr_quot0_perfcl>,
>> + <&cpr_quot1_perfcl>,
>> + <&cpr_quot2_perfcl>,
>> + <&cpr_quot3_perfcl>,
>> + <&cpr_quot_offset1_perfcl>,
>> + <&cpr_quot_offset2_perfcl>,
>> + <&cpr_quot_offset3_perfcl>,
>> + <&cpr_init_voltage0_perfcl>,
>> + <&cpr_init_voltage1_perfcl>,
>> + <&cpr_init_voltage2_perfcl>,
>> + <&cpr_init_voltage3_perfcl>,
>> + <&cpr_ro_sel0_perfcl>,
>> + <&cpr_ro_sel1_perfcl>,
>> + <&cpr_ro_sel2_perfcl>,
>> + <&cpr_ro_sel3_perfcl>;
>> +
>> + nvmem-cell-names = "cpr_speed_bin",
>> + "cpr_fuse_revision",
>> + "cpr0_quotient1",
>> + "cpr0_quotient2",
>> + "cpr0_quotient3",
>> + "cpr0_quotient4",
>> + "cpr0_quotient_offset2",
>> + "cpr0_quotient_offset3",
>> + "cpr0_quotient_offset4",
>> + "cpr0_init_voltage1",
>> + "cpr0_init_voltage2",
>> + "cpr0_init_voltage3",
>> + "cpr0_init_voltage4",
>> + "cpr0_ring_osc1",
>> + "cpr0_ring_osc2",
>> + "cpr0_ring_osc3",
>> + "cpr0_ring_osc4",
>> + "cpr1_quotient1",
>> + "cpr1_quotient2",
>> + "cpr1_quotient3",
>> + "cpr1_quotient4",
>> + "cpr1_quotient_offset2",
>> + "cpr1_quotient_offset3",
>> + "cpr1_quotient_offset4",
>> + "cpr1_init_voltage1",
>> + "cpr1_init_voltage2",
>> + "cpr1_init_voltage3",
>> + "cpr1_init_voltage4",
>> + "cpr1_ring_osc1",
>> + "cpr1_ring_osc2",
>> + "cpr1_ring_osc3",
>> + "cpr1_ring_osc4";
>> + };
>> +...
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
2023-01-11 2:18 ` Dmitry Baryshkov
@ 2023-01-11 13:30 ` Konrad Dybcio
2023-01-11 15:58 ` Dmitry Baryshkov
0 siblings, 1 reply; 17+ messages in thread
From: Konrad Dybcio @ 2023-01-11 13:30 UTC (permalink / raw)
To: Dmitry Baryshkov, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Rob Herring, Rob Herring,
Krzysztof Kozlowski, devicetree, linux-kernel
On 11.01.2023 03:18, Dmitry Baryshkov wrote:
> On 10/01/2023 20:54, Konrad Dybcio wrote:
>>
>>
>> On 10.01.2023 18:56, Konrad Dybcio wrote:
>>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>
>>> Add the bindings for the CPR3 driver to the documentation.
>>>
>>> Reviewed-by: Rob Herring <robh@kernel.org>
>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>> [Konrad: Add type reference to acc-syscon; update AGdR's email]
>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>>> ---
>> Need to add
>>
>> qcom,opp-oloop-vadj
>> qcom,opp-cloop-vadj
>
> And note that at least for CPR3 they are different between fusing revisions. I see that for CPRh (esp. for 8998v2) they are the same, but this is not the case for 8996 (CPR3).
If we both mean the "speed bin"-dependent values, the driver
reads the fuse value but currently does nothing. My guess would
be that Angelo omitted it, as - just like you pointed out - MSM8998
(and SDM660 for that matter) don't really use it. I suppose I could
take care of that in bindings by making this an array and handle it
separately in a different patchset, as the per-revision values
aren't *that much* different, and again aren't really of concern for
the first round of supported SoCs.
Konrad
>
>>
>> in next revision.
>>
>> Konrad
>>> .../bindings/soc/qcom/qcom,cpr3.yaml | 242 ++++++++++++++++++
>>> 1 file changed, 242 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>>> new file mode 100644
>>> index 000000000000..52e87061a04b
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
>>> @@ -0,0 +1,242 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#"
>>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>>> +
>>> +title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh)
>>> +
>>> +description: |
>>> + CPR (Core Power Reduction) is a technology to reduce core power on a CPU
>>> + or other device. Each OPP of a device corresponds to a "corner" that has
>>> + a range of valid voltages for a particular frequency. While the device is
>>> + running at a particular frequency, CPR monitors dynamic factors such as
>>> + temperature, etc. and suggests or, in the CPR-Hardened case performs,
>>> + adjustments to the voltage to save power and meet silicon characteristic
>>> + requirements.
>>> +
>>> +maintainers:
>>> + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>>> +
>>> +properties:
>>> + compatible:
>>> + oneOf:
>>> + - description: CPRv3 controller
>>> + items:
>>> + - const: qcom,cpr3
>>> + - description: CPRv4 controller
>>> + items:
>>> + - const: qcom,cpr4
>>> + - description: CPRv4-Hardened controller
>>> + items:
>>> + - enum:
>>> + - qcom,msm8998-cprh
>>> + - qcom,sdm630-cprh
>>> + - const: qcom,cprh
>>> +
>>> + reg:
>>> + description: Base address and size of the CPR controller(s)
>>> + minItems: 1
>>> + maxItems: 2
>>> +
>>> + interrupts:
>>> + maxItems: 1
>>> +
>>> + clock-names:
>>> + items:
>>> + - const: "ref"
>>> +
>>> + clocks:
>>> + items:
>>> + - description: CPR reference clock
>>> +
>>> + vdd-supply:
>>> + description: Autonomous Phase Control (APC) or other power supply
>>> +
>>> + '#power-domain-cells':
>>> + const: 1
>>> +
>>> + acc-syscon:
>>> + $ref: /schemas/types.yaml#/definitions/phandle
>>> + description: phandle to syscon for writing ACC settings
>>> +
>>> + nvmem-cells:
>>> + description: Cells containing the fuse corners and revision data
>>> + minItems: 10
>>> + maxItems: 32
>>> +
>>> + nvmem-cell-names:
>>> + minItems: 10
>>> + maxItems: 32
>>> +
>>> + operating-points-v2: true
>>> +
>>> +required:
>>> + - compatible
>>> + - reg
>>> + - clock-names
>>> + - clocks
>>> + - "#power-domain-cells"
>>> + - nvmem-cells
>>> + - nvmem-cell-names
>>> + - operating-points-v2
>>> +
>>> +additionalProperties: false
>>> +
>>> +examples:
>>> + - |
>>> + #include <dt-bindings/clock/qcom,gcc-msm8998.h>
>>> + #include <dt-bindings/interrupt-controller/irq.h>
>>> +
>>> + cpus {
>>> + #address-cells = <2>;
>>> + #size-cells = <0>;
>>> +
>>> + cpu@0 {
>>> + compatible = "qcom,kryo280";
>>> + device_type = "cpu";
>>> + reg = <0x0 0x0>;
>>> + operating-points-v2 = <&cpu_gold_opp_table>;
>>> + power-domains = <&apc_cprh 0>;
>>> + power-domain-names = "cprh";
>>> + };
>>> +
>>> + cpu@100 {
>>> + compatible = "qcom,kryo280";
>>> + device_type = "cpu";
>>> + reg = <0x0 0x0>;
>>> + operating-points-v2 = <&cpu_silver_opp_table>;
>>> + power-domains = <&apc_cprh 1>;
>>> + power-domain-names = "cprh";
>>> + };
>>> + };
>>> +
>>> + cpu_gold_opp_table: opp-table-gold {
>>> + compatible = "operating-points-v2";
>>> + opp-shared;
>>> +
>>> + opp-2208000000 {
>>> + opp-hz = /bits/ 64 <2208000000>;
>>> + required-opps = <&cprh_opp3>;
>>> + };
>>> + opp-1113600000 {
>>> + opp-hz = /bits/ 64 <1113600000>;
>>> + required-opps = <&cprh_opp2>;
>>> + };
>>> + opp-300000000 {
>>> + opp-hz = /bits/ 64 <300000000>;
>>> + required-opps = <&cprh_opp1>;
>>> + };
>>> + };
>>> +
>>> + cpu_silver_opp_table: opp-table-silver {
>>> + compatible = "operating-points-v2";
>>> + opp-shared;
>>> +
>>> + opp-1843200000 {
>>> + opp-hz = /bits/ 64 <1843200000>;
>>> + required-opps = <&cprh_opp3>;
>>> + };
>>> + opp-1094400000 {
>>> + opp-hz = /bits/ 64 <1094400000>;
>>> + required-opps = <&cprh_opp2>;
>>> + };
>>> + opp-300000000 {
>>> + opp-hz = /bits/ 64 <300000000>;
>>> + required-opps = <&cprh_opp1>;
>>> + };
>>> + };
>>> +
>>> + cprh_opp_table: opp-table-cprh {
>>> + compatible = "operating-points-v2-qcom-level";
>>> +
>>> + cprh_opp1: opp1 {
>>> + opp-level = <1>;
>>> + qcom,opp-fuse-level = <1>;
>>> + };
>>> + cprh_opp2: opp2 {
>>> + opp-level = <2>;
>>> + qcom,opp-fuse-level = <2>;
>>> + };
>>> + cprh_opp3: opp3 {
>>> + opp-level = <3>;
>>> + qcom,opp-fuse-level = <2 3>;
>>> + };
>>> + };
>>> +
>>> + apc_cprh: power-controller@179c8000 {
>>> + compatible = "qcom,msm8998-cprh", "qcom,cprh";
>>> + reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>;
>>> + clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
>>> + clock-names = "ref";
>>> +
>>> + #power-domain-cells = <1>;
>>> + operating-points-v2 = <&cprh_opp_table>;
>>> +
>>> + nvmem-cells = <&cpr_efuse_speedbin>,
>>> + <&cpr_fuse_revision>,
>>> + <&cpr_quot0_pwrcl>,
>>> + <&cpr_quot1_pwrcl>,
>>> + <&cpr_quot2_pwrcl>,
>>> + <&cpr_quot3_pwrcl>,
>>> + <&cpr_quot_offset1_pwrcl>,
>>> + <&cpr_quot_offset2_pwrcl>,
>>> + <&cpr_quot_offset3_pwrcl>,
>>> + <&cpr_init_voltage0_pwrcl>,
>>> + <&cpr_init_voltage1_pwrcl>,
>>> + <&cpr_init_voltage2_pwrcl>,
>>> + <&cpr_init_voltage3_pwrcl>,
>>> + <&cpr_ro_sel0_pwrcl>,
>>> + <&cpr_ro_sel1_pwrcl>,
>>> + <&cpr_ro_sel2_pwrcl>,
>>> + <&cpr_ro_sel3_pwrcl>,
>>> + <&cpr_quot0_perfcl>,
>>> + <&cpr_quot1_perfcl>,
>>> + <&cpr_quot2_perfcl>,
>>> + <&cpr_quot3_perfcl>,
>>> + <&cpr_quot_offset1_perfcl>,
>>> + <&cpr_quot_offset2_perfcl>,
>>> + <&cpr_quot_offset3_perfcl>,
>>> + <&cpr_init_voltage0_perfcl>,
>>> + <&cpr_init_voltage1_perfcl>,
>>> + <&cpr_init_voltage2_perfcl>,
>>> + <&cpr_init_voltage3_perfcl>,
>>> + <&cpr_ro_sel0_perfcl>,
>>> + <&cpr_ro_sel1_perfcl>,
>>> + <&cpr_ro_sel2_perfcl>,
>>> + <&cpr_ro_sel3_perfcl>;
>>> +
>>> + nvmem-cell-names = "cpr_speed_bin",
>>> + "cpr_fuse_revision",
>>> + "cpr0_quotient1",
>>> + "cpr0_quotient2",
>>> + "cpr0_quotient3",
>>> + "cpr0_quotient4",
>>> + "cpr0_quotient_offset2",
>>> + "cpr0_quotient_offset3",
>>> + "cpr0_quotient_offset4",
>>> + "cpr0_init_voltage1",
>>> + "cpr0_init_voltage2",
>>> + "cpr0_init_voltage3",
>>> + "cpr0_init_voltage4",
>>> + "cpr0_ring_osc1",
>>> + "cpr0_ring_osc2",
>>> + "cpr0_ring_osc3",
>>> + "cpr0_ring_osc4",
>>> + "cpr1_quotient1",
>>> + "cpr1_quotient2",
>>> + "cpr1_quotient3",
>>> + "cpr1_quotient4",
>>> + "cpr1_quotient_offset2",
>>> + "cpr1_quotient_offset3",
>>> + "cpr1_quotient_offset4",
>>> + "cpr1_init_voltage1",
>>> + "cpr1_init_voltage2",
>>> + "cpr1_init_voltage3",
>>> + "cpr1_init_voltage4",
>>> + "cpr1_ring_osc1",
>>> + "cpr1_ring_osc2",
>>> + "cpr1_ring_osc3",
>>> + "cpr1_ring_osc4";
>>> + };
>>> +...
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver
2023-01-11 13:30 ` Konrad Dybcio
@ 2023-01-11 15:58 ` Dmitry Baryshkov
0 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2023-01-11 15:58 UTC (permalink / raw)
To: Konrad Dybcio, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: marijn.suijten, angelogioacchino.delregno,
AngeloGioacchino Del Regno, Rob Herring, Rob Herring,
Krzysztof Kozlowski, devicetree, linux-kernel
On 11/01/2023 15:30, Konrad Dybcio wrote:
>
>
> On 11.01.2023 03:18, Dmitry Baryshkov wrote:
>> On 10/01/2023 20:54, Konrad Dybcio wrote:
>>>
>>>
>>> On 10.01.2023 18:56, Konrad Dybcio wrote:
>>>> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>>
>>>> Add the bindings for the CPR3 driver to the documentation.
>>>>
>>>> Reviewed-by: Rob Herring <robh@kernel.org>
>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
>>>> [Konrad: Add type reference to acc-syscon; update AGdR's email]
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>>>> ---
>>> Need to add
>>>
>>> qcom,opp-oloop-vadj
>>> qcom,opp-cloop-vadj
>>
>> And note that at least for CPR3 they are different between fusing revisions. I see that for CPRh (esp. for 8998v2) they are the same, but this is not the case for 8996 (CPR3).
> If we both mean the "speed bin"-dependent values, the driver
> reads the fuse value but currently does nothing. My guess would
> be that Angelo omitted it, as - just like you pointed out - MSM8998
> (and SDM660 for that matter) don't really use it. I suppose I could
> take care of that in bindings by making this an array and handle it
> separately in a different patchset, as the per-revision values
> aren't *that much* different, and again aren't really of concern for
> the first round of supported SoCs.
No, there are two dimensions there: speed-bin and then cpr fusing_rev, see:
ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision",
&drv->fusing_rev);
While the speed bin determines overall SoC performance characteristics,
cpr_fuse_revision determines how we interpret the fuse values. E.g. on
msm8996 some of loop adjustment values depend on fusing_rev. I
interpreted this as 'the manufacturer could not decide on how to measure
things'. May be we can support only the latest fusing rev (like we do
for the SoC versions). But I can not guarantee that it would be enough.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
2023-01-10 17:56 ` [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened Konrad Dybcio
2023-01-10 18:27 ` Robert Marko
@ 2023-01-11 20:43 ` kernel test robot
1 sibling, 0 replies; 17+ messages in thread
From: kernel test robot @ 2023-01-11 20:43 UTC (permalink / raw)
To: Konrad Dybcio, linux-arm-msm, andersson, agross, krzysztof.kozlowski
Cc: oe-kbuild-all, marijn.suijten, angelogioacchino.delregno,
Konrad Dybcio, AngeloGioacchino Del Regno, Liam Girdwood,
Mark Brown, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2175 bytes --]
Hi Konrad,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on next-20230110]
[cannot apply to robh/for-next linus/master v6.2-rc3 v6.2-rc2 v6.2-rc1 v6.2-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Konrad-Dybcio/dt-bindings-opp-v2-qcom-level-Let-qcom-opp-fuse-level-be-a-2-long-array/20230111-025647
patch link: https://lore.kernel.org/r/20230110175605.1240188-5-konrad.dybcio%40linaro.org
patch subject: [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened
config: arm-allyesconfig
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/d013cdd7c59750e5193932725b5231c196a95433
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Konrad-Dybcio/dt-bindings-opp-v2-qcom-level-Let-qcom-opp-fuse-level-be-a-2-long-array/20230111-025647
git checkout d013cdd7c59750e5193932725b5231c196a95433
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/soc/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> drivers/soc/qcom/cpr3.c:30:10: fatal error: soc/qcom/cpr.h: No such file or directory
30 | #include <soc/qcom/cpr.h>
| ^~~~~~~~~~~~~~~~
compilation terminated.
vim +30 drivers/soc/qcom/cpr3.c
> 30 #include <soc/qcom/cpr.h>
31
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
[-- Attachment #2: config --]
[-- Type: text/plain, Size: 362760 bytes --]
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 6.2.0-rc3 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="arm-linux-gnueabi-gcc (GCC) 12.1.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=120100
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23800
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23800
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_WATCH_QUEUE=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_USELIB=y
CONFIG_AUDIT=y
#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_GENERIC_IRQ_INJECTION=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_SIM=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
CONFIG_GENERIC_IRQ_IPI=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_IRQ_DEBUGFS=y
# end of IRQ subsystem
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_TIME_KUNIT_TEST=y
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
# CONFIG_NO_HZ_FULL is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem
CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y
#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_USERMODE_DRIVER=y
CONFIG_BPF_LSM=y
# end of BPF subsystem
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_COUNT=y
CONFIG_SCHED_CORE=y
#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_SCHED_AVG_IRQ=y
CONFIG_SCHED_THERMAL_PRESSURE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=y
# end of CPU/Task time and stats accounting
CONFIG_CPU_ISOLATION=y
#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
CONFIG_RCU_EXPERT=y
CONFIG_TREE_SRCU=y
CONFIG_NEED_SRCU_NMI_SAFE=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_FORCE_TASKS_RCU=y
CONFIG_TASKS_RCU=y
CONFIG_FORCE_TASKS_RUDE_RCU=y
CONFIG_TASKS_RUDE_RCU=y
CONFIG_FORCE_TASKS_TRACE_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=2
CONFIG_RCU_NOCB_CPU=y
CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y
CONFIG_TASKS_TRACE_RCU_READ_MB=y
CONFIG_RCU_LAZY=y
# end of RCU Subsystem
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_PRINTK_INDEX=y
CONFIG_GENERIC_SCHED_CLOCK=y
#
# Scheduler features
#
CONFIG_UCLAMP_TASK=y
CONFIG_UCLAMP_BUCKETS_COUNT=5
# end of Scheduler features
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_CGROUPS=y
CONFIG_PAGE_COUNTER=y
CONFIG_CGROUP_FAVOR_DYNMODS=y
CONFIG_MEMCG=y
CONFIG_MEMCG_KMEM=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_MM_CID=y
CONFIG_UCLAMP_TASK_GROUP=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
CONFIG_CGROUP_DEBUG=y
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_RD_ZSTD=y
CONFIG_BOOT_CONFIG=y
CONFIG_BOOT_CONFIG_FORCE=y
CONFIG_BOOT_CONFIG_EMBED=y
CONFIG_BOOT_CONFIG_EMBED_FILE=""
CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
CONFIG_SYSCTL=y
CONFIG_HAVE_UID16=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_SELFTEST=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_KCMP=y
CONFIG_RSEQ=y
CONFIG_DEBUG_RSEQ=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PC104=y
#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_DEBUG_PERF_USE_VMALLOC=y
# end of Kernel Performance Events And Counters
CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
# end of General setup
CONFIG_ARM=y
CONFIG_ARM_DMA_USE_IOMMU=y
CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_HAVE_TCM=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_NO_IOPORT_MAP=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_ARCH_HAS_BANDGAP=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIQ=y
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_GENERIC_BUG=y
CONFIG_PGTABLE_LEVELS=2
#
# System Type
#
CONFIG_MMU=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_BITS_MAX=16
CONFIG_ARCH_MULTIPLATFORM=y
#
# Platform selection
#
#
# CPU Core family selection
#
CONFIG_ARCH_MULTI_V6=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MULTI_V6_V7=y
# end of Platform selection
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_ACTIONS=y
CONFIG_ARCH_ALPINE=y
CONFIG_ARCH_ARTPEC=y
CONFIG_MACH_ARTPEC6=y
CONFIG_ARCH_ASPEED=y
CONFIG_MACH_ASPEED_G5=y
CONFIG_MACH_ASPEED_G6=y
CONFIG_ARCH_AT91=y
CONFIG_SOC_SAMA5D2=y
CONFIG_SOC_SAMA5D3=y
CONFIG_SOC_SAMA5D4=y
CONFIG_SOC_SAMA7G5=y
CONFIG_SOC_LAN966=y
#
# Clocksource driver selection
#
CONFIG_ATMEL_CLOCKSOURCE_PIT=y
CONFIG_ATMEL_CLOCKSOURCE_TCB=y
CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y
CONFIG_HAVE_AT91_UTMI=y
CONFIG_HAVE_AT91_USB_CLK=y
CONFIG_COMMON_CLK_AT91=y
CONFIG_HAVE_AT91_SMD=y
CONFIG_HAVE_AT91_H32MX=y
CONFIG_HAVE_AT91_GENERATED_CLK=y
CONFIG_HAVE_AT91_AUDIO_PLL=y
CONFIG_HAVE_AT91_I2S_MUX_CLK=y
CONFIG_HAVE_AT91_SAM9X60_PLL=y
CONFIG_SOC_SAM_V7=y
CONFIG_SOC_SAMA5=y
CONFIG_ATMEL_PM=y
CONFIG_ATMEL_SECURE_PM=y
CONFIG_SOC_SAMA7=y
CONFIG_ARCH_BCM=y
#
# IPROC architected SoCs
#
CONFIG_ARCH_BCM_IPROC=y
CONFIG_ARCH_BCM_CYGNUS=y
CONFIG_ARCH_BCM_HR2=y
CONFIG_ARCH_BCM_NSP=y
CONFIG_ARCH_BCM_5301X=y
#
# KONA architected SoCs
#
CONFIG_ARCH_BCM_MOBILE=y
CONFIG_ARCH_BCM_281XX=y
CONFIG_ARCH_BCM_21664=y
CONFIG_ARCH_BCM_23550=y
CONFIG_ARCH_BCM_MOBILE_L2_CACHE=y
CONFIG_ARCH_BCM_MOBILE_SMC=y
CONFIG_ARCH_BCM_MOBILE_SMP=y
#
# Other Architectures
#
CONFIG_ARCH_BCM2835=y
CONFIG_ARCH_BCM_53573=y
CONFIG_ARCH_BRCMSTB=y
CONFIG_ARCH_BCMBCA=y
#
# BCMBCA sub platforms
#
CONFIG_ARCH_BCMBCA_CORTEXA7=y
CONFIG_ARCH_BCMBCA_CORTEXA9=y
CONFIG_ARCH_BCMBCA_BRAHMAB15=y
CONFIG_ARCH_BERLIN=y
CONFIG_MACH_BERLIN_BG2=y
CONFIG_MACH_BERLIN_BG2CD=y
CONFIG_MACH_BERLIN_BG2Q=y
CONFIG_ARCH_DIGICOLOR=y
CONFIG_ARCH_DOVE=y
CONFIG_DOVE_LEGACY=y
CONFIG_MACH_CM_A510=y
CONFIG_ARCH_EXYNOS=y
CONFIG_S5P_DEV_MFC=y
CONFIG_ARCH_EXYNOS3=y
CONFIG_ARCH_EXYNOS4=y
CONFIG_ARCH_EXYNOS5=y
#
# Exynos SoCs
#
CONFIG_SOC_EXYNOS3250=y
CONFIG_CPU_EXYNOS4210=y
CONFIG_SOC_EXYNOS4412=y
CONFIG_SOC_EXYNOS5250=y
CONFIG_SOC_EXYNOS5260=y
CONFIG_SOC_EXYNOS5410=y
CONFIG_SOC_EXYNOS5420=y
CONFIG_SOC_EXYNOS5800=y
CONFIG_EXYNOS_MCPM=y
CONFIG_EXYNOS_CPU_SUSPEND=y
CONFIG_ARCH_HIGHBANK=y
CONFIG_ARCH_HISI=y
#
# Hisilicon platform type
#
CONFIG_ARCH_HI3xxx=y
CONFIG_ARCH_HIP01=y
CONFIG_ARCH_HIP04=y
CONFIG_ARCH_HIX5HD2=y
# end of Hisilicon platform type
CONFIG_ARCH_HPE=y
CONFIG_ARCH_HPE_GXP=y
CONFIG_ARCH_MXC=y
CONFIG_MXC_TZIC=y
CONFIG_MXC_AVIC=y
CONFIG_HAVE_IMX_ANATOP=y
CONFIG_HAVE_IMX_GPC=y
CONFIG_HAVE_IMX_MMDC=y
CONFIG_HAVE_IMX_SRC=y
#
# ARM1136 platforms
#
CONFIG_SOC_IMX31=y
CONFIG_SOC_IMX35=y
#
# Cortex-A platforms
#
CONFIG_SOC_IMX5=y
CONFIG_SOC_IMX50=y
CONFIG_SOC_IMX51=y
CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
CONFIG_SOC_IMX6SLL=y
CONFIG_SOC_IMX6SX=y
CONFIG_SOC_IMX6UL=y
CONFIG_SOC_LS1021A=y
#
# Cortex-A/Cortex-M asymmetric multiprocessing platforms
#
CONFIG_SOC_IMX7D_CA7=y
CONFIG_SOC_IMX7D=y
CONFIG_SOC_IMX7ULP=y
CONFIG_SOC_VF610=y
CONFIG_VF_USE_ARM_GLOBAL_TIMER=y
# CONFIG_VF_USE_PIT_TIMER is not set
CONFIG_ARCH_KEYSTONE=y
CONFIG_ARCH_MEDIATEK=y
CONFIG_MACH_MT2701=y
CONFIG_MACH_MT6589=y
CONFIG_MACH_MT6592=y
CONFIG_MACH_MT7623=y
CONFIG_MACH_MT7629=y
CONFIG_MACH_MT8127=y
CONFIG_MACH_MT8135=y
CONFIG_ARCH_MESON=y
CONFIG_MACH_MESON6=y
CONFIG_MACH_MESON8=y
CONFIG_ARCH_MILBEAUT=y
CONFIG_ARCH_MILBEAUT_M10V=y
CONFIG_ARCH_MMP=y
#
# Marvell PXA168/910/MMP2 Implementations
#
CONFIG_MACH_MMP2_DT=y
CONFIG_MACH_MMP3_DT=y
# end of Marvell PXA168/910/MMP2 Implementations
CONFIG_USB_EHCI_MV_U2O=y
CONFIG_ARCH_MSTARV7=y
CONFIG_MACH_INFINITY=y
CONFIG_MACH_MERCURY=y
CONFIG_ARCH_MVEBU=y
CONFIG_MACH_MVEBU_ANY=y
CONFIG_MACH_MVEBU_V7=y
CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_375=y
CONFIG_MACH_ARMADA_38X=y
CONFIG_MACH_ARMADA_39X=y
CONFIG_MACH_ARMADA_XP=y
CONFIG_MACH_DOVE=y
CONFIG_ARCH_NPCM=y
CONFIG_ARCH_NPCM7XX=y
CONFIG_ARCH_OMAP=y
#
# TI OMAP/AM/DM/DRA Family
#
CONFIG_OMAP_HWMOD=y
CONFIG_ARCH_OMAP2=y
CONFIG_ARCH_OMAP3=y
CONFIG_ARCH_OMAP4=y
CONFIG_SOC_OMAP5=y
CONFIG_SOC_AM33XX=y
CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARCH_OMAP2PLUS=y
CONFIG_OMAP_INTERCONNECT_BARRIER=y
#
# TI OMAP2/3/4 Specific Features
#
CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
CONFIG_SOC_HAS_OMAP2_SDRC=y
CONFIG_SOC_HAS_REALTIME_COUNTER=y
CONFIG_POWER_AVS_OMAP=y
CONFIG_POWER_AVS_OMAP_CLASS3=y
CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE=y
CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID=43
#
# OMAP Core Type
#
CONFIG_SOC_OMAP2420=y
CONFIG_SOC_OMAP2430=y
CONFIG_SOC_OMAP3430=y
CONFIG_SOC_TI81XX=y
#
# OMAP Legacy Platform Data Board Type
#
CONFIG_MACH_OMAP_GENERIC=y
CONFIG_MACH_OMAP2_TUSB6010=y
CONFIG_MACH_NOKIA_N810=y
CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
CONFIG_OMAP3_SDRC_AC_TIMING=y
# end of TI OMAP2/3/4 Specific Features
CONFIG_OMAP5_ERRATA_801819=y
# end of TI OMAP/AM/DM/DRA Family
CONFIG_ARCH_OXNAS=y
CONFIG_MACH_OX820=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_IPQ40XX=y
CONFIG_ARCH_MSM8X60=y
CONFIG_ARCH_MSM8909=y
CONFIG_ARCH_MSM8916=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8974=y
CONFIG_ARCH_MDM9615=y
CONFIG_ARCH_RDA=y
CONFIG_ARCH_REALTEK=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_S3C64XX=y
CONFIG_CPU_S3C6400=y
CONFIG_CPU_S3C6410=y
CONFIG_S3C64XX_PL080=y
CONFIG_S3C64XX_SETUP_SDHCI=y
CONFIG_S3C64XX_SETUP_I2C0=y
CONFIG_S3C64XX_SETUP_I2C1=y
CONFIG_S3C64XX_SETUP_IDE=y
CONFIG_S3C64XX_SETUP_FB_24BPP=y
CONFIG_S3C64XX_SETUP_KEYPAD=y
CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y
CONFIG_S3C64XX_SETUP_SPI=y
CONFIG_S3C64XX_SETUP_USB_PHY=y
CONFIG_MACH_WLF_CRAGG_6410=y
CONFIG_MACH_S3C64XX_DT=y
CONFIG_PLAT_SAMSUNG=y
CONFIG_SAMSUNG_PM=y
#
# Samsung Common options
#
#
# Boot options
#
CONFIG_S3C_LOWLEVEL_UART_PORT=0
CONFIG_SAMSUNG_ATAGS=y
CONFIG_S3C_GPIO_SPACE=0
CONFIG_S3C_GPIO_TRACK=y
CONFIG_S3C_DEV_HSMMC=y
CONFIG_S3C_DEV_HSMMC1=y
CONFIG_S3C_DEV_HSMMC2=y
CONFIG_S3C_DEV_I2C1=y
CONFIG_S3C_DEV_FB=y
CONFIG_S3C_DEV_USB_HOST=y
CONFIG_S3C_DEV_USB_HSOTG=y
CONFIG_S3C64XX_DEV_SPI0=y
CONFIG_SAMSUNG_DEV_KEYPAD=y
CONFIG_SAMSUNG_DEV_PWM=y
CONFIG_GPIO_SAMSUNG=y
CONFIG_SAMSUNG_PM_GPIO=y
CONFIG_SAMSUNG_WAKEMASK=y
# end of Samsung Common options
CONFIG_ARCH_S5PV210=y
CONFIG_CPU_S5PV210=y
CONFIG_ARCH_RENESAS=y
CONFIG_ARCH_INTEL_SOCFPGA=y
CONFIG_SOCFPGA_SUSPEND=y
CONFIG_PLAT_SPEAR=y
CONFIG_ARCH_SPEAR13XX=y
CONFIG_MACH_SPEAR1310=y
CONFIG_MACH_SPEAR1340=y
CONFIG_ARCH_STI=y
CONFIG_SOC_STIH415=y
CONFIG_SOC_STIH416=y
CONFIG_SOC_STIH407=y
CONFIG_ARCH_STM32=y
CONFIG_MACH_STM32MP157=y
CONFIG_MACH_STM32MP13=y
CONFIG_ARCH_SUNPLUS=y
CONFIG_SOC_SP7021=y
CONFIG_ARCH_SUNXI=y
CONFIG_MACH_SUN4I=y
CONFIG_MACH_SUN5I=y
CONFIG_MACH_SUN6I=y
CONFIG_MACH_SUN7I=y
CONFIG_MACH_SUN8I=y
CONFIG_MACH_SUN9I=y
CONFIG_ARCH_SUNXI_MC_SMP=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_UNIPHIER=y
CONFIG_ARCH_U8500=y
CONFIG_UX500_SOC_DB8500=y
CONFIG_UX500_DEBUG_UART=2
CONFIG_ARCH_INTEGRATOR=y
CONFIG_ARCH_INTEGRATOR_AP=y
CONFIG_INTEGRATOR_IMPD1=y
CONFIG_INTEGRATOR_CM1136JFS=y
CONFIG_ARCH_INTEGRATOR_CP=y
CONFIG_INTEGRATOR_CTB36=y
CONFIG_ARCH_CINTEGRATOR=y
CONFIG_ARCH_REALVIEW=y
CONFIG_MACH_REALVIEW_EB=y
CONFIG_REALVIEW_EB_ARM1136=y
CONFIG_REALVIEW_EB_ARM1176=y
CONFIG_REALVIEW_EB_A9MP=y
CONFIG_REALVIEW_EB_ARM11MP=y
CONFIG_MACH_REALVIEW_PB11MP=y
CONFIG_MACH_REALVIEW_PB1176=y
CONFIG_MACH_REALVIEW_PBA8=y
CONFIG_MACH_REALVIEW_PBX=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
CONFIG_ARCH_VEXPRESS_DCSCB=y
CONFIG_ARCH_VEXPRESS_SPC=y
CONFIG_ARCH_VEXPRESS_TC2_PM=y
CONFIG_ARCH_VT8500=y
CONFIG_ARCH_WM8750=y
CONFIG_ARCH_WM8850=y
CONFIG_ARCH_ZYNQ=y
CONFIG_PLAT_ORION=y
CONFIG_PLAT_ORION_LEGACY=y
CONFIG_PLAT_VERSATILE=y
#
# Processor Type
#
CONFIG_CPU_PJ4=y
CONFIG_CPU_PJ4B=y
CONFIG_CPU_V6=y
CONFIG_CPU_V6K=y
CONFIG_CPU_V7=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_32v6=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV6=y
CONFIG_CPU_ABRT_EV7=y
CONFIG_CPU_PABRT_V6=y
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_CACHE_V6=y
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_TLB_V6=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_HAS_ASID=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
CONFIG_ARM_THUMB=y
CONFIG_ARM_THUMBEE=y
CONFIG_ARM_VIRT_EXT=y
CONFIG_SWP_EMULATE=y
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_ICACHE_DISABLE=y
CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND=y
CONFIG_CPU_BPREDICT_DISABLE=y
CONFIG_CPU_SPECTRE=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDEN_BRANCH_HISTORY=y
CONFIG_KUSER_HELPERS=y
CONFIG_VDSO=y
CONFIG_DMA_CACHE_RWFO=y
CONFIG_OUTER_CACHE=y
CONFIG_OUTER_CACHE_SYNC=y
CONFIG_CACHE_B15_RAC=y
CONFIG_CACHE_FEROCEON_L2=y
CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_CACHE_L2X0=y
CONFIG_CACHE_L2X0_PMU=y
CONFIG_PL310_ERRATA_588369=y
CONFIG_PL310_ERRATA_727915=y
CONFIG_PL310_ERRATA_753970=y
CONFIG_PL310_ERRATA_769419=y
CONFIG_CACHE_TAUROS2=y
CONFIG_CACHE_UNIPHIER=y
CONFIG_ARM_L1_CACHE_SHIFT_6=y
CONFIG_ARM_L1_CACHE_SHIFT_7=y
CONFIG_ARM_L1_CACHE_SHIFT=7
CONFIG_ARM_DMA_MEM_BUFFERABLE=y
CONFIG_ARM_HEAVY_MB=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_IWMMXT=y
CONFIG_PJ4B_ERRATA_4742=y
CONFIG_ARM_ERRATA_326103=y
CONFIG_ARM_ERRATA_411920=y
CONFIG_ARM_ERRATA_430973=y
CONFIG_ARM_ERRATA_643719=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_754327=y
CONFIG_ARM_ERRATA_364296=y
CONFIG_ARM_ERRATA_764369=y
CONFIG_ARM_ERRATA_764319=y
CONFIG_ARM_ERRATA_775420=y
CONFIG_ARM_ERRATA_798181=y
CONFIG_ARM_ERRATA_773022=y
CONFIG_ARM_ERRATA_818325_852422=y
CONFIG_ARM_ERRATA_821420=y
CONFIG_ARM_ERRATA_825619=y
CONFIG_ARM_ERRATA_857271=y
CONFIG_ARM_ERRATA_852421=y
CONFIG_ARM_ERRATA_852423=y
CONFIG_ARM_ERRATA_857272=y
# end of System Type
CONFIG_KRAIT_L2_ACCESSORS=y
#
# Bus support
#
CONFIG_ARM_ERRATA_814220=y
# end of Bus support
#
# Kernel Features
#
CONFIG_HAVE_SMP=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_IRQSTACKS=y
CONFIG_ARM_CPU_TOPOLOGY=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_HAVE_ARM_SCU=y
CONFIG_HAVE_ARM_ARCH_TIMER=y
CONFIG_HAVE_ARM_TWD=y
CONFIG_MCPM=y
CONFIG_MCPM_QUAD_CLUSTER=y
CONFIG_BIG_LITTLE=y
CONFIG_BL_SWITCHER=y
CONFIG_BL_SWITCHER_DUMMY_IF=y
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
CONFIG_ARM_PSCI=y
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
# CONFIG_HZ_200 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_500 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
CONFIG_ARM_PATCH_IDIV=y
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_CPU_SW_DOMAIN_PAN=y
CONFIG_HW_PERF_EVENTS=y
CONFIG_ARM_MODULE_PLTS=y
CONFIG_ARCH_FORCE_MAX_ORDER=12
CONFIG_ALIGNMENT_TRAP=y
CONFIG_UACCESS_WITH_MEMCPY=y
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_TIME_ACCOUNTING=y
CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
# end of Kernel Features
#
# Boot options
#
CONFIG_USE_OF=y
CONFIG_ATAGS=y
CONFIG_DEPRECATED_PARAM_STRUCT=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
CONFIG_CMDLINE=""
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
CONFIG_CRASH_DUMP=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_EFI_STUB=y
CONFIG_EFI=y
CONFIG_DMI=y
# end of Boot options
#
# CPU Power Management
#
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
#
# CPU frequency scaling drivers
#
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=y
CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
CONFIG_ARM_ARMADA_8K_CPUFREQ=y
CONFIG_ARM_SCPI_CPUFREQ=y
CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y
CONFIG_ARM_BRCMSTB_AVS_CPUFREQ=y
CONFIG_ARM_HIGHBANK_CPUFREQ=y
CONFIG_ARM_IMX6Q_CPUFREQ=y
CONFIG_ARM_IMX_CPUFREQ_DT=y
CONFIG_ARM_MEDIATEK_CPUFREQ=y
CONFIG_ARM_MEDIATEK_CPUFREQ_HW=y
CONFIG_ARM_OMAP2PLUS_CPUFREQ=y
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
CONFIG_ARM_QCOM_CPUFREQ_HW=y
CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
CONFIG_ARM_S3C64XX_CPUFREQ=y
CONFIG_ARM_S5PV210_CPUFREQ=y
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ARM_SPEAR_CPUFREQ=y
CONFIG_ARM_STI_CPUFREQ=y
CONFIG_ARM_TEGRA20_CPUFREQ=y
CONFIG_ARM_TEGRA124_CPUFREQ=y
CONFIG_ARM_TEGRA186_CPUFREQ=y
CONFIG_ARM_TI_CPUFREQ=y
CONFIG_QORIQ_CPUFREQ=y
# end of CPU Frequency scaling
#
# CPU Idle
#
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_GOV_TEO=y
CONFIG_DT_IDLE_STATES=y
CONFIG_DT_IDLE_GENPD=y
#
# ARM CPU Idle Drivers
#
CONFIG_ARM_CPUIDLE=y
CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
CONFIG_ARM_CLPS711X_CPUIDLE=y
CONFIG_ARM_HIGHBANK_CPUIDLE=y
CONFIG_ARM_KIRKWOOD_CPUIDLE=y
CONFIG_ARM_ZYNQ_CPUIDLE=y
CONFIG_ARM_U8500_CPUIDLE=y
CONFIG_ARM_AT91_CPUIDLE=y
CONFIG_ARM_EXYNOS_CPUIDLE=y
CONFIG_ARM_MVEBU_V7_CPUIDLE=y
CONFIG_ARM_TEGRA_CPUIDLE=y
CONFIG_ARM_QCOM_SPM_CPUIDLE=y
# end of ARM CPU Idle Drivers
CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
# end of CPU Idle
# end of CPU Power Management
#
# Floating point emulation
#
#
# At least one emulation must be selected
#
CONFIG_FPE_NWFPE=y
CONFIG_FPE_NWFPE_XP=y
CONFIG_FPE_FASTFPE=y
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
# end of Floating point emulation
#
# Power management options
#
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SUSPEND_SKIP_SYNC=y
CONFIG_HIBERNATE_CALLBACKS=y
CONFIG_HIBERNATION=y
CONFIG_HIBERNATION_SNAPSHOT_DEV=y
CONFIG_PM_STD_PARTITION=""
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_USERSPACE_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y
CONFIG_PM_SLEEP_DEBUG=y
CONFIG_DPM_WATCHDOG=y
CONFIG_DPM_WATCHDOG_TIMEOUT=120
CONFIG_APM_EMULATION=y
CONFIG_PM_CLK=y
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_CPU_PM=y
CONFIG_ENERGY_MODEL=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# end of Power management options
CONFIG_AS_VFP_VMRS_FPINST=y
#
# General architecture-dependent options
#
CONFIG_CRASH_CORE=y
CONFIG_KEXEC_CORE=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_OPTPROBES=y
CONFIG_UPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_KEEPINITRD=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_SECCOMP=y
CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_LTO_NONE=y
CONFIG_HAVE_CONTEXT_TRACKING_USER=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS=8
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
CONFIG_ISA_BUS_API=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_STRICT_MODULE_RWX=y
CONFIG_LOCK_EVENT_COUNTS=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_HAVE_ARCH_PFN_VALID=y
#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling
CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
CONFIG_FUNCTION_ALIGNMENT=0
# end of General architecture-dependent options
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
CONFIG_MODULE_SIG_SHA1=y
# CONFIG_MODULE_SIG_SHA224 is not set
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
# CONFIG_MODULE_SIG_SHA512 is not set
CONFIG_MODULE_SIG_HASH="sha1"
CONFIG_MODULE_COMPRESS_NONE=y
# CONFIG_MODULE_COMPRESS_GZIP is not set
# CONFIG_MODULE_COMPRESS_XZ is not set
# CONFIG_MODULE_COMPRESS_ZSTD is not set
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
CONFIG_MODPROBE_PATH="/sbin/modprobe"
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
CONFIG_BLK_RQ_ALLOC_TIME=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_ICQ=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_INTEGRITY_T10=y
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_DEV_THROTTLING_LOW=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_FC_APPID=y
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_DEBUG_FS_ZONED=y
CONFIG_BLK_SED_OPAL=y
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_AIX_PARTITION=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_CMDLINE_PARTITION=y
# end of Partition Types
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_MQ_RDMA=y
CONFIG_BLK_PM=y
CONFIG_BLOCK_HOLDER_DEPRECATED=y
CONFIG_BLK_MQ_STACKING=y
#
# IO Schedulers
#
CONFIG_MQ_IOSCHED_DEADLINE=y
CONFIG_MQ_IOSCHED_KYBER=y
CONFIG_IOSCHED_BFQ=y
CONFIG_BFQ_GROUP_IOSCHED=y
CONFIG_BFQ_CGROUP_DEBUG=y
# end of IO Schedulers
CONFIG_PADATA=y
CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_FREEZER=y
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_ELF_KUNIT_TEST=y
CONFIG_BINFMT_ELF_FDPIC=y
CONFIG_ELFCORE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_ARCH_HAS_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
CONFIG_BINFMT_FLAT_OLD=y
CONFIG_BINFMT_ZFLAT=y
CONFIG_BINFMT_MISC=y
CONFIG_COREDUMP=y
# end of Executable file formats
#
# Memory Management options
#
CONFIG_ZPOOL=y
CONFIG_SWAP=y
CONFIG_ZSWAP=y
CONFIG_ZSWAP_DEFAULT_ON=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo"
CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud"
CONFIG_ZBUD=y
CONFIG_Z3FOLD=y
CONFIG_ZSMALLOC=y
CONFIG_ZSMALLOC_STAT=y
#
# SLAB allocator options
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB_DEPRECATED is not set
CONFIG_SLUB_TINY=y
CONFIG_SLAB_MERGE_DEFAULT=y
# end of SLAB allocator options
CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
CONFIG_COMPAT_BRK=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_MEMORY_BALLOON=y
CONFIG_BALLOON_COMPACTION=y
CONFIG_COMPACTION=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_PAGE_REPORTING=y
CONFIG_MIGRATION=y
CONFIG_CONTIG_ALLOC=y
CONFIG_BOUNCE=y
CONFIG_MMU_NOTIFIER=y
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_FRONTSWAP=y
CONFIG_CMA=y
CONFIG_CMA_DEBUG=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_SYSFS=y
CONFIG_CMA_AREAS=7
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_PAGE_IDLE_FLAG=y
CONFIG_IDLE_PAGE_TRACKING=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_ZONE_DMA=y
CONFIG_HMM_MIRROR=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
CONFIG_GUP_TEST=y
CONFIG_KMAP_LOCAL=y
CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
CONFIG_ANON_VMA_NAME=y
CONFIG_USERFAULTFD=y
CONFIG_LRU_GEN=y
CONFIG_LRU_GEN_ENABLED=y
CONFIG_LRU_GEN_STATS=y
#
# Data Access Monitoring
#
CONFIG_DAMON=y
CONFIG_DAMON_KUNIT_TEST=y
CONFIG_DAMON_VADDR=y
CONFIG_DAMON_PADDR=y
CONFIG_DAMON_VADDR_KUNIT_TEST=y
CONFIG_DAMON_SYSFS=y
CONFIG_DAMON_DBGFS=y
CONFIG_DAMON_DBGFS_KUNIT_TEST=y
CONFIG_DAMON_RECLAIM=y
CONFIG_DAMON_LRU_SORT=y
# end of Data Access Monitoring
# end of Memory Management options
CONFIG_NET=y
CONFIG_NET_INGRESS=y
CONFIG_NET_EGRESS=y
CONFIG_NET_REDIRECT=y
CONFIG_SKB_EXTENSIONS=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_SCM=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=y
CONFIG_TLS=y
CONFIG_TLS_DEVICE=y
CONFIG_TLS_TOE=y
CONFIG_XFRM=y
CONFIG_XFRM_OFFLOAD=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_INTERFACE=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_AH=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_XFRM_ESPINTCP=y
CONFIG_SMC=y
CONFIG_SMC_DIAG=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_ROUTE_CLASSID=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_NET_IP_TUNNEL=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE_COMMON=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=y
CONFIG_NET_UDP_TUNNEL=y
CONFIG_NET_FOU=y
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_ESP_OFFLOAD=y
CONFIG_INET_ESPINTCP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_TABLE_PERTURB_ORDER=16
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_INET_UDP_DIAG=y
CONFIG_INET_RAW_DIAG=y
CONFIG_INET_DIAG_DESTROY=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_TCP_CONG_WESTWOOD=y
CONFIG_TCP_CONG_HTCP=y
CONFIG_TCP_CONG_HSTCP=y
CONFIG_TCP_CONG_HYBLA=y
CONFIG_TCP_CONG_VEGAS=y
CONFIG_TCP_CONG_NV=y
CONFIG_TCP_CONG_SCALABLE=y
CONFIG_TCP_CONG_LP=y
CONFIG_TCP_CONG_VENO=y
CONFIG_TCP_CONG_YEAH=y
CONFIG_TCP_CONG_ILLINOIS=y
CONFIG_TCP_CONG_DCTCP=y
CONFIG_TCP_CONG_CDG=y
CONFIG_TCP_CONG_BBR=y
# CONFIG_DEFAULT_BIC is not set
CONFIG_DEFAULT_CUBIC=y
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_HYBLA is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_VENO is not set
# CONFIG_DEFAULT_WESTWOOD is not set
# CONFIG_DEFAULT_DCTCP is not set
# CONFIG_DEFAULT_CDG is not set
# CONFIG_DEFAULT_BBR is not set
# CONFIG_DEFAULT_RENO is not set
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_ESP_OFFLOAD=y
CONFIG_INET6_ESPINTCP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_ILA=y
CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
CONFIG_IPV6_VTI=y
CONFIG_IPV6_SIT=y
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_GRE=y
CONFIG_IPV6_FOU=y
CONFIG_IPV6_FOU_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
CONFIG_IPV6_SEG6_BPF=y
CONFIG_IPV6_RPL_LWTUNNEL=y
CONFIG_IPV6_IOAM6_LWTUNNEL=y
CONFIG_NETLABEL=y
CONFIG_MPTCP=y
CONFIG_INET_MPTCP_DIAG=y
CONFIG_MPTCP_IPV6=y
CONFIG_MPTCP_KUNIT_TEST=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_EGRESS=y
CONFIG_NETFILTER_SKIP_EGRESS=y
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
CONFIG_NETFILTER_NETLINK_HOOK=y
CONFIG_NETFILTER_NETLINK_ACCT=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NETFILTER_NETLINK_OSF=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_LOG_SYSLOG=y
CONFIG_NETFILTER_CONNCOUNT=y
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_LABELS=y
CONFIG_NF_CT_PROTO_DCCP=y
CONFIG_NF_CT_PROTO_GRE=y
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_NF_CT_PROTO_UDPLITE=y
CONFIG_NF_CONNTRACK_AMANDA=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_CONNTRACK_H323=y
CONFIG_NF_CONNTRACK_IRC=y
CONFIG_NF_CONNTRACK_BROADCAST=y
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
CONFIG_NF_CONNTRACK_SNMP=y
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SANE=y
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
CONFIG_NF_CT_NETLINK_TIMEOUT=y
CONFIG_NF_CT_NETLINK_HELPER=y
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_NAT=y
CONFIG_NF_NAT_AMANDA=y
CONFIG_NF_NAT_FTP=y
CONFIG_NF_NAT_IRC=y
CONFIG_NF_NAT_SIP=y
CONFIG_NF_NAT_TFTP=y
CONFIG_NF_NAT_REDIRECT=y
CONFIG_NF_NAT_MASQUERADE=y
CONFIG_NF_NAT_OVS=y
CONFIG_NETFILTER_SYNPROXY=y
CONFIG_NF_TABLES=y
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=y
CONFIG_NFT_CT=y
CONFIG_NFT_FLOW_OFFLOAD=y
CONFIG_NFT_CONNLIMIT=y
CONFIG_NFT_LOG=y
CONFIG_NFT_LIMIT=y
CONFIG_NFT_MASQ=y
CONFIG_NFT_REDIR=y
CONFIG_NFT_NAT=y
CONFIG_NFT_TUNNEL=y
CONFIG_NFT_QUEUE=y
CONFIG_NFT_QUOTA=y
CONFIG_NFT_REJECT=y
CONFIG_NFT_REJECT_INET=y
CONFIG_NFT_COMPAT=y
CONFIG_NFT_HASH=y
CONFIG_NFT_FIB=y
CONFIG_NFT_FIB_INET=y
CONFIG_NFT_XFRM=y
CONFIG_NFT_SOCKET=y
CONFIG_NFT_OSF=y
CONFIG_NFT_TPROXY=y
CONFIG_NFT_SYNPROXY=y
CONFIG_NF_DUP_NETDEV=y
CONFIG_NFT_DUP_NETDEV=y
CONFIG_NFT_FWD_NETDEV=y
CONFIG_NFT_FIB_NETDEV=y
CONFIG_NFT_REJECT_NETDEV=y
CONFIG_NF_FLOW_TABLE_INET=y
CONFIG_NF_FLOW_TABLE=y
CONFIG_NF_FLOW_TABLE_PROCFS=y
CONFIG_NETFILTER_XTABLES=y
#
# Xtables combined modules
#
CONFIG_NETFILTER_XT_MARK=y
CONFIG_NETFILTER_XT_CONNMARK=y
CONFIG_NETFILTER_XT_SET=y
#
# Xtables targets
#
CONFIG_NETFILTER_XT_TARGET_AUDIT=y
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_CT=y
CONFIG_NETFILTER_XT_TARGET_DSCP=y
CONFIG_NETFILTER_XT_TARGET_HL=y
CONFIG_NETFILTER_XT_TARGET_HMARK=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LED=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_NAT=y
CONFIG_NETFILTER_XT_TARGET_NETMAP=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
CONFIG_NETFILTER_XT_TARGET_RATEEST=y
CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=y
#
# Xtables matches
#
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_NETFILTER_XT_MATCH_CGROUP=y
CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_CPU=y
CONFIG_NETFILTER_XT_MATCH_DCCP=y
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ECN=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_HL=y
CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
CONFIG_NETFILTER_XT_MATCH_IPVS=y
CONFIG_NETFILTER_XT_MATCH_L2TP=y
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_NFACCT=y
CONFIG_NETFILTER_XT_MATCH_OSF=y
CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
CONFIG_NETFILTER_XT_MATCH_RATEEST=y
CONFIG_NETFILTER_XT_MATCH_REALM=y
CONFIG_NETFILTER_XT_MATCH_RECENT=y
CONFIG_NETFILTER_XT_MATCH_SCTP=y
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
# end of Core Netfilter Configuration
CONFIG_IP_SET=y
CONFIG_IP_SET_MAX=256
CONFIG_IP_SET_BITMAP_IP=y
CONFIG_IP_SET_BITMAP_IPMAC=y
CONFIG_IP_SET_BITMAP_PORT=y
CONFIG_IP_SET_HASH_IP=y
CONFIG_IP_SET_HASH_IPMARK=y
CONFIG_IP_SET_HASH_IPPORT=y
CONFIG_IP_SET_HASH_IPPORTIP=y
CONFIG_IP_SET_HASH_IPPORTNET=y
CONFIG_IP_SET_HASH_IPMAC=y
CONFIG_IP_SET_HASH_MAC=y
CONFIG_IP_SET_HASH_NETPORTNET=y
CONFIG_IP_SET_HASH_NET=y
CONFIG_IP_SET_HASH_NETNET=y
CONFIG_IP_SET_HASH_NETPORT=y
CONFIG_IP_SET_HASH_NETIFACE=y
CONFIG_IP_SET_LIST_SET=y
CONFIG_IP_VS=y
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler
#
CONFIG_IP_VS_RR=y
CONFIG_IP_VS_WRR=y
CONFIG_IP_VS_LC=y
CONFIG_IP_VS_WLC=y
CONFIG_IP_VS_FO=y
CONFIG_IP_VS_OVF=y
CONFIG_IP_VS_LBLC=y
CONFIG_IP_VS_LBLCR=y
CONFIG_IP_VS_DH=y
CONFIG_IP_VS_SH=y
CONFIG_IP_VS_MH=y
CONFIG_IP_VS_SED=y
CONFIG_IP_VS_NQ=y
CONFIG_IP_VS_TWOS=y
#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8
#
# IPVS MH scheduler
#
CONFIG_IP_VS_MH_TAB_INDEX=12
#
# IPVS application helper
#
CONFIG_IP_VS_FTP=y
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=y
#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=y
CONFIG_NF_SOCKET_IPV4=y
CONFIG_NF_TPROXY_IPV4=y
CONFIG_NF_TABLES_IPV4=y
CONFIG_NFT_REJECT_IPV4=y
CONFIG_NFT_DUP_IPV4=y
CONFIG_NFT_FIB_IPV4=y
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_DUP_IPV4=y
CONFIG_NF_LOG_ARP=y
CONFIG_NF_LOG_IPV4=y
CONFIG_NF_REJECT_IPV4=y
CONFIG_NF_NAT_SNMP_BASIC=y
CONFIG_NF_NAT_PPTP=y
CONFIG_NF_NAT_H323=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_SYNPROXY=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_TARGET_CLUSTERIP=y
CONFIG_IP_NF_TARGET_ECN=y
CONFIG_IP_NF_TARGET_TTL=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
# end of IP: Netfilter Configuration
#
# IPv6: Netfilter Configuration
#
CONFIG_NF_SOCKET_IPV6=y
CONFIG_NF_TPROXY_IPV6=y
CONFIG_NF_TABLES_IPV6=y
CONFIG_NFT_REJECT_IPV6=y
CONFIG_NFT_DUP_IPV6=y
CONFIG_NFT_FIB_IPV6=y
CONFIG_NF_DUP_IPV6=y
CONFIG_NF_REJECT_IPV6=y
CONFIG_NF_LOG_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_AH=y
CONFIG_IP6_NF_MATCH_EUI64=y
CONFIG_IP6_NF_MATCH_FRAG=y
CONFIG_IP6_NF_MATCH_OPTS=y
CONFIG_IP6_NF_MATCH_HL=y
CONFIG_IP6_NF_MATCH_IPV6HEADER=y
CONFIG_IP6_NF_MATCH_MH=y
CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_MATCH_RT=y
CONFIG_IP6_NF_MATCH_SRH=y
CONFIG_IP6_NF_TARGET_HL=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_TARGET_SYNPROXY=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
CONFIG_IP6_NF_SECURITY=y
CONFIG_IP6_NF_NAT=y
CONFIG_IP6_NF_TARGET_MASQUERADE=y
CONFIG_IP6_NF_TARGET_NPT=y
# end of IPv6: Netfilter Configuration
CONFIG_NF_DEFRAG_IPV6=y
CONFIG_NF_TABLES_BRIDGE=y
CONFIG_NFT_BRIDGE_META=y
CONFIG_NFT_BRIDGE_REJECT=y
CONFIG_NF_CONNTRACK_BRIDGE=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
CONFIG_BRIDGE_EBT_T_FILTER=y
CONFIG_BRIDGE_EBT_T_NAT=y
CONFIG_BRIDGE_EBT_802_3=y
CONFIG_BRIDGE_EBT_AMONG=y
CONFIG_BRIDGE_EBT_ARP=y
CONFIG_BRIDGE_EBT_IP=y
CONFIG_BRIDGE_EBT_IP6=y
CONFIG_BRIDGE_EBT_LIMIT=y
CONFIG_BRIDGE_EBT_MARK=y
CONFIG_BRIDGE_EBT_PKTTYPE=y
CONFIG_BRIDGE_EBT_STP=y
CONFIG_BRIDGE_EBT_VLAN=y
CONFIG_BRIDGE_EBT_ARPREPLY=y
CONFIG_BRIDGE_EBT_DNAT=y
CONFIG_BRIDGE_EBT_MARK_T=y
CONFIG_BRIDGE_EBT_REDIRECT=y
CONFIG_BRIDGE_EBT_SNAT=y
CONFIG_BRIDGE_EBT_LOG=y
CONFIG_BRIDGE_EBT_NFLOG=y
CONFIG_BPFILTER=y
CONFIG_IP_DCCP=y
CONFIG_INET_DCCP_DIAG=y
#
# DCCP CCIDs Configuration
#
CONFIG_IP_DCCP_CCID2_DEBUG=y
CONFIG_IP_DCCP_CCID3=y
CONFIG_IP_DCCP_CCID3_DEBUG=y
CONFIG_IP_DCCP_TFRC_LIB=y
CONFIG_IP_DCCP_TFRC_DEBUG=y
# end of DCCP CCIDs Configuration
#
# DCCP Kernel Hacking
#
CONFIG_IP_DCCP_DEBUG=y
# end of DCCP Kernel Hacking
CONFIG_IP_SCTP=y
CONFIG_SCTP_DBG_OBJCNT=y
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_SCTP_COOKIE_HMAC_MD5=y
CONFIG_SCTP_COOKIE_HMAC_SHA1=y
CONFIG_INET_SCTP_DIAG=y
CONFIG_RDS=y
CONFIG_RDS_RDMA=y
CONFIG_RDS_TCP=y
CONFIG_RDS_DEBUG=y
CONFIG_TIPC=y
CONFIG_TIPC_MEDIA_IB=y
CONFIG_TIPC_MEDIA_UDP=y
CONFIG_TIPC_CRYPTO=y
CONFIG_TIPC_DIAG=y
CONFIG_ATM=y
CONFIG_ATM_CLIP=y
CONFIG_ATM_CLIP_NO_ICMP=y
CONFIG_ATM_LANE=y
CONFIG_ATM_MPOA=y
CONFIG_ATM_BR2684=y
CONFIG_ATM_BR2684_IPFILTER=y
CONFIG_L2TP=y
CONFIG_L2TP_DEBUGFS=y
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=y
CONFIG_L2TP_ETH=y
CONFIG_STP=y
CONFIG_GARP=y
CONFIG_MRP=y
CONFIG_BRIDGE=y
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_DSA_TAG_AR9331=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_HELLCREEK=y
CONFIG_NET_DSA_TAG_GSWIP=y
CONFIG_NET_DSA_TAG_DSA_COMMON=y
CONFIG_NET_DSA_TAG_DSA=y
CONFIG_NET_DSA_TAG_EDSA=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_DSA_TAG_KSZ=y
CONFIG_NET_DSA_TAG_OCELOT=y
CONFIG_NET_DSA_TAG_OCELOT_8021Q=y
CONFIG_NET_DSA_TAG_QCA=y
CONFIG_NET_DSA_TAG_RTL4_A=y
CONFIG_NET_DSA_TAG_RTL8_4=y
CONFIG_NET_DSA_TAG_RZN1_A5PSW=y
CONFIG_NET_DSA_TAG_LAN9303=y
CONFIG_NET_DSA_TAG_SJA1105=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NET_DSA_TAG_XRS700X=y
CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_LLC=y
CONFIG_LLC2=y
CONFIG_ATALK=y
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=y
CONFIG_IPDDP_ENCAP=y
CONFIG_X25=y
CONFIG_LAPB=y
CONFIG_PHONET=y
CONFIG_6LOWPAN=y
CONFIG_6LOWPAN_DEBUGFS=y
CONFIG_6LOWPAN_NHC=y
CONFIG_6LOWPAN_NHC_DEST=y
CONFIG_6LOWPAN_NHC_FRAGMENT=y
CONFIG_6LOWPAN_NHC_HOP=y
CONFIG_6LOWPAN_NHC_IPV6=y
CONFIG_6LOWPAN_NHC_MOBILITY=y
CONFIG_6LOWPAN_NHC_ROUTING=y
CONFIG_6LOWPAN_NHC_UDP=y
CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=y
CONFIG_6LOWPAN_GHC_UDP=y
CONFIG_6LOWPAN_GHC_ICMPV6=y
CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=y
CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=y
CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=y
CONFIG_IEEE802154=y
CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y
CONFIG_IEEE802154_SOCKET=y
CONFIG_IEEE802154_6LOWPAN=y
CONFIG_MAC802154=y
CONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_HFSC=y
CONFIG_NET_SCH_ATM=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_RED=y
CONFIG_NET_SCH_SFB=y
CONFIG_NET_SCH_SFQ=y
CONFIG_NET_SCH_TEQL=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_CBS=y
CONFIG_NET_SCH_ETF=y
CONFIG_NET_SCH_TAPRIO=y
CONFIG_NET_SCH_GRED=y
CONFIG_NET_SCH_DSMARK=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_DRR=y
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_SCH_SKBPRIO=y
CONFIG_NET_SCH_CHOKE=y
CONFIG_NET_SCH_QFQ=y
CONFIG_NET_SCH_CODEL=y
CONFIG_NET_SCH_FQ_CODEL=y
CONFIG_NET_SCH_CAKE=y
CONFIG_NET_SCH_FQ=y
CONFIG_NET_SCH_HHF=y
CONFIG_NET_SCH_PIE=y
CONFIG_NET_SCH_FQ_PIE=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_SCH_PLUG=y
CONFIG_NET_SCH_ETS=y
CONFIG_NET_SCH_DEFAULT=y
# CONFIG_DEFAULT_FQ is not set
# CONFIG_DEFAULT_CODEL is not set
# CONFIG_DEFAULT_FQ_CODEL is not set
# CONFIG_DEFAULT_FQ_PIE is not set
# CONFIG_DEFAULT_SFQ is not set
CONFIG_DEFAULT_PFIFO_FAST=y
CONFIG_DEFAULT_NET_SCH="pfifo_fast"
#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=y
CONFIG_NET_CLS_ROUTE4=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=y
CONFIG_NET_CLS_RSVP6=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_FLOWER=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_EMATCH_CANID=y
CONFIG_NET_EMATCH_IPSET=y
CONFIG_NET_EMATCH_IPT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SAMPLE=y
CONFIG_NET_ACT_IPT=y
CONFIG_NET_ACT_NAT=y
CONFIG_NET_ACT_PEDIT=y
CONFIG_NET_ACT_SIMP=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_NET_ACT_CSUM=y
CONFIG_NET_ACT_MPLS=y
CONFIG_NET_ACT_VLAN=y
CONFIG_NET_ACT_BPF=y
CONFIG_NET_ACT_CONNMARK=y
CONFIG_NET_ACT_CTINFO=y
CONFIG_NET_ACT_SKBMOD=y
CONFIG_NET_ACT_IFE=y
CONFIG_NET_ACT_TUNNEL_KEY=y
CONFIG_NET_ACT_CT=y
CONFIG_NET_ACT_GATE=y
CONFIG_NET_IFE_SKBMARK=y
CONFIG_NET_IFE_SKBPRIO=y
CONFIG_NET_IFE_SKBTCINDEX=y
CONFIG_NET_TC_SKB_EXT=y
CONFIG_NET_SCH_FIFO=y
CONFIG_DCB=y
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=y
CONFIG_BATMAN_ADV_BATMAN_V=y
CONFIG_BATMAN_ADV_BLA=y
CONFIG_BATMAN_ADV_DAT=y
CONFIG_BATMAN_ADV_NC=y
CONFIG_BATMAN_ADV_MCAST=y
CONFIG_BATMAN_ADV_DEBUG=y
CONFIG_BATMAN_ADV_TRACING=y
CONFIG_OPENVSWITCH=y
CONFIG_OPENVSWITCH_GRE=y
CONFIG_OPENVSWITCH_VXLAN=y
CONFIG_OPENVSWITCH_GENEVE=y
CONFIG_VSOCKETS=y
CONFIG_VSOCKETS_DIAG=y
CONFIG_VSOCKETS_LOOPBACK=y
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS_COMMON=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=y
CONFIG_MPLS_ROUTING=y
CONFIG_MPLS_IPTUNNEL=y
CONFIG_NET_NSH=y
CONFIG_HSR=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_QRTR=y
CONFIG_QRTR_SMD=y
CONFIG_QRTR_TUN=y
CONFIG_QRTR_MHI=y
CONFIG_NET_NCSI=y
CONFIG_NCSI_OEM_CMD_GET_MAC=y
CONFIG_NCSI_OEM_CMD_KEEP_PHY=y
CONFIG_PCPU_DEV_REFCNT=y
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_XPS=y
CONFIG_HWBM=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_NET_FLOW_LIMIT=y
#
# Network testing
#
CONFIG_NET_PKTGEN=y
CONFIG_NET_DROP_MONITOR=y
# end of Network testing
# end of Networking options
CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
CONFIG_AX25=y
CONFIG_AX25_DAMA_SLAVE=y
CONFIG_NETROM=y
CONFIG_ROSE=y
#
# AX.25 network device drivers
#
CONFIG_MKISS=y
CONFIG_6PACK=y
CONFIG_BPQETHER=y
CONFIG_BAYCOM_SER_FDX=y
CONFIG_BAYCOM_SER_HDX=y
CONFIG_BAYCOM_PAR=y
CONFIG_BAYCOM_EPP=y
CONFIG_YAM=y
# end of AX.25 network device drivers
CONFIG_CAN=y
CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_GW=y
CONFIG_CAN_J1939=y
CONFIG_CAN_ISOTP=y
CONFIG_BT=y
CONFIG_BT_BREDR=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_CMTP=y
CONFIG_BT_HIDP=y
CONFIG_BT_HS=y
CONFIG_BT_LE=y
CONFIG_BT_LE_L2CAP_ECRED=y
CONFIG_BT_6LOWPAN=y
CONFIG_BT_LEDS=y
CONFIG_BT_MSFTEXT=y
CONFIG_BT_AOSPEXT=y
CONFIG_BT_DEBUGFS=y
CONFIG_BT_SELFTEST=y
CONFIG_BT_SELFTEST_ECDH=y
CONFIG_BT_SELFTEST_SMP=y
#
# Bluetooth device drivers
#
CONFIG_BT_INTEL=y
CONFIG_BT_BCM=y
CONFIG_BT_RTL=y
CONFIG_BT_QCA=y
CONFIG_BT_MTK=y
CONFIG_BT_HCIBTUSB=y
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
CONFIG_BT_HCIBTUSB_POLL_SYNC=y
CONFIG_BT_HCIBTUSB_BCM=y
CONFIG_BT_HCIBTUSB_MTK=y
CONFIG_BT_HCIBTUSB_RTL=y
CONFIG_BT_HCIBTSDIO=y
CONFIG_BT_HCIUART=y
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_NOKIA=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
CONFIG_BT_HCIUART_INTEL=y
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_HCIUART_RTL=y
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
CONFIG_BT_HCIBCM203X=y
CONFIG_BT_HCIBCM4377=y
CONFIG_BT_HCIBPA10X=y
CONFIG_BT_HCIBFUSB=y
CONFIG_BT_HCIDTL1=y
CONFIG_BT_HCIBT3C=y
CONFIG_BT_HCIBLUECARD=y
CONFIG_BT_HCIVHCI=y
CONFIG_BT_MRVL=y
CONFIG_BT_MRVL_SDIO=y
CONFIG_BT_ATH3K=y
CONFIG_BT_MTKSDIO=y
CONFIG_BT_MTKUART=y
CONFIG_BT_QCOMSMD=y
CONFIG_BT_HCIRSI=y
CONFIG_BT_VIRTIO=y
# end of Bluetooth device drivers
CONFIG_AF_RXRPC=y
CONFIG_AF_RXRPC_IPV6=y
CONFIG_AF_RXRPC_INJECT_LOSS=y
CONFIG_AF_RXRPC_DEBUG=y
CONFIG_RXKAD=y
CONFIG_RXPERF=y
CONFIG_AF_KCM=y
CONFIG_STREAM_PARSER=y
CONFIG_MCTP=y
CONFIG_MCTP_TEST=y
CONFIG_MCTP_FLOWS=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
CONFIG_CFG80211=y
CONFIG_NL80211_TESTMODE=y
CONFIG_CFG80211_DEVELOPER_WARNINGS=y
CONFIG_CFG80211_CERTIFICATION_ONUS=y
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
CONFIG_CFG80211_EXTRA_REGDB_KEYDIR=""
CONFIG_CFG80211_REG_CELLULAR_HINTS=y
CONFIG_CFG80211_REG_RELAX_NO_IR=y
CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_DEBUGFS=y
CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
CONFIG_CFG80211_WEXT_EXPORT=y
CONFIG_LIB80211=y
CONFIG_LIB80211_CRYPT_WEP=y
CONFIG_LIB80211_CRYPT_CCMP=y
CONFIG_LIB80211_CRYPT_TKIP=y
CONFIG_LIB80211_DEBUG=y
CONFIG_MAC80211=y
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_MESSAGE_TRACING=y
CONFIG_MAC80211_DEBUG_MENU=y
CONFIG_MAC80211_NOINLINE=y
CONFIG_MAC80211_VERBOSE_DEBUG=y
CONFIG_MAC80211_MLME_DEBUG=y
CONFIG_MAC80211_STA_DEBUG=y
CONFIG_MAC80211_HT_DEBUG=y
CONFIG_MAC80211_OCB_DEBUG=y
CONFIG_MAC80211_IBSS_DEBUG=y
CONFIG_MAC80211_PS_DEBUG=y
CONFIG_MAC80211_MPL_DEBUG=y
CONFIG_MAC80211_MPATH_DEBUG=y
CONFIG_MAC80211_MHWMP_DEBUG=y
CONFIG_MAC80211_MESH_SYNC_DEBUG=y
CONFIG_MAC80211_MESH_CSA_DEBUG=y
CONFIG_MAC80211_MESH_PS_DEBUG=y
CONFIG_MAC80211_TDLS_DEBUG=y
CONFIG_MAC80211_DEBUG_COUNTERS=y
CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
CONFIG_RFKILL=y
CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
CONFIG_RFKILL_GPIO=y
CONFIG_NET_9P=y
CONFIG_NET_9P_FD=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_RDMA=y
CONFIG_NET_9P_DEBUG=y
CONFIG_CAIF=y
CONFIG_CAIF_DEBUG=y
CONFIG_CAIF_NETDEV=y
CONFIG_CAIF_USB=y
CONFIG_CEPH_LIB=y
CONFIG_CEPH_LIB_PRETTYDEBUG=y
CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
CONFIG_NFC=y
CONFIG_NFC_DIGITAL=y
CONFIG_NFC_NCI=y
CONFIG_NFC_NCI_SPI=y
CONFIG_NFC_NCI_UART=y
CONFIG_NFC_HCI=y
CONFIG_NFC_SHDLC=y
#
# Near Field Communication (NFC) devices
#
CONFIG_NFC_TRF7970A=y
CONFIG_NFC_SIM=y
CONFIG_NFC_PORT100=y
CONFIG_NFC_VIRTUAL_NCI=y
CONFIG_NFC_FDP=y
CONFIG_NFC_FDP_I2C=y
CONFIG_NFC_PN544=y
CONFIG_NFC_PN544_I2C=y
CONFIG_NFC_PN533=y
CONFIG_NFC_PN533_USB=y
CONFIG_NFC_PN533_I2C=y
CONFIG_NFC_PN532_UART=y
CONFIG_NFC_MICROREAD=y
CONFIG_NFC_MICROREAD_I2C=y
CONFIG_NFC_MRVL=y
CONFIG_NFC_MRVL_USB=y
CONFIG_NFC_MRVL_UART=y
CONFIG_NFC_MRVL_I2C=y
CONFIG_NFC_MRVL_SPI=y
CONFIG_NFC_ST21NFCA=y
CONFIG_NFC_ST21NFCA_I2C=y
CONFIG_NFC_ST_NCI=y
CONFIG_NFC_ST_NCI_I2C=y
CONFIG_NFC_ST_NCI_SPI=y
CONFIG_NFC_NXP_NCI=y
CONFIG_NFC_NXP_NCI_I2C=y
CONFIG_NFC_S3FWRN5=y
CONFIG_NFC_S3FWRN5_I2C=y
CONFIG_NFC_S3FWRN82_UART=y
CONFIG_NFC_ST95HF=y
# end of Near Field Communication (NFC) devices
CONFIG_PSAMPLE=y
CONFIG_NET_IFE=y
CONFIG_LWTUNNEL=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_DST_CACHE=y
CONFIG_GRO_CELLS=y
CONFIG_SOCK_VALIDATE_XMIT=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SOCK_MSG=y
CONFIG_NET_DEVLINK=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_POOL_STATS=y
CONFIG_FAILOVER=y
CONFIG_ETHTOOL_NETLINK=y
CONFIG_NETDEV_ADDR_LIST_TEST=y
#
# Device Drivers
#
CONFIG_ARM_AMBA=y
CONFIG_TEGRA_AHB=y
CONFIG_HAVE_PCI=y
CONFIG_FORCE_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_SYSCALL=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCIEAER=y
CONFIG_PCIEAER_INJECT=y
CONFIG_PCIE_ECRC=y
CONFIG_PCIEASPM=y
CONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
# CONFIG_PCIEASPM_PERFORMANCE is not set
CONFIG_PCIE_PME=y
CONFIG_PCIE_DPC=y
CONFIG_PCIE_PTM=y
CONFIG_PCI_MSI=y
CONFIG_PCI_QUIRKS=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_REALLOC_ENABLE_AUTO=y
CONFIG_PCI_STUB=y
CONFIG_PCI_PF_STUB=y
CONFIG_PCI_ATS=y
CONFIG_PCI_DOE=y
CONFIG_PCI_ECAM=y
CONFIG_PCI_BRIDGE_EMUL=y
CONFIG_PCI_IOV=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_PCI_LABEL=y
# CONFIG_PCIE_BUS_TUNE_OFF is not set
CONFIG_PCIE_BUS_DEFAULT=y
# CONFIG_PCIE_BUS_SAFE is not set
# CONFIG_PCIE_BUS_PERFORMANCE is not set
# CONFIG_PCIE_BUS_PEER2PEER is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_SHPC=y
#
# PCI controller drivers
#
CONFIG_PCI_MVEBU=y
CONFIG_PCI_AARDVARK=y
CONFIG_PCIE_XILINX_NWL=y
CONFIG_PCI_FTPCI100=y
CONFIG_PCI_IXP4XX=y
CONFIG_PCI_TEGRA=y
CONFIG_PCI_RCAR_GEN2=y
CONFIG_PCIE_RCAR_HOST=y
CONFIG_PCIE_RCAR_EP=y
CONFIG_PCI_HOST_COMMON=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_XILINX_CPM=y
CONFIG_PCI_XGENE=y
CONFIG_PCI_XGENE_MSI=y
CONFIG_PCI_V3_SEMI=y
CONFIG_PCI_VERSATILE=y
CONFIG_PCIE_IPROC=y
CONFIG_PCIE_IPROC_PLATFORM=y
CONFIG_PCIE_IPROC_BCMA=y
CONFIG_PCIE_IPROC_MSI=y
CONFIG_PCIE_ALTERA=y
CONFIG_PCIE_ALTERA_MSI=y
CONFIG_PCI_HOST_THUNDER_PEM=y
CONFIG_PCI_HOST_THUNDER_ECAM=y
CONFIG_PCIE_ROCKCHIP=y
CONFIG_PCIE_ROCKCHIP_HOST=y
CONFIG_PCIE_ROCKCHIP_EP=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_MEDIATEK_GEN3=y
CONFIG_PCIE_BRCMSTB=y
CONFIG_PCI_LOONGSON=y
CONFIG_PCIE_MICROCHIP_HOST=y
CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR=0xfffff000
CONFIG_PCIE_APPLE=y
CONFIG_PCIE_MT7621=y
#
# DesignWare PCI Core Support
#
CONFIG_PCIE_DW=y
CONFIG_PCIE_DW_HOST=y
CONFIG_PCIE_DW_EP=y
CONFIG_PCI_DRA7XX=y
CONFIG_PCI_DRA7XX_HOST=y
CONFIG_PCI_DRA7XX_EP=y
CONFIG_PCIE_DW_PLAT=y
CONFIG_PCIE_DW_PLAT_HOST=y
CONFIG_PCIE_DW_PLAT_EP=y
CONFIG_PCI_EXYNOS=y
CONFIG_PCI_IMX6=y
CONFIG_PCIE_SPEAR13XX=y
CONFIG_PCI_KEYSTONE=y
CONFIG_PCI_KEYSTONE_HOST=y
CONFIG_PCI_KEYSTONE_EP=y
CONFIG_PCI_LAYERSCAPE=y
CONFIG_PCI_LAYERSCAPE_EP=y
CONFIG_PCI_HISI=y
CONFIG_PCIE_QCOM=y
CONFIG_PCIE_QCOM_EP=y
CONFIG_PCIE_ARMADA_8K=y
CONFIG_PCIE_ARTPEC6=y
CONFIG_PCIE_ARTPEC6_HOST=y
CONFIG_PCIE_ARTPEC6_EP=y
CONFIG_PCIE_BT1=y
CONFIG_PCIE_ROCKCHIP_DW_HOST=y
CONFIG_PCIE_INTEL_GW=y
CONFIG_PCIE_KEEMBAY=y
CONFIG_PCIE_KEEMBAY_HOST=y
CONFIG_PCIE_KEEMBAY_EP=y
CONFIG_PCIE_KIRIN=y
CONFIG_PCIE_HISI_STB=y
CONFIG_PCI_MESON=y
CONFIG_PCIE_TEGRA194=y
CONFIG_PCIE_TEGRA194_HOST=y
CONFIG_PCIE_TEGRA194_EP=y
CONFIG_PCIE_VISCONTI_HOST=y
CONFIG_PCIE_UNIPHIER=y
CONFIG_PCIE_UNIPHIER_EP=y
CONFIG_PCIE_AL=y
CONFIG_PCIE_FU740=y
# end of DesignWare PCI Core Support
#
# Mobiveil PCIe Core Support
#
CONFIG_PCIE_MOBIVEIL=y
CONFIG_PCIE_MOBIVEIL_HOST=y
CONFIG_PCIE_MOBIVEIL_PLAT=y
CONFIG_PCIE_LAYERSCAPE_GEN4=y
# end of Mobiveil PCIe Core Support
#
# Cadence PCIe controllers support
#
CONFIG_PCIE_CADENCE=y
CONFIG_PCIE_CADENCE_HOST=y
CONFIG_PCIE_CADENCE_EP=y
CONFIG_PCIE_CADENCE_PLAT=y
CONFIG_PCIE_CADENCE_PLAT_HOST=y
CONFIG_PCIE_CADENCE_PLAT_EP=y
CONFIG_PCI_J721E=y
CONFIG_PCI_J721E_HOST=y
CONFIG_PCI_J721E_EP=y
# end of Cadence PCIe controllers support
# end of PCI controller drivers
#
# PCI Endpoint
#
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
CONFIG_PCI_EPF_TEST=y
CONFIG_PCI_EPF_NTB=y
CONFIG_PCI_EPF_VNTB=y
# end of PCI Endpoint
#
# PCI switch controller drivers
#
CONFIG_PCI_SW_SWITCHTEC=y
# end of PCI switch controller drivers
CONFIG_CXL_BUS=y
CONFIG_CXL_PCI=y
CONFIG_CXL_MEM_RAW_COMMANDS=y
CONFIG_CXL_MEM=y
CONFIG_CXL_PORT=y
CONFIG_CXL_SUSPEND=y
CONFIG_PCCARD=y
CONFIG_PCMCIA=y
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_CARDBUS=y
#
# PC-card bridges
#
CONFIG_YENTA=y
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=y
CONFIG_I82092=y
CONFIG_OMAP_CF=y
CONFIG_PCCARD_NONSTATIC=y
CONFIG_RAPIDIO=y
CONFIG_RAPIDIO_TSI721=y
CONFIG_RAPIDIO_DISC_TIMEOUT=30
CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y
CONFIG_RAPIDIO_DMA_ENGINE=y
CONFIG_RAPIDIO_DEBUG=y
CONFIG_RAPIDIO_ENUM_BASIC=y
CONFIG_RAPIDIO_CHMAN=y
CONFIG_RAPIDIO_MPORT_CDEV=y
#
# RapidIO Switch drivers
#
CONFIG_RAPIDIO_CPS_XX=y
CONFIG_RAPIDIO_CPS_GEN2=y
CONFIG_RAPIDIO_RXS_GEN3=y
# end of RapidIO Switch drivers
#
# Generic Driver Options
#
CONFIG_AUXILIARY_BUS=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DEVTMPFS_SAFE=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Firmware loader
#
CONFIG_FW_LOADER=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_FW_LOADER_COMPRESS=y
CONFIG_FW_LOADER_COMPRESS_XZ=y
CONFIG_FW_LOADER_COMPRESS_ZSTD=y
CONFIG_FW_CACHE=y
CONFIG_FW_UPLOAD=y
# end of Firmware loader
CONFIG_WANT_DEV_COREDUMP=y
CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_DEV_COREDUMP=y
CONFIG_DEBUG_DRIVER=y
CONFIG_DEBUG_DEVRES=y
CONFIG_DEBUG_TEST_DRIVER_REMOVE=y
CONFIG_PM_QOS_KUNIT_TEST=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
CONFIG_DRIVER_PE_KUNIT_TEST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_SOC_BUS=y
CONFIG_REGMAP=y
CONFIG_REGMAP_AC97=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_SLIMBUS=y
CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_SPMI=y
CONFIG_REGMAP_W1=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_REGMAP_SOUNDWIRE=y
CONFIG_REGMAP_SOUNDWIRE_MBQ=y
CONFIG_REGMAP_SCCB=y
CONFIG_REGMAP_I3C=y
CONFIG_REGMAP_SPI_AVMM=y
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMA_FENCE_TRACE=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
# end of Generic Driver Options
#
# Bus devices
#
CONFIG_ARM_CCI=y
CONFIG_ARM_CCI400_COMMON=y
CONFIG_ARM_CCI400_PORT_CTRL=y
CONFIG_ARM_INTEGRATOR_LM=y
CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_BT1_APB=y
CONFIG_BT1_AXI=y
CONFIG_MOXTET=y
CONFIG_HISILICON_LPC=y
CONFIG_IMX_WEIM=y
CONFIG_INTEL_IXP4XX_EB=y
CONFIG_MVEBU_MBUS=y
CONFIG_OMAP_INTERCONNECT=y
CONFIG_OMAP_OCP2SCP=y
CONFIG_QCOM_EBI2=y
CONFIG_QCOM_SSC_BLOCK_BUS=y
CONFIG_SUN50I_DE2_BUS=y
CONFIG_SUNXI_RSB=y
CONFIG_TEGRA_GMI=y
CONFIG_TI_PWMSS=y
CONFIG_TI_SYSC=y
CONFIG_UNIPHIER_SYSTEM_BUS=y
CONFIG_VEXPRESS_CONFIG=y
CONFIG_FSL_MC_BUS=y
CONFIG_FSL_MC_UAPI_SUPPORT=y
CONFIG_MHI_BUS=y
CONFIG_MHI_BUS_DEBUG=y
CONFIG_MHI_BUS_PCI_GENERIC=y
CONFIG_MHI_BUS_EP=y
# end of Bus devices
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
#
# Firmware Drivers
#
#
# ARM System Control and Management Interface Protocol
#
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCMI_HAVE_TRANSPORT=y
CONFIG_ARM_SCMI_HAVE_SHMEM=y
CONFIG_ARM_SCMI_HAVE_MSG=y
CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y
CONFIG_ARM_SCMI_TRANSPORT_OPTEE=y
CONFIG_ARM_SCMI_TRANSPORT_SMC=y
CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE=y
CONFIG_ARM_SCMI_POWER_DOMAIN=y
CONFIG_ARM_SCMI_POWER_CONTROL=y
# end of ARM System Control and Management Interface Protocol
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_ARM_SCPI_POWER_DOMAIN=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_MTK_ADSP_IPC=y
CONFIG_QCOM_SCM=y
CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT=y
CONFIG_SYSFB=y
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_TI_SCI_PROTOCOL=y
CONFIG_TRUSTED_FOUNDATIONS=y
CONFIG_TURRIS_MOX_RWTM=y
CONFIG_BCM47XX_NVRAM=y
CONFIG_BCM47XX_SPROM=y
CONFIG_TEE_BNXT_FW=y
CONFIG_FW_CS_DSP=y
CONFIG_GOOGLE_FIRMWARE=y
CONFIG_GOOGLE_CBMEM=y
CONFIG_GOOGLE_COREBOOT_TABLE=y
CONFIG_GOOGLE_MEMCONSOLE=y
CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=y
CONFIG_GOOGLE_VPD=y
#
# EFI (Extensible Firmware Interface) Support
#
CONFIG_EFI_ESRT=y
CONFIG_EFI_VARS_PSTORE=y
CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB=y
CONFIG_EFI_ARMSTUB_DTB_LOADER=y
CONFIG_EFI_BOOTLOADER_CONTROL=y
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_EFI_TEST=y
CONFIG_RESET_ATTACK_MITIGATION=y
CONFIG_EFI_RCI2_TABLE=y
CONFIG_EFI_DISABLE_PCI_DMA=y
CONFIG_EFI_DISABLE_RUNTIME=y
CONFIG_EFI_COCO_SECRET=y
# end of EFI (Extensible Firmware Interface) Support
CONFIG_IMX_DSP=y
CONFIG_IMX_SCU=y
CONFIG_IMX_SCU_PD=y
CONFIG_ARM_PSCI_FW=y
CONFIG_HAVE_ARM_SMCCC=y
CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y
CONFIG_ARM_SMCCC_SOC_ID=y
#
# Tegra firmware driver
#
CONFIG_TEGRA_IVC=y
CONFIG_TEGRA_BPMP=y
# end of Tegra firmware driver
# end of Firmware Drivers
CONFIG_GNSS=y
CONFIG_GNSS_SERIAL=y
CONFIG_GNSS_MTK_SERIAL=y
CONFIG_GNSS_SIRF_SERIAL=y
CONFIG_GNSS_UBX_SERIAL=y
CONFIG_GNSS_USB=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
#
# Partition parsers
#
CONFIG_MTD_AR7_PARTS=y
CONFIG_MTD_BCM47XX_PARTS=y
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_BRCM_U_BOOT=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_OF_PARTS_BCM4908=y
CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
CONFIG_MTD_PARSER_IMAGETAG=y
CONFIG_MTD_AFS_PARTS=y
CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y
CONFIG_MTD_PARSER_TRX=y
CONFIG_MTD_SHARPSL_PARTS=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_QCOMSMEM_PARTS=y
# end of Partition parsers
#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
#
# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
#
CONFIG_FTL=y
CONFIG_NFTL=y
CONFIG_NFTL_RW=y
CONFIG_INFTL=y
CONFIG_RFD_FTL=y
CONFIG_SSFDC=y
CONFIG_SM_FTL=y
CONFIG_MTD_OOPS=y
CONFIG_MTD_PSTORE=y
CONFIG_MTD_SWAP=y
CONFIG_MTD_PARTITIONED_MASTER=y
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_MTD_MAP_BANK_WIDTH_8=y
CONFIG_MTD_MAP_BANK_WIDTH_16=y
CONFIG_MTD_MAP_BANK_WIDTH_32=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_I8=y
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=y
CONFIG_MTD_ABSENT=y
# end of RAM/ROM/Flash chip drivers
#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_PHYSMAP_BT1_ROM=y
CONFIG_MTD_PHYSMAP_VERSATILE=y
CONFIG_MTD_PHYSMAP_GEMINI=y
CONFIG_MTD_PHYSMAP_IXP4XX=y
CONFIG_MTD_PHYSMAP_GPIO_ADDR=y
CONFIG_MTD_SC520CDP=y
CONFIG_MTD_NETSC520=y
CONFIG_MTD_TS5500=y
CONFIG_MTD_IMPA7=y
CONFIG_MTD_PCI=y
CONFIG_MTD_PCMCIA=y
CONFIG_MTD_PCMCIA_ANONYMOUS=y
CONFIG_MTD_INTEL_VR_NOR=y
CONFIG_MTD_PLATRAM=y
# end of Mapping drivers for chip access
#
# Self-contained MTD device drivers
#
CONFIG_MTD_PMC551=y
CONFIG_MTD_PMC551_BUGFIX=y
CONFIG_MTD_PMC551_DEBUG=y
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
CONFIG_MTD_DATAFLASH_OTP=y
CONFIG_MTD_MCHP23K256=y
CONFIG_MTD_MCHP48L640=y
CONFIG_MTD_SPEAR_SMI=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_BCM47XXSFLASH=y
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=y
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTD_BLOCK2MTD=y
#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOCG3=y
CONFIG_MTD_ST_SPI_FSM=y
CONFIG_BCH_CONST_M=14
CONFIG_BCH_CONST_T=4
# end of Self-contained MTD device drivers
#
# NAND
#
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_ONENAND=y
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=y
CONFIG_MTD_ONENAND_OMAP2=y
CONFIG_MTD_ONENAND_SAMSUNG=y
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_RAW_NAND=y
#
# Raw/parallel NAND flash controllers
#
CONFIG_MTD_NAND_DENALI=y
CONFIG_MTD_NAND_DENALI_PCI=y
CONFIG_MTD_NAND_DENALI_DT=y
CONFIG_MTD_NAND_AMS_DELTA=y
CONFIG_MTD_NAND_OMAP2=y
CONFIG_MTD_NAND_OMAP_BCH=y
CONFIG_MTD_NAND_OMAP_BCH_BUILD=y
CONFIG_MTD_NAND_S3C2410=y
CONFIG_MTD_NAND_S3C2410_DEBUG=y
CONFIG_MTD_NAND_S3C2410_CLKSTOP=y
CONFIG_MTD_NAND_SHARPSL=y
CONFIG_MTD_NAND_CAFE=y
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_ORION=y
CONFIG_MTD_NAND_MARVELL=y
CONFIG_MTD_NAND_SLC_LPC32XX=y
CONFIG_MTD_NAND_MLC_LPC32XX=y
CONFIG_MTD_NAND_BRCMNAND=y
CONFIG_MTD_NAND_BRCMNAND_BCM63XX=y
CONFIG_MTD_NAND_BRCMNAND_BCMA=y
CONFIG_MTD_NAND_BRCMNAND_BCMBCA=y
CONFIG_MTD_NAND_BRCMNAND_BRCMSTB=y
CONFIG_MTD_NAND_BRCMNAND_IPROC=y
CONFIG_MTD_NAND_BCM47XXNFLASH=y
CONFIG_MTD_NAND_OXNAS=y
CONFIG_MTD_NAND_GPMI_NAND=y
CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_NAND_VF610_NFC=y
CONFIG_MTD_NAND_MXC=y
CONFIG_MTD_NAND_SH_FLCTL=y
CONFIG_MTD_NAND_DAVINCI=y
CONFIG_MTD_NAND_TXX9NDFMC=y
CONFIG_MTD_NAND_JZ4780=y
CONFIG_MTD_NAND_INGENIC_ECC=y
CONFIG_MTD_NAND_JZ4740_ECC=y
CONFIG_MTD_NAND_JZ4725B_BCH=y
CONFIG_MTD_NAND_JZ4780_BCH=y
CONFIG_MTD_NAND_FSMC=y
CONFIG_MTD_NAND_SUNXI=y
CONFIG_MTD_NAND_HISI504=y
CONFIG_MTD_NAND_QCOM=y
CONFIG_MTD_NAND_MTK=y
CONFIG_MTD_NAND_MXIC=y
CONFIG_MTD_NAND_TEGRA=y
CONFIG_MTD_NAND_STM32_FMC2=y
CONFIG_MTD_NAND_MESON=y
CONFIG_MTD_NAND_GPIO=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_NAND_CADENCE=y
CONFIG_MTD_NAND_ARASAN=y
CONFIG_MTD_NAND_INTEL_LGM=y
CONFIG_MTD_NAND_ROCKCHIP=y
CONFIG_MTD_NAND_PL35X=y
CONFIG_MTD_NAND_RENESAS=y
#
# Misc
#
CONFIG_MTD_SM_COMMON=y
CONFIG_MTD_NAND_NANDSIM=y
CONFIG_MTD_NAND_RICOH=y
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_SPI_NAND=y
#
# ECC engine support
#
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
CONFIG_MTD_NAND_ECC_SW_BCH=y
CONFIG_MTD_NAND_ECC_MXIC=y
CONFIG_MTD_NAND_ECC_MEDIATEK=y
# end of ECC engine support
# end of NAND
#
# LPDDR & LPDDR2 PCM memory drivers
#
CONFIG_MTD_LPDDR=y
CONFIG_MTD_QINFO_PROBE=y
CONFIG_MTD_LPDDR2_NVM=y
# end of LPDDR & LPDDR2 PCM memory drivers
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
CONFIG_SPI_HISI_SFC=y
CONFIG_SPI_NXP_SPIFI=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_FASTMAP=y
CONFIG_MTD_UBI_GLUEBI=y
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_HYPERBUS=y
CONFIG_HBMC_AM654=y
CONFIG_DTC=y
CONFIG_OF=y
CONFIG_OF_UNITTEST=y
CONFIG_OF_ALL_DTBS=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OF_RESOLVE=y
CONFIG_OF_OVERLAY=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_SERIAL=y
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_PC_SUPERIO=y
CONFIG_PARPORT_PC_PCMCIA=y
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_NULL_BLK=y
CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION=y
CONFIG_CDROM=y
CONFIG_PARIDE=y
#
# Parallel IDE high-level drivers
#
CONFIG_PARIDE_PD=y
CONFIG_PARIDE_PCD=y
CONFIG_PARIDE_PF=y
CONFIG_PARIDE_PT=y
CONFIG_PARIDE_PG=y
#
# Parallel IDE protocol modules
#
CONFIG_PARIDE_ATEN=y
CONFIG_PARIDE_BPCK=y
CONFIG_PARIDE_BPCK6=y
CONFIG_PARIDE_COMM=y
CONFIG_PARIDE_DSTR=y
CONFIG_PARIDE_FIT2=y
CONFIG_PARIDE_FIT3=y
CONFIG_PARIDE_EPAT=y
CONFIG_PARIDE_EPATC8=y
CONFIG_PARIDE_EPIA=y
CONFIG_PARIDE_FRIQ=y
CONFIG_PARIDE_FRPW=y
CONFIG_PARIDE_KBIC=y
CONFIG_PARIDE_KTTI=y
CONFIG_PARIDE_ON20=y
CONFIG_PARIDE_ON26=y
CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y
CONFIG_ZRAM=y
CONFIG_ZRAM_DEF_COMP_LZORLE=y
# CONFIG_ZRAM_DEF_COMP_ZSTD is not set
# CONFIG_ZRAM_DEF_COMP_LZ4 is not set
# CONFIG_ZRAM_DEF_COMP_LZO is not set
# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set
# CONFIG_ZRAM_DEF_COMP_842 is not set
CONFIG_ZRAM_DEF_COMP="lzo-rle"
CONFIG_ZRAM_WRITEBACK=y
CONFIG_ZRAM_MEMORY_TRACKING=y
CONFIG_ZRAM_MULTI_COMP=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_BLK_DEV_DRBD=y
CONFIG_DRBD_FAULT_INJECTION=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
CONFIG_CDROM_PKTCDVD_WCACHE=y
CONFIG_ATA_OVER_ETH=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=y
CONFIG_BLK_DEV_UBLK=y
CONFIG_BLK_DEV_RNBD=y
CONFIG_BLK_DEV_RNBD_CLIENT=y
CONFIG_BLK_DEV_RNBD_SERVER=y
#
# NVME Support
#
CONFIG_NVME_COMMON=y
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_NVME_MULTIPATH=y
CONFIG_NVME_VERBOSE_ERRORS=y
CONFIG_NVME_HWMON=y
CONFIG_NVME_FABRICS=y
CONFIG_NVME_RDMA=y
CONFIG_NVME_FC=y
CONFIG_NVME_TCP=y
CONFIG_NVME_AUTH=y
CONFIG_NVME_APPLE=y
CONFIG_NVME_TARGET=y
CONFIG_NVME_TARGET_PASSTHRU=y
CONFIG_NVME_TARGET_LOOP=y
CONFIG_NVME_TARGET_RDMA=y
CONFIG_NVME_TARGET_FC=y
CONFIG_NVME_TARGET_FCLOOP=y
CONFIG_NVME_TARGET_TCP=y
CONFIG_NVME_TARGET_AUTH=y
# end of NVME Support
#
# Misc devices
#
CONFIG_SENSORS_LIS3LV02D=y
CONFIG_AD525X_DPOT=y
CONFIG_AD525X_DPOT_I2C=y
CONFIG_AD525X_DPOT_SPI=y
CONFIG_DUMMY_IRQ=y
CONFIG_PHANTOM=y
CONFIG_TIFM_CORE=y
CONFIG_TIFM_7XX1=y
CONFIG_ICS932S401=y
CONFIG_ATMEL_SSC=y
CONFIG_ENCLOSURE_SERVICES=y
CONFIG_SMPRO_ERRMON=y
CONFIG_SMPRO_MISC=y
CONFIG_GEHC_ACHC=y
CONFIG_HI6421V600_IRQ=y
CONFIG_HP_ILO=y
CONFIG_QCOM_COINCELL=y
CONFIG_QCOM_FASTRPC=y
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
CONFIG_ISL29020=y
CONFIG_SENSORS_TSL2550=y
CONFIG_SENSORS_BH1770=y
CONFIG_SENSORS_APDS990X=y
CONFIG_HMC6352=y
CONFIG_DS1682=y
CONFIG_PCH_PHUB=y
CONFIG_LATTICE_ECP3_CONFIG=y
CONFIG_SRAM=y
CONFIG_SRAM_EXEC=y
CONFIG_DW_XDATA_PCIE=y
CONFIG_PCI_ENDPOINT_TEST=y
CONFIG_XILINX_SDFEC=y
CONFIG_MISC_RTSX=y
CONFIG_HISI_HIKEY_USB=y
CONFIG_OPEN_DICE=y
CONFIG_VCPU_STALL_DETECTOR=y
CONFIG_C2PORT=y
#
# EEPROM support
#
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_AT25=y
CONFIG_EEPROM_LEGACY=y
CONFIG_EEPROM_MAX6875=y
CONFIG_EEPROM_93CX6=y
CONFIG_EEPROM_93XX46=y
CONFIG_EEPROM_IDT_89HPESX=y
CONFIG_EEPROM_EE1004=y
# end of EEPROM support
CONFIG_CB710_CORE=y
CONFIG_CB710_DEBUG=y
CONFIG_CB710_DEBUG_ASSUMPTIONS=y
#
# Texas Instruments shared transport line discipline
#
CONFIG_TI_ST=y
# end of Texas Instruments shared transport line discipline
CONFIG_SENSORS_LIS3_SPI=y
CONFIG_SENSORS_LIS3_I2C=y
CONFIG_ALTERA_STAPL=y
CONFIG_ECHO=y
CONFIG_BCM_VK=y
CONFIG_BCM_VK_TTY=y
CONFIG_MISC_ALCOR_PCI=y
CONFIG_MISC_RTSX_PCI=y
CONFIG_MISC_RTSX_USB=y
CONFIG_UACCE=y
CONFIG_PVPANIC=y
CONFIG_PVPANIC_MMIO=y
CONFIG_PVPANIC_PCI=y
CONFIG_GP_PCI1XXXX=y
# end of Misc devices
#
# SCSI device support
#
CONFIG_SCSI_MOD=y
CONFIG_RAID_ATTRS=y
CONFIG_SCSI_COMMON=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
CONFIG_BLK_DEV_BSG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_ENCLOSURE=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SRP_ATTRS=y
# end of SCSI Transports
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=y
CONFIG_ISCSI_BOOT_SYSFS=y
CONFIG_SCSI_CXGB3_ISCSI=y
CONFIG_SCSI_CXGB4_ISCSI=y
CONFIG_SCSI_BNX2_ISCSI=y
CONFIG_SCSI_BNX2X_FCOE=y
CONFIG_BE2ISCSI=y
CONFIG_BLK_DEV_3W_XXXX_RAID=y
CONFIG_SCSI_HPSA=y
CONFIG_SCSI_3W_9XXX=y
CONFIG_SCSI_3W_SAS=y
CONFIG_SCSI_ACARD=y
CONFIG_SCSI_AACRAID=y
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_AIC7XXX_RESET_DELAY_MS=5000
CONFIG_AIC7XXX_DEBUG_ENABLE=y
CONFIG_AIC7XXX_DEBUG_MASK=0
CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
CONFIG_SCSI_AIC79XX=y
CONFIG_AIC79XX_CMDS_PER_DEVICE=32
CONFIG_AIC79XX_RESET_DELAY_MS=5000
CONFIG_AIC79XX_DEBUG_ENABLE=y
CONFIG_AIC79XX_DEBUG_MASK=0
CONFIG_AIC79XX_REG_PRETTY_PRINT=y
CONFIG_SCSI_AIC94XX=y
CONFIG_AIC94XX_DEBUG=y
CONFIG_SCSI_HISI_SAS=y
CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y
CONFIG_SCSI_MVSAS=y
CONFIG_SCSI_MVSAS_DEBUG=y
CONFIG_SCSI_MVSAS_TASKLET=y
CONFIG_SCSI_MVUMI=y
CONFIG_SCSI_ADVANSYS=y
CONFIG_SCSI_ARCMSR=y
CONFIG_SCSI_ESAS2R=y
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=y
CONFIG_MEGARAID_MAILBOX=y
CONFIG_MEGARAID_LEGACY=y
CONFIG_MEGARAID_SAS=y
CONFIG_SCSI_MPT3SAS=y
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS=y
CONFIG_SCSI_MPI3MR=y
CONFIG_SCSI_SMARTPQI=y
CONFIG_SCSI_HPTIOP=y
CONFIG_SCSI_BUSLOGIC=y
CONFIG_SCSI_FLASHPOINT=y
CONFIG_SCSI_MYRB=y
CONFIG_SCSI_MYRS=y
CONFIG_LIBFC=y
CONFIG_LIBFCOE=y
CONFIG_FCOE=y
CONFIG_SCSI_SNIC=y
CONFIG_SCSI_SNIC_DEBUG_FS=y
CONFIG_SCSI_DMX3191D=y
CONFIG_SCSI_FDOMAIN=y
CONFIG_SCSI_FDOMAIN_PCI=y
CONFIG_SCSI_IPS=y
CONFIG_SCSI_INITIO=y
CONFIG_SCSI_INIA100=y
CONFIG_SCSI_PPA=y
CONFIG_SCSI_IMM=y
CONFIG_SCSI_IZIP_EPP16=y
CONFIG_SCSI_IZIP_SLOW_CTR=y
CONFIG_SCSI_STEX=y
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
CONFIG_SCSI_IPR=y
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
CONFIG_SCSI_QLOGIC_1280=y
CONFIG_SCSI_QLA_FC=y
CONFIG_TCM_QLA2XXX=y
CONFIG_TCM_QLA2XXX_DEBUG=y
CONFIG_SCSI_QLA_ISCSI=y
CONFIG_QEDI=y
CONFIG_QEDF=y
CONFIG_SCSI_LPFC=y
CONFIG_SCSI_LPFC_DEBUG_FS=y
CONFIG_SCSI_EFCT=y
CONFIG_SCSI_DC395x=y
CONFIG_SCSI_AM53C974=y
CONFIG_SCSI_NSP32=y
CONFIG_SCSI_WD719X=y
CONFIG_SCSI_DEBUG=y
CONFIG_SCSI_PMCRAID=y
CONFIG_SCSI_PM8001=y
CONFIG_SCSI_BFA_FC=y
CONFIG_SCSI_VIRTIO=y
CONFIG_SCSI_CHELSIO_FCOE=y
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_PCMCIA_AHA152X=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_PCMCIA_NINJA_SCSI=m
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=y
CONFIG_SCSI_DH_HP_SW=y
CONFIG_SCSI_DH_EMC=y
CONFIG_SCSI_DH_ALUA=y
# end of SCSI device support
CONFIG_HAVE_PATA_PLATFORM=y
CONFIG_ATA=y
CONFIG_SATA_HOST=y
CONFIG_PATA_TIMINGS=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_FORCE=y
CONFIG_SATA_PMP=y
#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
CONFIG_SATA_MOBILE_LPM_POLICY=0
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_BRCM=y
CONFIG_AHCI_DA850=y
CONFIG_AHCI_DM816=y
CONFIG_AHCI_DWC=y
CONFIG_AHCI_ST=y
CONFIG_AHCI_IMX=y
CONFIG_AHCI_CEVA=y
CONFIG_AHCI_MTK=y
CONFIG_AHCI_MVEBU=y
CONFIG_AHCI_SUNXI=y
CONFIG_AHCI_TEGRA=y
CONFIG_AHCI_XGENE=y
CONFIG_AHCI_QORIQ=y
CONFIG_SATA_FSL=y
CONFIG_SATA_GEMINI=y
CONFIG_SATA_AHCI_SEATTLE=y
CONFIG_SATA_INIC162X=y
CONFIG_SATA_ACARD_AHCI=y
CONFIG_SATA_SIL24=y
CONFIG_ATA_SFF=y
#
# SFF controllers with custom DMA interface
#
CONFIG_PDC_ADMA=y
CONFIG_SATA_QSTOR=y
CONFIG_SATA_SX4=y
CONFIG_ATA_BMDMA=y
#
# SATA SFF controllers with BMDMA
#
CONFIG_ATA_PIIX=y
CONFIG_SATA_DWC=y
CONFIG_SATA_DWC_OLD_DMA=y
CONFIG_SATA_HIGHBANK=y
CONFIG_SATA_MV=y
CONFIG_SATA_NV=y
CONFIG_SATA_PROMISE=y
CONFIG_SATA_RCAR=y
CONFIG_SATA_SIL=y
CONFIG_SATA_SIS=y
CONFIG_SATA_SVW=y
CONFIG_SATA_ULI=y
CONFIG_SATA_VIA=y
CONFIG_SATA_VITESSE=y
#
# PATA SFF controllers with BMDMA
#
CONFIG_PATA_ALI=y
CONFIG_PATA_AMD=y
CONFIG_PATA_ARASAN_CF=y
CONFIG_PATA_ARTOP=y
CONFIG_PATA_ATIIXP=y
CONFIG_PATA_ATP867X=y
CONFIG_PATA_CMD64X=y
CONFIG_PATA_CS5520=y
CONFIG_PATA_CS5530=y
CONFIG_PATA_CS5536=y
CONFIG_PATA_CYPRESS=y
CONFIG_PATA_EFAR=y
CONFIG_PATA_FTIDE010=y
CONFIG_PATA_HPT366=y
CONFIG_PATA_HPT37X=y
CONFIG_PATA_HPT3X2N=y
CONFIG_PATA_HPT3X3=y
CONFIG_PATA_HPT3X3_DMA=y
CONFIG_PATA_IMX=y
CONFIG_PATA_IT8213=y
CONFIG_PATA_IT821X=y
CONFIG_PATA_JMICRON=y
CONFIG_PATA_MARVELL=y
CONFIG_PATA_NETCELL=y
CONFIG_PATA_NINJA32=y
CONFIG_PATA_NS87415=y
CONFIG_PATA_OLDPIIX=y
CONFIG_PATA_OPTIDMA=y
CONFIG_PATA_PDC2027X=y
CONFIG_PATA_PDC_OLD=y
CONFIG_PATA_RADISYS=y
CONFIG_PATA_RDC=y
CONFIG_PATA_SC1200=y
CONFIG_PATA_SCH=y
CONFIG_PATA_SERVERWORKS=y
CONFIG_PATA_SIL680=y
CONFIG_PATA_SIS=y
CONFIG_PATA_TOSHIBA=y
CONFIG_PATA_TRIFLEX=y
CONFIG_PATA_VIA=y
CONFIG_PATA_PXA=y
CONFIG_PATA_WINBOND=y
#
# PIO-only SFF controllers
#
CONFIG_PATA_CMD640_PCI=y
CONFIG_PATA_IXP4XX_CF=y
CONFIG_PATA_MPIIX=y
CONFIG_PATA_NS87410=y
CONFIG_PATA_OPTI=y
CONFIG_PATA_PCMCIA=y
CONFIG_PATA_PLATFORM=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_PATA_RZ1000=y
#
# Generic fallback / legacy drivers
#
CONFIG_ATA_GENERIC=y
CONFIG_PATA_LEGACY=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
CONFIG_MD_MULTIPATH=y
CONFIG_MD_FAULTY=y
CONFIG_MD_CLUSTER=y
CONFIG_BCACHE=y
CONFIG_BCACHE_DEBUG=y
CONFIG_BCACHE_CLOSURES_DEBUG=y
CONFIG_BCACHE_ASYNC_REGISTRATION=y
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_DEBUG=y
CONFIG_DM_BUFIO=y
CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING=y
CONFIG_DM_DEBUG_BLOCK_STACK_TRACING=y
CONFIG_DM_BIO_PRISON=y
CONFIG_DM_PERSISTENT_DATA=y
CONFIG_DM_UNSTRIPED=y
CONFIG_DM_CRYPT=y
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_THIN_PROVISIONING=y
CONFIG_DM_CACHE=y
CONFIG_DM_CACHE_SMQ=y
CONFIG_DM_WRITECACHE=y
CONFIG_DM_ERA=y
CONFIG_DM_CLONE=y
CONFIG_DM_MIRROR=y
CONFIG_DM_LOG_USERSPACE=y
CONFIG_DM_RAID=y
CONFIG_DM_ZERO=y
CONFIG_DM_MULTIPATH=y
CONFIG_DM_MULTIPATH_QL=y
CONFIG_DM_MULTIPATH_ST=y
CONFIG_DM_MULTIPATH_HST=y
CONFIG_DM_MULTIPATH_IOA=y
CONFIG_DM_DELAY=y
CONFIG_DM_DUST=y
CONFIG_DM_INIT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y
CONFIG_DM_VERITY_FEC=y
CONFIG_DM_SWITCH=y
CONFIG_DM_LOG_WRITES=y
CONFIG_DM_INTEGRITY=y
CONFIG_DM_ZONED=y
CONFIG_DM_AUDIT=y
CONFIG_TARGET_CORE=y
CONFIG_TCM_IBLOCK=y
CONFIG_TCM_FILEIO=y
CONFIG_TCM_PSCSI=y
CONFIG_TCM_USER2=y
CONFIG_LOOPBACK_TARGET=y
CONFIG_TCM_FC=y
CONFIG_ISCSI_TARGET=y
CONFIG_ISCSI_TARGET_CXGB4=y
CONFIG_SBP_TARGET=y
CONFIG_FUSION=y
CONFIG_FUSION_SPI=y
CONFIG_FUSION_FC=y
CONFIG_FUSION_SAS=y
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=y
CONFIG_FUSION_LAN=y
CONFIG_FUSION_LOGGING=y
#
# IEEE 1394 (FireWire) support
#
CONFIG_FIREWIRE=y
CONFIG_FIREWIRE_OHCI=y
CONFIG_FIREWIRE_SBP2=y
CONFIG_FIREWIRE_NET=y
CONFIG_FIREWIRE_NOSY=y
# end of IEEE 1394 (FireWire) support
CONFIG_NETDEVICES=y
CONFIG_MII=y
CONFIG_NET_CORE=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_WIREGUARD=y
CONFIG_WIREGUARD_DEBUG=y
CONFIG_EQUALIZER=y
CONFIG_NET_FC=y
CONFIG_IFB=y
CONFIG_NET_TEAM=y
CONFIG_NET_TEAM_MODE_BROADCAST=y
CONFIG_NET_TEAM_MODE_ROUNDROBIN=y
CONFIG_NET_TEAM_MODE_RANDOM=y
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y
CONFIG_NET_TEAM_MODE_LOADBALANCE=y
CONFIG_MACVLAN=y
CONFIG_MACVTAP=y
CONFIG_IPVLAN_L3S=y
CONFIG_IPVLAN=y
CONFIG_IPVTAP=y
CONFIG_VXLAN=y
CONFIG_GENEVE=y
CONFIG_BAREUDP=y
CONFIG_GTP=y
CONFIG_AMT=y
CONFIG_MACSEC=y
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_NTB_NETDEV=y
CONFIG_RIONET=y
CONFIG_RIONET_TX_SIZE=128
CONFIG_RIONET_RX_SIZE=128
CONFIG_TUN=y
CONFIG_TAP=y
CONFIG_TUN_VNET_CROSS_LE=y
CONFIG_VETH=y
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=y
CONFIG_NET_VRF=y
CONFIG_VSOCKMON=y
CONFIG_MHI_NET=y
CONFIG_SUNGEM_PHY=y
CONFIG_ARCNET=y
CONFIG_ARCNET_1201=y
CONFIG_ARCNET_1051=y
CONFIG_ARCNET_RAW=y
CONFIG_ARCNET_CAP=y
CONFIG_ARCNET_COM90xx=y
CONFIG_ARCNET_COM90xxIO=y
CONFIG_ARCNET_RIM_I=y
CONFIG_ARCNET_COM20020=y
CONFIG_ARCNET_COM20020_PCI=y
CONFIG_ARCNET_COM20020_CS=y
CONFIG_ATM_DRIVERS=y
CONFIG_ATM_DUMMY=y
CONFIG_ATM_TCP=y
CONFIG_ATM_LANAI=y
CONFIG_ATM_ENI=y
CONFIG_ATM_ENI_DEBUG=y
CONFIG_ATM_ENI_TUNE_BURST=y
CONFIG_ATM_ENI_BURST_TX_16W=y
CONFIG_ATM_ENI_BURST_TX_8W=y
CONFIG_ATM_ENI_BURST_TX_4W=y
CONFIG_ATM_ENI_BURST_TX_2W=y
CONFIG_ATM_ENI_BURST_RX_16W=y
CONFIG_ATM_ENI_BURST_RX_8W=y
CONFIG_ATM_ENI_BURST_RX_4W=y
CONFIG_ATM_ENI_BURST_RX_2W=y
CONFIG_ATM_NICSTAR=y
CONFIG_ATM_NICSTAR_USE_SUNI=y
CONFIG_ATM_NICSTAR_USE_IDT77105=y
CONFIG_ATM_IDT77252=y
CONFIG_ATM_IDT77252_DEBUG=y
CONFIG_ATM_IDT77252_RCV_ALL=y
CONFIG_ATM_IDT77252_USE_SUNI=y
CONFIG_ATM_IA=y
CONFIG_ATM_IA_DEBUG=y
CONFIG_ATM_FORE200E=y
CONFIG_ATM_FORE200E_USE_TASKLET=y
CONFIG_ATM_FORE200E_TX_RETRY=16
CONFIG_ATM_FORE200E_DEBUG=0
CONFIG_ATM_HE=y
CONFIG_ATM_HE_USE_SUNI=y
CONFIG_ATM_SOLOS=y
CONFIG_CAIF_DRIVERS=y
CONFIG_CAIF_TTY=y
CONFIG_CAIF_VIRTIO=y
#
# Distributed Switch Architecture drivers
#
CONFIG_B53=y
CONFIG_B53_SPI_DRIVER=y
CONFIG_B53_MDIO_DRIVER=y
CONFIG_B53_MMAP_DRIVER=y
CONFIG_B53_SRAB_DRIVER=y
CONFIG_B53_SERDES=y
CONFIG_NET_DSA_BCM_SF2=y
CONFIG_NET_DSA_LOOP=y
CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=y
CONFIG_NET_DSA_LANTIQ_GSWIP=y
CONFIG_NET_DSA_MT7530=y
CONFIG_NET_DSA_MV88E6060=y
CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=y
CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=y
CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=y
CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=y
CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_NET_DSA_MV88E6XXX_PTP=y
CONFIG_NET_DSA_MSCC_FELIX=y
CONFIG_NET_DSA_MSCC_SEVILLE=y
CONFIG_NET_DSA_AR9331=y
CONFIG_NET_DSA_QCA8K=y
CONFIG_NET_DSA_SJA1105=y
CONFIG_NET_DSA_SJA1105_PTP=y
CONFIG_NET_DSA_SJA1105_TAS=y
CONFIG_NET_DSA_SJA1105_VL=y
CONFIG_NET_DSA_XRS700X=y
CONFIG_NET_DSA_XRS700X_I2C=y
CONFIG_NET_DSA_XRS700X_MDIO=y
CONFIG_NET_DSA_REALTEK=y
CONFIG_NET_DSA_REALTEK_MDIO=y
CONFIG_NET_DSA_REALTEK_SMI=y
CONFIG_NET_DSA_REALTEK_RTL8365MB=y
CONFIG_NET_DSA_REALTEK_RTL8366RB=y
CONFIG_NET_DSA_RZN1_A5PSW=y
CONFIG_NET_DSA_SMSC_LAN9303=y
CONFIG_NET_DSA_SMSC_LAN9303_I2C=y
CONFIG_NET_DSA_SMSC_LAN9303_MDIO=y
CONFIG_NET_DSA_VITESSE_VSC73XX=y
CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=y
CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=y
# end of Distributed Switch Architecture drivers
CONFIG_ETHERNET=y
CONFIG_MDIO=y
CONFIG_NET_VENDOR_3COM=y
CONFIG_PCMCIA_3C574=y
CONFIG_PCMCIA_3C589=y
CONFIG_TYPHOON=y
CONFIG_NET_VENDOR_ACTIONS=y
CONFIG_OWL_EMAC=y
CONFIG_NET_VENDOR_ADAPTEC=y
CONFIG_ADAPTEC_STARFIRE=y
CONFIG_NET_VENDOR_AGERE=y
CONFIG_ET131X=y
CONFIG_NET_VENDOR_ALACRITECH=y
CONFIG_SLICOSS=y
CONFIG_NET_VENDOR_ALLWINNER=y
CONFIG_SUN4I_EMAC=y
CONFIG_NET_VENDOR_ALTEON=y
CONFIG_ACENIC=y
CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_ALTERA_TSE=y
CONFIG_NET_VENDOR_AMAZON=y
CONFIG_ENA_ETHERNET=y
CONFIG_NET_VENDOR_AMD=y
CONFIG_AMD8111_ETH=y
CONFIG_PCNET32=y
CONFIG_PCMCIA_NMCLAN=y
CONFIG_AMD_XGBE=y
CONFIG_AMD_XGBE_DCB=y
CONFIG_NET_XGENE=y
CONFIG_NET_XGENE_V2=y
CONFIG_NET_VENDOR_AQUANTIA=y
CONFIG_AQTION=y
CONFIG_NET_VENDOR_ARC=y
CONFIG_ARC_EMAC_CORE=y
CONFIG_ARC_EMAC=y
CONFIG_EMAC_ROCKCHIP=y
CONFIG_NET_VENDOR_ASIX=y
CONFIG_SPI_AX88796C=y
CONFIG_SPI_AX88796C_COMPRESSION=y
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL2=y
CONFIG_ATL1=y
CONFIG_ATL1E=y
CONFIG_ATL1C=y
CONFIG_ALX=y
CONFIG_CX_ECAT=y
CONFIG_NET_VENDOR_BROADCOM=y
CONFIG_B44=y
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
CONFIG_BCM4908_ENET=y
CONFIG_BCMGENET=y
CONFIG_BNX2=y
CONFIG_CNIC=y
CONFIG_TIGON3=y
CONFIG_TIGON3_HWMON=y
CONFIG_BNX2X=y
CONFIG_BNX2X_SRIOV=y
CONFIG_BGMAC=y
CONFIG_BGMAC_BCMA=y
CONFIG_BGMAC_PLATFORM=y
CONFIG_SYSTEMPORT=y
CONFIG_BNXT=y
CONFIG_BNXT_SRIOV=y
CONFIG_BNXT_FLOWER_OFFLOAD=y
CONFIG_BNXT_DCB=y
CONFIG_BNXT_HWMON=y
CONFIG_NET_VENDOR_CADENCE=y
CONFIG_MACB=y
CONFIG_MACB_USE_HWSTAMP=y
CONFIG_MACB_PCI=y
CONFIG_NET_CALXEDA_XGMAC=y
CONFIG_NET_VENDOR_CAVIUM=y
CONFIG_NET_VENDOR_CHELSIO=y
CONFIG_CHELSIO_T1=y
CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T3=y
CONFIG_CHELSIO_T4=y
CONFIG_CHELSIO_T4_DCB=y
CONFIG_CHELSIO_T4_FCOE=y
CONFIG_CHELSIO_T4VF=y
CONFIG_CHELSIO_LIB=y
CONFIG_CHELSIO_INLINE_CRYPTO=y
CONFIG_CRYPTO_DEV_CHELSIO_TLS=y
CONFIG_CHELSIO_IPSEC_INLINE=y
CONFIG_CHELSIO_TLS_DEVICE=y
CONFIG_NET_VENDOR_CIRRUS=y
CONFIG_CS89x0=y
CONFIG_CS89x0_PLATFORM=y
CONFIG_EP93XX_ETH=y
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=y
CONFIG_NET_VENDOR_CORTINA=y
CONFIG_GEMINI_ETHERNET=y
CONFIG_NET_VENDOR_DAVICOM=y
CONFIG_DM9000=y
CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
CONFIG_DM9051=y
CONFIG_DNET=y
CONFIG_NET_VENDOR_DEC=y
CONFIG_NET_TULIP=y
CONFIG_DE2104X=y
CONFIG_DE2104X_DSL=0
CONFIG_TULIP=y
CONFIG_TULIP_MWI=y
CONFIG_TULIP_MMIO=y
CONFIG_TULIP_NAPI=y
CONFIG_TULIP_NAPI_HW_MITIGATION=y
CONFIG_WINBOND_840=y
CONFIG_DM9102=y
CONFIG_ULI526X=y
CONFIG_PCMCIA_XIRCOM=y
CONFIG_NET_VENDOR_DLINK=y
CONFIG_DL2K=y
CONFIG_SUNDANCE=y
CONFIG_SUNDANCE_MMIO=y
CONFIG_NET_VENDOR_EMULEX=y
CONFIG_BE2NET=y
CONFIG_BE2NET_HWMON=y
CONFIG_BE2NET_BE2=y
CONFIG_BE2NET_BE3=y
CONFIG_BE2NET_LANCER=y
CONFIG_BE2NET_SKYHAWK=y
CONFIG_NET_VENDOR_ENGLEDER=y
CONFIG_TSNEP=y
CONFIG_TSNEP_SELFTESTS=y
CONFIG_NET_VENDOR_EZCHIP=y
CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y
CONFIG_NET_VENDOR_FARADAY=y
CONFIG_FTMAC100=y
CONFIG_FTGMAC100=y
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FEC=y
CONFIG_FSL_FMAN=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_GIANFAR=y
CONFIG_FSL_DPAA2_ETH=y
CONFIG_FSL_DPAA2_ETH_DCB=y
CONFIG_FSL_DPAA2_PTP_CLOCK=y
CONFIG_FSL_DPAA2_SWITCH=y
CONFIG_FSL_ENETC=y
CONFIG_FSL_ENETC_VF=y
CONFIG_FSL_ENETC_IERB=y
CONFIG_FSL_ENETC_MDIO=y
CONFIG_FSL_ENETC_PTP_CLOCK=y
CONFIG_FSL_ENETC_QOS=y
CONFIG_NET_VENDOR_FUJITSU=y
CONFIG_PCMCIA_FMVJ18X=y
CONFIG_NET_VENDOR_FUNGIBLE=y
CONFIG_FUN_CORE=y
CONFIG_FUN_ETH=y
CONFIG_NET_VENDOR_GOOGLE=y
CONFIG_GVE=y
CONFIG_NET_VENDOR_HISILICON=y
CONFIG_HIX5HD2_GMAC=y
CONFIG_HISI_FEMAC=y
CONFIG_HIP04_ETH=y
CONFIG_HI13X1_GMAC=y
CONFIG_HNS_MDIO=y
CONFIG_HNS=y
CONFIG_HNS_DSAF=y
CONFIG_HNS_ENET=y
CONFIG_HNS3=y
CONFIG_HNS3_HCLGE=y
CONFIG_HNS3_DCB=y
CONFIG_HNS3_HCLGEVF=y
CONFIG_NET_VENDOR_HUAWEI=y
CONFIG_NET_VENDOR_I825XX=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_E100=y
CONFIG_E1000=y
CONFIG_E1000E=y
CONFIG_IGB=y
CONFIG_IGB_HWMON=y
CONFIG_IGBVF=y
CONFIG_IXGB=y
CONFIG_IXGBE=y
CONFIG_IXGBE_HWMON=y
CONFIG_IXGBE_DCB=y
CONFIG_IXGBE_IPSEC=y
CONFIG_IXGBEVF=y
CONFIG_IXGBEVF_IPSEC=y
CONFIG_I40E=y
CONFIG_I40E_DCB=y
CONFIG_IAVF=y
CONFIG_I40EVF=y
CONFIG_ICE=y
CONFIG_ICE_SWITCHDEV=y
CONFIG_FM10K=y
CONFIG_IGC=y
CONFIG_NET_VENDOR_WANGXUN=y
CONFIG_LIBWX=y
CONFIG_NGBE=y
CONFIG_TXGBE=y
CONFIG_JME=y
CONFIG_KORINA=y
CONFIG_NET_VENDOR_ADI=y
CONFIG_ADIN1110=y
CONFIG_NET_VENDOR_LITEX=y
CONFIG_LITEX_LITEETH=y
CONFIG_NET_VENDOR_MARVELL=y
CONFIG_MV643XX_ETH=y
CONFIG_MVMDIO=y
CONFIG_MVNETA_BM_ENABLE=y
CONFIG_MVNETA=y
CONFIG_MVNETA_BM=y
CONFIG_MVPP2=y
CONFIG_MVPP2_PTP=y
CONFIG_PXA168_ETH=y
CONFIG_SKGE=y
CONFIG_SKGE_DEBUG=y
CONFIG_SKGE_GENESIS=y
CONFIG_SKY2=y
CONFIG_SKY2_DEBUG=y
CONFIG_PRESTERA=y
CONFIG_PRESTERA_PCI=y
CONFIG_NET_VENDOR_MEDIATEK=y
CONFIG_NET_MEDIATEK_SOC_WED=y
CONFIG_NET_MEDIATEK_SOC=y
CONFIG_NET_MEDIATEK_STAR_EMAC=y
CONFIG_NET_VENDOR_MELLANOX=y
CONFIG_MLX4_EN=y
CONFIG_MLX4_EN_DCB=y
CONFIG_MLX4_CORE=y
CONFIG_MLX4_DEBUG=y
CONFIG_MLX4_CORE_GEN2=y
CONFIG_MLX5_CORE=y
CONFIG_MLX5_FPGA=y
CONFIG_MLX5_CORE_EN=y
CONFIG_MLX5_EN_ARFS=y
CONFIG_MLX5_EN_RXNFC=y
CONFIG_MLX5_MPFS=y
CONFIG_MLX5_ESWITCH=y
CONFIG_MLX5_BRIDGE=y
CONFIG_MLX5_CLS_ACT=y
CONFIG_MLX5_TC_CT=y
CONFIG_MLX5_TC_SAMPLE=y
CONFIG_MLX5_CORE_EN_DCB=y
CONFIG_MLX5_CORE_IPOIB=y
CONFIG_MLX5_EN_MACSEC=y
CONFIG_MLX5_EN_IPSEC=y
CONFIG_MLX5_EN_TLS=y
CONFIG_MLX5_SW_STEERING=y
CONFIG_MLX5_SF=y
CONFIG_MLX5_SF_MANAGER=y
CONFIG_MLXSW_CORE=y
CONFIG_MLXSW_CORE_HWMON=y
CONFIG_MLXSW_CORE_THERMAL=y
CONFIG_MLXSW_PCI=y
CONFIG_MLXSW_I2C=y
CONFIG_MLXSW_SPECTRUM=y
CONFIG_MLXSW_SPECTRUM_DCB=y
CONFIG_MLXSW_MINIMAL=y
CONFIG_MLXFW=y
CONFIG_MLXBF_GIGE=y
CONFIG_NET_VENDOR_MICREL=y
CONFIG_KS8842=y
CONFIG_KS8851=y
CONFIG_KS8851_MLL=y
CONFIG_KSZ884X_PCI=y
CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_ENC28J60=y
CONFIG_ENC28J60_WRITEVERIFY=y
CONFIG_ENCX24J600=y
CONFIG_LAN743X=y
CONFIG_LAN966X_SWITCH=y
CONFIG_SPARX5_SWITCH=y
CONFIG_SPARX5_DCB=y
CONFIG_VCAP=y
CONFIG_VCAP_KUNIT_TEST=y
CONFIG_NET_VENDOR_MICROSEMI=y
CONFIG_MSCC_OCELOT_SWITCH_LIB=y
CONFIG_MSCC_OCELOT_SWITCH=y
CONFIG_NET_VENDOR_MICROSOFT=y
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=y
CONFIG_NET_VENDOR_NI=y
CONFIG_NI_XGE_MANAGEMENT_ENET=y
CONFIG_NET_VENDOR_NATSEMI=y
CONFIG_NATSEMI=y
CONFIG_NS83820=y
CONFIG_NET_VENDOR_NETERION=y
CONFIG_S2IO=y
CONFIG_NET_VENDOR_NETRONOME=y
CONFIG_NFP=y
CONFIG_NFP_APP_FLOWER=y
CONFIG_NFP_APP_ABM_NIC=y
CONFIG_NFP_NET_IPSEC=y
CONFIG_NFP_DEBUG=y
CONFIG_NET_VENDOR_8390=y
CONFIG_PCMCIA_AXNET=y
CONFIG_AX88796=y
CONFIG_AX88796_93CX6=y
CONFIG_NE2K_PCI=y
CONFIG_PCMCIA_PCNET=y
CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=y
CONFIG_LPC_ENET=y
CONFIG_NET_VENDOR_OKI=y
CONFIG_PCH_GBE=y
CONFIG_ETHOC=y
CONFIG_NET_VENDOR_PACKET_ENGINES=y
CONFIG_HAMACHI=y
CONFIG_YELLOWFIN=y
CONFIG_NET_VENDOR_PENSANDO=y
CONFIG_NET_VENDOR_QLOGIC=y
CONFIG_QLA3XXX=y
CONFIG_QLCNIC=y
CONFIG_QLCNIC_SRIOV=y
CONFIG_QLCNIC_DCB=y
CONFIG_QLCNIC_HWMON=y
CONFIG_NETXEN_NIC=y
CONFIG_QED=y
CONFIG_QED_LL2=y
CONFIG_QED_SRIOV=y
CONFIG_QEDE=y
CONFIG_QED_ISCSI=y
CONFIG_QED_FCOE=y
CONFIG_QED_OOO=y
CONFIG_NET_VENDOR_BROCADE=y
CONFIG_BNA=y
CONFIG_NET_VENDOR_QUALCOMM=y
CONFIG_QCA7000=y
CONFIG_QCA7000_SPI=y
CONFIG_QCA7000_UART=y
CONFIG_QCOM_EMAC=y
CONFIG_RMNET=y
CONFIG_NET_VENDOR_RDC=y
CONFIG_R6040=y
CONFIG_NET_VENDOR_REALTEK=y
CONFIG_8139CP=y
CONFIG_8139TOO=y
CONFIG_8139TOO_PIO=y
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
CONFIG_8139_OLD_RX_RESET=y
CONFIG_R8169=y
CONFIG_NET_VENDOR_RENESAS=y
CONFIG_SH_ETH=y
CONFIG_RAVB=y
CONFIG_RENESAS_ETHER_SWITCH=y
CONFIG_NET_VENDOR_ROCKER=y
CONFIG_ROCKER=y
CONFIG_NET_VENDOR_SAMSUNG=y
CONFIG_SXGBE_ETH=y
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SILAN=y
CONFIG_SC92031=y
CONFIG_NET_VENDOR_SIS=y
CONFIG_SIS900=y
CONFIG_SIS190=y
CONFIG_NET_VENDOR_SOLARFLARE=y
CONFIG_SFC=y
CONFIG_SFC_MTD=y
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
CONFIG_SFC_MCDI_LOGGING=y
CONFIG_SFC_FALCON=y
CONFIG_SFC_FALCON_MTD=y
CONFIG_SFC_SIENA=y
CONFIG_SFC_SIENA_MTD=y
CONFIG_SFC_SIENA_MCDI_MON=y
CONFIG_SFC_SIENA_SRIOV=y
CONFIG_SFC_SIENA_MCDI_LOGGING=y
CONFIG_NET_VENDOR_SMSC=y
CONFIG_SMC91X=y
CONFIG_PCMCIA_SMC91C92=y
CONFIG_EPIC100=y
CONFIG_SMSC911X=y
CONFIG_SMSC9420=y
CONFIG_NET_VENDOR_SOCIONEXT=y
CONFIG_SNI_AVE=y
CONFIG_SNI_NETSEC=y
CONFIG_NET_VENDOR_STMICRO=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_SELFTESTS=y
CONFIG_STMMAC_PLATFORM=y
CONFIG_DWMAC_DWC_QOS_ETH=y
CONFIG_DWMAC_GENERIC=y
CONFIG_DWMAC_ANARION=y
CONFIG_DWMAC_INGENIC=y
CONFIG_DWMAC_IPQ806X=y
CONFIG_DWMAC_LPC18XX=y
CONFIG_DWMAC_MEDIATEK=y
CONFIG_DWMAC_MESON=y
CONFIG_DWMAC_OXNAS=y
CONFIG_DWMAC_QCOM_ETHQOS=y
CONFIG_DWMAC_ROCKCHIP=y
CONFIG_DWMAC_SOCFPGA=y
CONFIG_DWMAC_STI=y
CONFIG_DWMAC_STM32=y
CONFIG_DWMAC_SUNXI=y
CONFIG_DWMAC_SUN8I=y
CONFIG_DWMAC_IMX8=y
CONFIG_DWMAC_INTEL_PLAT=y
CONFIG_DWMAC_TEGRA=y
CONFIG_DWMAC_VISCONTI=y
CONFIG_DWMAC_LOONGSON=y
CONFIG_STMMAC_PCI=y
CONFIG_NET_VENDOR_SUN=y
CONFIG_HAPPYMEAL=y
CONFIG_SUNGEM=y
CONFIG_CASSINI=y
CONFIG_NIU=y
CONFIG_NET_VENDOR_SUNPLUS=y
CONFIG_SP7021_EMAC=y
CONFIG_NET_VENDOR_SYNOPSYS=y
CONFIG_DWC_XLGMAC=y
CONFIG_DWC_XLGMAC_PCI=y
CONFIG_NET_VENDOR_TEHUTI=y
CONFIG_TEHUTI=y
CONFIG_NET_VENDOR_TI=y
CONFIG_TI_DAVINCI_EMAC=y
CONFIG_TI_DAVINCI_MDIO=y
CONFIG_TI_CPSW_PHY_SEL=y
CONFIG_TI_CPSW=y
CONFIG_TI_CPSW_SWITCHDEV=y
CONFIG_TI_CPTS=y
CONFIG_TI_KEYSTONE_NETCP=y
CONFIG_TI_KEYSTONE_NETCP_ETHSS=y
CONFIG_TLAN=y
CONFIG_NET_VENDOR_VERTEXCOM=y
CONFIG_MSE102X=y
CONFIG_NET_VENDOR_VIA=y
CONFIG_VIA_RHINE=y
CONFIG_VIA_RHINE_MMIO=y
CONFIG_VIA_VELOCITY=y
CONFIG_NET_VENDOR_WIZNET=y
CONFIG_WIZNET_W5100=y
CONFIG_WIZNET_W5300=y
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not set
CONFIG_WIZNET_BUS_ANY=y
CONFIG_WIZNET_W5100_SPI=y
CONFIG_NET_VENDOR_XILINX=y
CONFIG_XILINX_EMACLITE=y
CONFIG_XILINX_AXI_EMAC=y
CONFIG_XILINX_LL_TEMAC=y
CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=y
CONFIG_FDDI=y
CONFIG_DEFXX=y
CONFIG_SKFP=y
CONFIG_HIPPI=y
CONFIG_ROADRUNNER=y
CONFIG_ROADRUNNER_LARGE_RINGS=y
CONFIG_QCOM_IPA=y
CONFIG_PHYLINK=y
CONFIG_PHYLIB=y
CONFIG_SWPHY=y
CONFIG_LED_TRIGGER_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_SFP=y
#
# MII PHY device drivers
#
CONFIG_AMD_PHY=y
CONFIG_MESON_GXL_PHY=y
CONFIG_ADIN_PHY=y
CONFIG_ADIN1100_PHY=y
CONFIG_AQUANTIA_PHY=y
CONFIG_AX88796B_PHY=y
CONFIG_BROADCOM_PHY=y
CONFIG_BCM54140_PHY=y
CONFIG_BCM63XX_PHY=y
CONFIG_BCM7XXX_PHY=y
CONFIG_BCM84881_PHY=y
CONFIG_BCM87XX_PHY=y
CONFIG_BCM_CYGNUS_PHY=y
CONFIG_BCM_NET_PHYLIB=y
CONFIG_BCM_NET_PHYPTP=y
CONFIG_CICADA_PHY=y
CONFIG_CORTINA_PHY=y
CONFIG_DAVICOM_PHY=y
CONFIG_ICPLUS_PHY=y
CONFIG_LXT_PHY=y
CONFIG_INTEL_XWAY_PHY=y
CONFIG_LSI_ET1011C_PHY=y
CONFIG_MARVELL_PHY=y
CONFIG_MARVELL_10G_PHY=y
CONFIG_MARVELL_88X2222_PHY=y
CONFIG_MAXLINEAR_GPHY=y
CONFIG_MEDIATEK_GE_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_MICROCHIP_PHY=y
CONFIG_MICROCHIP_T1_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_MOTORCOMM_PHY=y
CONFIG_NATIONAL_PHY=y
CONFIG_NXP_C45_TJA11XX_PHY=y
CONFIG_NXP_TJA11XX_PHY=y
CONFIG_AT803X_PHY=y
CONFIG_QSEMI_PHY=y
CONFIG_REALTEK_PHY=y
CONFIG_RENESAS_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_STE10XP=y
CONFIG_TERANETICS_PHY=y
CONFIG_DP83822_PHY=y
CONFIG_DP83TC811_PHY=y
CONFIG_DP83848_PHY=y
CONFIG_DP83867_PHY=y
CONFIG_DP83869_PHY=y
CONFIG_DP83TD510_PHY=y
CONFIG_VITESSE_PHY=y
CONFIG_XILINX_GMII2RGMII=y
CONFIG_MICREL_KS8995MA=y
CONFIG_PSE_CONTROLLER=y
CONFIG_PSE_REGULATOR=y
CONFIG_CAN_DEV=y
CONFIG_CAN_VCAN=y
CONFIG_CAN_VXCAN=y
CONFIG_CAN_NETLINK=y
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_RX_OFFLOAD=y
CONFIG_CAN_AT91=y
CONFIG_CAN_CAN327=y
CONFIG_CAN_FLEXCAN=y
CONFIG_CAN_GRCAN=y
CONFIG_CAN_JANZ_ICAN3=y
CONFIG_CAN_KVASER_PCIEFD=y
CONFIG_CAN_SLCAN=y
CONFIG_CAN_SUN4I=y
CONFIG_CAN_TI_HECC=y
CONFIG_CAN_XILINXCAN=y
CONFIG_CAN_C_CAN=y
CONFIG_CAN_C_CAN_PLATFORM=y
CONFIG_CAN_C_CAN_PCI=y
CONFIG_CAN_CC770=y
CONFIG_CAN_CC770_ISA=y
CONFIG_CAN_CC770_PLATFORM=y
CONFIG_CAN_CTUCANFD=y
CONFIG_CAN_CTUCANFD_PCI=y
CONFIG_CAN_CTUCANFD_PLATFORM=y
CONFIG_CAN_IFI_CANFD=y
CONFIG_CAN_M_CAN=y
CONFIG_CAN_M_CAN_PCI=y
CONFIG_CAN_M_CAN_PLATFORM=y
CONFIG_CAN_M_CAN_TCAN4X5X=y
CONFIG_CAN_PEAK_PCIEFD=y
CONFIG_CAN_RCAR=y
CONFIG_CAN_RCAR_CANFD=y
CONFIG_CAN_SJA1000=y
CONFIG_CAN_EMS_PCI=y
CONFIG_CAN_EMS_PCMCIA=y
CONFIG_CAN_F81601=y
CONFIG_CAN_KVASER_PCI=y
CONFIG_CAN_PEAK_PCI=y
CONFIG_CAN_PEAK_PCIEC=y
CONFIG_CAN_PLX_PCI=y
CONFIG_CAN_SJA1000_ISA=y
CONFIG_CAN_SJA1000_PLATFORM=y
CONFIG_CAN_SOFTING=y
CONFIG_CAN_SOFTING_CS=y
#
# CAN SPI interfaces
#
CONFIG_CAN_HI311X=y
CONFIG_CAN_MCP251X=y
CONFIG_CAN_MCP251XFD=y
CONFIG_CAN_MCP251XFD_SANITY=y
# end of CAN SPI interfaces
#
# CAN USB interfaces
#
CONFIG_CAN_8DEV_USB=y
CONFIG_CAN_EMS_USB=y
CONFIG_CAN_ESD_USB=y
CONFIG_CAN_ETAS_ES58X=y
CONFIG_CAN_GS_USB=y
CONFIG_CAN_KVASER_USB=y
CONFIG_CAN_MCBA_USB=y
CONFIG_CAN_PEAK_USB=y
CONFIG_CAN_UCAN=y
# end of CAN USB interfaces
CONFIG_CAN_DEBUG_DEVICES=y
#
# MCTP Device Drivers
#
CONFIG_MCTP_SERIAL=y
CONFIG_MCTP_TRANSPORT_I2C=y
# end of MCTP Device Drivers
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_BUS=y
CONFIG_FWNODE_MDIO=y
CONFIG_OF_MDIO=y
CONFIG_MDIO_DEVRES=y
CONFIG_MDIO_SUN4I=y
CONFIG_MDIO_XGENE=y
CONFIG_MDIO_ASPEED=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BCM_IPROC=y
CONFIG_MDIO_BCM_UNIMAC=y
CONFIG_MDIO_CAVIUM=y
CONFIG_MDIO_GPIO=y
CONFIG_MDIO_HISI_FEMAC=y
CONFIG_MDIO_I2C=y
CONFIG_MDIO_MVUSB=y
CONFIG_MDIO_MSCC_MIIM=y
CONFIG_MDIO_MOXART=y
CONFIG_MDIO_OCTEON=y
CONFIG_MDIO_IPQ4019=y
CONFIG_MDIO_IPQ8064=y
#
# MDIO Multiplexers
#
CONFIG_MDIO_BUS_MUX=y
CONFIG_MDIO_BUS_MUX_MESON_G12A=y
CONFIG_MDIO_BUS_MUX_BCM6368=y
CONFIG_MDIO_BUS_MUX_BCM_IPROC=y
CONFIG_MDIO_BUS_MUX_GPIO=y
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
#
# PCS device drivers
#
CONFIG_PCS_XPCS=y
CONFIG_PCS_LYNX=y
CONFIG_PCS_RZN1_MIIC=y
CONFIG_PCS_ALTERA_TSE=y
# end of PCS device drivers
CONFIG_PLIP=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOATM=y
CONFIG_PPPOE=y
CONFIG_PPTP=y
CONFIG_PPPOL2TP=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
CONFIG_SLIP=y
CONFIG_SLHC=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_CATC=y
CONFIG_USB_KAWETH=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8150=y
CONFIG_USB_RTL8152=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_AX88179_178A=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_CDC_EEM=y
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_HUAWEI_CDC_NCM=y
CONFIG_USB_NET_CDC_MBIM=y
CONFIG_USB_NET_DM9601=y
CONFIG_USB_NET_SR9700=y
CONFIG_USB_NET_SR9800=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_NET_GL620A=y
CONFIG_USB_NET_NET1080=y
CONFIG_USB_NET_PLUSB=y
CONFIG_USB_NET_MCS7830=y
CONFIG_USB_NET_RNDIS_HOST=y
CONFIG_USB_NET_CDC_SUBSET_ENABLE=y
CONFIG_USB_NET_CDC_SUBSET=y
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=y
CONFIG_USB_NET_CX82310_ETH=y
CONFIG_USB_NET_KALMIA=y
CONFIG_USB_NET_QMI_WWAN=y
CONFIG_USB_HSO=y
CONFIG_USB_NET_INT51X1=y
CONFIG_USB_CDC_PHONET=y
CONFIG_USB_IPHETH=y
CONFIG_USB_SIERRA_NET=y
CONFIG_USB_VL600=y
CONFIG_USB_NET_CH9200=y
CONFIG_USB_NET_AQC111=y
CONFIG_USB_RTL8153_ECM=y
CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y
CONFIG_ADM8211=y
CONFIG_ATH_COMMON=y
CONFIG_WLAN_VENDOR_ATH=y
CONFIG_ATH_DEBUG=y
CONFIG_ATH_TRACEPOINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y
CONFIG_ATH5K=y
CONFIG_ATH5K_DEBUG=y
CONFIG_ATH5K_TRACER=y
CONFIG_ATH5K_PCI=y
CONFIG_ATH5K_TEST_CHANNELS=y
CONFIG_ATH9K_HW=y
CONFIG_ATH9K_COMMON=y
CONFIG_ATH9K_COMMON_DEBUG=y
CONFIG_ATH9K_DFS_DEBUGFS=y
CONFIG_ATH9K_BTCOEX_SUPPORT=y
CONFIG_ATH9K=y
CONFIG_ATH9K_PCI=y
CONFIG_ATH9K_AHB=y
CONFIG_ATH9K_DEBUGFS=y
CONFIG_ATH9K_STATION_STATISTICS=y
CONFIG_ATH9K_TX99=y
CONFIG_ATH9K_DFS_CERTIFIED=y
CONFIG_ATH9K_DYNACK=y
CONFIG_ATH9K_WOW=y
CONFIG_ATH9K_RFKILL=y
CONFIG_ATH9K_CHANNEL_CONTEXT=y
CONFIG_ATH9K_PCOEM=y
CONFIG_ATH9K_PCI_NO_EEPROM=y
CONFIG_ATH9K_HTC=y
CONFIG_ATH9K_HTC_DEBUGFS=y
CONFIG_ATH9K_HWRNG=y
CONFIG_ATH9K_COMMON_SPECTRAL=y
CONFIG_CARL9170=y
CONFIG_CARL9170_LEDS=y
CONFIG_CARL9170_DEBUGFS=y
CONFIG_CARL9170_WPC=y
CONFIG_CARL9170_HWRNG=y
CONFIG_ATH6KL=y
CONFIG_ATH6KL_SDIO=y
CONFIG_ATH6KL_USB=y
CONFIG_ATH6KL_DEBUG=y
CONFIG_ATH6KL_TRACING=y
CONFIG_ATH6KL_REGDOMAIN=y
CONFIG_AR5523=y
CONFIG_WIL6210=y
CONFIG_WIL6210_ISR_COR=y
CONFIG_WIL6210_TRACING=y
CONFIG_WIL6210_DEBUGFS=y
CONFIG_ATH10K=y
CONFIG_ATH10K_CE=y
CONFIG_ATH10K_PCI=y
CONFIG_ATH10K_AHB=y
CONFIG_ATH10K_SDIO=y
CONFIG_ATH10K_USB=y
CONFIG_ATH10K_SNOC=y
CONFIG_ATH10K_DEBUG=y
CONFIG_ATH10K_DEBUGFS=y
CONFIG_ATH10K_SPECTRAL=y
CONFIG_ATH10K_TRACING=y
CONFIG_ATH10K_DFS_CERTIFIED=y
CONFIG_WCN36XX=y
CONFIG_WCN36XX_DEBUGFS=y
CONFIG_ATH11K=y
CONFIG_ATH11K_AHB=y
CONFIG_ATH11K_PCI=y
CONFIG_ATH11K_DEBUG=y
CONFIG_ATH11K_DEBUGFS=y
CONFIG_ATH11K_TRACING=y
CONFIG_ATH11K_SPECTRAL=y
CONFIG_WLAN_VENDOR_ATMEL=y
CONFIG_ATMEL=y
CONFIG_PCI_ATMEL=y
CONFIG_PCMCIA_ATMEL=y
CONFIG_AT76C50X_USB=y
CONFIG_WLAN_VENDOR_BROADCOM=y
CONFIG_B43=y
CONFIG_B43_BCMA=y
CONFIG_B43_SSB=y
CONFIG_B43_BUSES_BCMA_AND_SSB=y
# CONFIG_B43_BUSES_BCMA is not set
# CONFIG_B43_BUSES_SSB is not set
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
CONFIG_B43_SDIO=y
CONFIG_B43_BCMA_PIO=y
CONFIG_B43_PIO=y
CONFIG_B43_PHY_G=y
CONFIG_B43_PHY_N=y
CONFIG_B43_PHY_LP=y
CONFIG_B43_PHY_HT=y
CONFIG_B43_LEDS=y
CONFIG_B43_HWRNG=y
CONFIG_B43_DEBUG=y
CONFIG_B43LEGACY=y
CONFIG_B43LEGACY_PCI_AUTOSELECT=y
CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
CONFIG_B43LEGACY_LEDS=y
CONFIG_B43LEGACY_HWRNG=y
CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
CONFIG_BRCMUTIL=y
CONFIG_BRCMSMAC=y
CONFIG_BRCMSMAC_LEDS=y
CONFIG_BRCMFMAC=y
CONFIG_BRCMFMAC_PROTO_BCDC=y
CONFIG_BRCMFMAC_PROTO_MSGBUF=y
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_USB=y
CONFIG_BRCMFMAC_PCIE=y
CONFIG_BRCM_TRACING=y
CONFIG_BRCMDBG=y
CONFIG_WLAN_VENDOR_CISCO=y
CONFIG_AIRO_CS=y
CONFIG_WLAN_VENDOR_INTEL=y
CONFIG_IPW2100=y
CONFIG_IPW2100_MONITOR=y
CONFIG_IPW2100_DEBUG=y
CONFIG_IPW2200=y
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y
CONFIG_IPW2200_DEBUG=y
CONFIG_LIBIPW=y
CONFIG_LIBIPW_DEBUG=y
CONFIG_IWLEGACY=y
CONFIG_IWL4965=y
CONFIG_IWL3945=y
#
# iwl3945 / iwl4965 Debugging Options
#
CONFIG_IWLEGACY_DEBUG=y
CONFIG_IWLEGACY_DEBUGFS=y
# end of iwl3945 / iwl4965 Debugging Options
CONFIG_IWLWIFI=y
CONFIG_IWLWIFI_LEDS=y
CONFIG_IWLDVM=y
CONFIG_IWLMVM=y
#
# Debugging Options
#
CONFIG_IWLWIFI_DEBUG=y
CONFIG_IWLWIFI_DEBUGFS=y
CONFIG_IWLWIFI_DEVICE_TRACING=y
# end of Debugging Options
CONFIG_WLAN_VENDOR_INTERSIL=y
CONFIG_HOSTAP=y
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_HOSTAP_PLX=y
CONFIG_HOSTAP_PCI=y
CONFIG_HOSTAP_CS=y
CONFIG_HERMES=y
CONFIG_HERMES_PRISM=y
CONFIG_HERMES_CACHE_FW_ON_INIT=y
CONFIG_PLX_HERMES=y
CONFIG_TMD_HERMES=y
CONFIG_NORTEL_HERMES=y
CONFIG_PCI_HERMES=y
CONFIG_ORINOCO_USB=y
CONFIG_P54_COMMON=y
CONFIG_P54_USB=y
CONFIG_P54_PCI=y
CONFIG_P54_SPI=y
CONFIG_P54_SPI_DEFAULT_EEPROM=y
CONFIG_P54_LEDS=y
CONFIG_WLAN_VENDOR_MARVELL=y
CONFIG_LIBERTAS=y
CONFIG_LIBERTAS_USB=y
CONFIG_LIBERTAS_SDIO=y
CONFIG_LIBERTAS_SPI=y
CONFIG_LIBERTAS_DEBUG=y
CONFIG_LIBERTAS_MESH=y
CONFIG_LIBERTAS_THINFIRM=y
CONFIG_LIBERTAS_THINFIRM_DEBUG=y
CONFIG_LIBERTAS_THINFIRM_USB=y
CONFIG_MWIFIEX=y
CONFIG_MWIFIEX_SDIO=y
CONFIG_MWIFIEX_PCIE=y
CONFIG_MWIFIEX_USB=y
CONFIG_MWL8K=y
CONFIG_WLAN_VENDOR_MEDIATEK=y
CONFIG_MT7601U=y
CONFIG_MT76_CORE=y
CONFIG_MT76_LEDS=y
CONFIG_MT76_USB=y
CONFIG_MT76_SDIO=y
CONFIG_MT76x02_LIB=y
CONFIG_MT76x02_USB=y
CONFIG_MT76_CONNAC_LIB=y
CONFIG_MT76x0_COMMON=y
CONFIG_MT76x0U=y
CONFIG_MT76x0E=y
CONFIG_MT76x2_COMMON=y
CONFIG_MT76x2E=y
CONFIG_MT76x2U=y
CONFIG_MT7603E=y
CONFIG_MT7615_COMMON=y
CONFIG_MT7615E=y
CONFIG_MT7622_WMAC=y
CONFIG_MT7663_USB_SDIO_COMMON=y
CONFIG_MT7663U=y
CONFIG_MT7663S=y
CONFIG_MT7915E=y
CONFIG_MT7986_WMAC=y
CONFIG_MT7921_COMMON=y
CONFIG_MT7921E=y
CONFIG_MT7921S=y
CONFIG_MT7921U=y
CONFIG_MT7996E=y
CONFIG_WLAN_VENDOR_MICROCHIP=y
CONFIG_WILC1000=y
CONFIG_WILC1000_SDIO=y
CONFIG_WILC1000_SPI=y
CONFIG_WILC1000_HW_OOB_INTR=y
CONFIG_WLAN_VENDOR_PURELIFI=y
CONFIG_PLFXLC=y
CONFIG_WLAN_VENDOR_RALINK=y
CONFIG_RT2X00=y
CONFIG_RT2400PCI=y
CONFIG_RT2500PCI=y
CONFIG_RT61PCI=y
CONFIG_RT2800PCI=y
CONFIG_RT2800PCI_RT33XX=y
CONFIG_RT2800PCI_RT35XX=y
CONFIG_RT2800PCI_RT53XX=y
CONFIG_RT2800PCI_RT3290=y
CONFIG_RT2500USB=y
CONFIG_RT73USB=y
CONFIG_RT2800USB=y
CONFIG_RT2800USB_RT33XX=y
CONFIG_RT2800USB_RT35XX=y
CONFIG_RT2800USB_RT3573=y
CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_RT55XX=y
CONFIG_RT2800USB_UNKNOWN=y
CONFIG_RT2800_LIB=y
CONFIG_RT2800_LIB_MMIO=y
CONFIG_RT2X00_LIB_MMIO=y
CONFIG_RT2X00_LIB_PCI=y
CONFIG_RT2X00_LIB_USB=y
CONFIG_RT2X00_LIB=y
CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_CRYPTO=y
CONFIG_RT2X00_LIB_LEDS=y
CONFIG_RT2X00_LIB_DEBUGFS=y
CONFIG_RT2X00_DEBUG=y
CONFIG_WLAN_VENDOR_REALTEK=y
CONFIG_RTL8180=y
CONFIG_RTL8187=y
CONFIG_RTL8187_LEDS=y
CONFIG_RTL_CARDS=y
CONFIG_RTL8192CE=y
CONFIG_RTL8192SE=y
CONFIG_RTL8192DE=y
CONFIG_RTL8723AE=y
CONFIG_RTL8723BE=y
CONFIG_RTL8188EE=y
CONFIG_RTL8192EE=y
CONFIG_RTL8821AE=y
CONFIG_RTL8192CU=y
CONFIG_RTLWIFI=y
CONFIG_RTLWIFI_PCI=y
CONFIG_RTLWIFI_USB=y
CONFIG_RTLWIFI_DEBUG=y
CONFIG_RTL8192C_COMMON=y
CONFIG_RTL8723_COMMON=y
CONFIG_RTLBTCOEXIST=y
CONFIG_RTL8XXXU=y
CONFIG_RTL8XXXU_UNTESTED=y
CONFIG_RTW88=y
CONFIG_RTW88_CORE=y
CONFIG_RTW88_PCI=y
CONFIG_RTW88_USB=y
CONFIG_RTW88_8822B=y
CONFIG_RTW88_8822C=y
CONFIG_RTW88_8723D=y
CONFIG_RTW88_8821C=y
CONFIG_RTW88_8822BE=y
CONFIG_RTW88_8822BU=y
CONFIG_RTW88_8822CE=y
CONFIG_RTW88_8822CU=y
CONFIG_RTW88_8723DE=y
CONFIG_RTW88_8723DU=y
CONFIG_RTW88_8821CE=y
CONFIG_RTW88_8821CU=y
CONFIG_RTW88_DEBUG=y
CONFIG_RTW88_DEBUGFS=y
CONFIG_RTW89=y
CONFIG_RTW89_CORE=y
CONFIG_RTW89_PCI=y
CONFIG_RTW89_8852A=y
CONFIG_RTW89_8852B=y
CONFIG_RTW89_8852C=y
CONFIG_RTW89_8852AE=y
CONFIG_RTW89_8852BE=y
CONFIG_RTW89_8852CE=y
CONFIG_RTW89_DEBUG=y
CONFIG_RTW89_DEBUGMSG=y
CONFIG_RTW89_DEBUGFS=y
CONFIG_WLAN_VENDOR_RSI=y
CONFIG_RSI_91X=y
CONFIG_RSI_DEBUGFS=y
CONFIG_RSI_SDIO=y
CONFIG_RSI_USB=y
CONFIG_RSI_COEX=y
CONFIG_WLAN_VENDOR_SILABS=y
CONFIG_WFX=y
CONFIG_WLAN_VENDOR_ST=y
CONFIG_CW1200=y
CONFIG_CW1200_WLAN_SDIO=y
CONFIG_CW1200_WLAN_SPI=y
CONFIG_WLAN_VENDOR_TI=y
CONFIG_WL1251=y
CONFIG_WL1251_SPI=y
CONFIG_WL1251_SDIO=y
CONFIG_WL12XX=y
CONFIG_WL18XX=y
CONFIG_WLCORE=y
CONFIG_WLCORE_SPI=y
CONFIG_WLCORE_SDIO=y
CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_USB_ZD1201=y
CONFIG_ZD1211RW=y
CONFIG_ZD1211RW_DEBUG=y
CONFIG_WLAN_VENDOR_QUANTENNA=y
CONFIG_QTNFMAC=y
CONFIG_QTNFMAC_PCIE=y
CONFIG_PCMCIA_RAYCS=y
CONFIG_PCMCIA_WL3501=y
CONFIG_MAC80211_HWSIM=y
CONFIG_USB_NET_RNDIS_WLAN=y
CONFIG_VIRT_WIFI=y
CONFIG_WAN=y
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
CONFIG_HDLC_RAW_ETH=y
CONFIG_HDLC_CISCO=y
CONFIG_HDLC_FR=y
CONFIG_HDLC_PPP=y
CONFIG_HDLC_X25=y
CONFIG_PCI200SYN=y
CONFIG_WANXL=y
CONFIG_PC300TOO=y
CONFIG_FARSYNC=y
CONFIG_FSL_UCC_HDLC=y
CONFIG_SLIC_DS26522=y
CONFIG_LAPBETHER=y
CONFIG_IEEE802154_DRIVERS=y
CONFIG_IEEE802154_FAKELB=y
CONFIG_IEEE802154_AT86RF230=y
CONFIG_IEEE802154_MRF24J40=y
CONFIG_IEEE802154_CC2520=y
CONFIG_IEEE802154_ATUSB=y
CONFIG_IEEE802154_ADF7242=y
CONFIG_IEEE802154_CA8210=y
CONFIG_IEEE802154_CA8210_DEBUGFS=y
CONFIG_IEEE802154_MCR20A=y
CONFIG_IEEE802154_HWSIM=y
#
# Wireless WAN
#
CONFIG_WWAN=y
CONFIG_WWAN_DEBUGFS=y
CONFIG_WWAN_HWSIM=y
CONFIG_MHI_WWAN_CTRL=y
CONFIG_MHI_WWAN_MBIM=y
CONFIG_QCOM_BAM_DMUX=y
CONFIG_RPMSG_WWAN_CTRL=y
CONFIG_IOSM=y
CONFIG_MTK_T7XX=y
# end of Wireless WAN
CONFIG_VMXNET3=y
CONFIG_USB4_NET=y
CONFIG_NETDEVSIM=y
CONFIG_NET_FAILOVER=y
CONFIG_ISDN=y
CONFIG_ISDN_CAPI=y
CONFIG_CAPI_TRACE=y
CONFIG_ISDN_CAPI_MIDDLEWARE=y
CONFIG_MISDN=y
CONFIG_MISDN_DSP=y
CONFIG_MISDN_L1OIP=y
#
# mISDN hardware drivers
#
CONFIG_MISDN_HFCPCI=y
CONFIG_MISDN_HFCMULTI=y
CONFIG_MISDN_HFCUSB=y
CONFIG_MISDN_AVMFRITZ=y
CONFIG_MISDN_SPEEDFAX=y
CONFIG_MISDN_INFINEON=y
CONFIG_MISDN_W6692=y
CONFIG_MISDN_NETJET=y
CONFIG_MISDN_HDLC=y
CONFIG_MISDN_IPAC=y
CONFIG_MISDN_ISAR=y
#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_LEDS=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_SPARSEKMAP=y
CONFIG_INPUT_MATRIXKMAP=y
CONFIG_INPUT_VIVALDIFMAP=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y
CONFIG_INPUT_APMPOWER=y
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADC=y
CONFIG_KEYBOARD_ADP5520=y
CONFIG_KEYBOARD_ADP5588=y
CONFIG_KEYBOARD_ADP5589=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_QT1050=y
CONFIG_KEYBOARD_QT1070=y
CONFIG_KEYBOARD_QT2160=y
CONFIG_KEYBOARD_CLPS711X=y
CONFIG_KEYBOARD_DLINK_DIR685=y
CONFIG_KEYBOARD_LKKBD=y
CONFIG_KEYBOARD_EP93XX=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_GPIO_POLLED=y
CONFIG_KEYBOARD_TCA6416=y
CONFIG_KEYBOARD_TCA8418=y
CONFIG_KEYBOARD_MATRIX=y
CONFIG_KEYBOARD_LM8323=y
CONFIG_KEYBOARD_LM8333=y
CONFIG_KEYBOARD_LPC32XX=y
CONFIG_KEYBOARD_MAX7359=y
CONFIG_KEYBOARD_MCS=y
CONFIG_KEYBOARD_MPR121=y
CONFIG_KEYBOARD_SNVS_PWRKEY=y
CONFIG_KEYBOARD_IMX=y
CONFIG_KEYBOARD_IMX_SC_KEY=y
CONFIG_KEYBOARD_NEWTON=y
CONFIG_KEYBOARD_NOMADIK=y
CONFIG_KEYBOARD_TEGRA=y
CONFIG_KEYBOARD_OPENCORES=y
CONFIG_KEYBOARD_PINEPHONE=y
CONFIG_KEYBOARD_PXA27x=y
CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_KEYBOARD_SAMSUNG=y
CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
CONFIG_KEYBOARD_STOWAWAY=y
CONFIG_KEYBOARD_ST_KEYSCAN=y
CONFIG_KEYBOARD_SUNKBD=y
CONFIG_KEYBOARD_SH_KEYSC=y
CONFIG_KEYBOARD_STMPE=y
CONFIG_KEYBOARD_SUN4I_LRADC=y
CONFIG_KEYBOARD_IQS62X=y
CONFIG_KEYBOARD_OMAP4=y
CONFIG_KEYBOARD_SPEAR=y
CONFIG_KEYBOARD_TC3589X=y
CONFIG_KEYBOARD_TM2_TOUCHKEY=y
CONFIG_KEYBOARD_TWL4030=y
CONFIG_KEYBOARD_XTKBD=y
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_KEYBOARD_CAP11XX=y
CONFIG_KEYBOARD_BCM=y
CONFIG_KEYBOARD_MT6779=y
CONFIG_KEYBOARD_MTK_PMIC=y
CONFIG_KEYBOARD_CYPRESS_SF=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_BYD=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_ELANTECH_SMBUS=y
CONFIG_MOUSE_PS2_SENTELIC=y
CONFIG_MOUSE_PS2_TOUCHKIT=y
CONFIG_MOUSE_PS2_FOCALTECH=y
CONFIG_MOUSE_PS2_SMBUS=y
CONFIG_MOUSE_SERIAL=y
CONFIG_MOUSE_APPLETOUCH=y
CONFIG_MOUSE_BCM5974=y
CONFIG_MOUSE_CYAPA=y
CONFIG_MOUSE_ELAN_I2C=y
CONFIG_MOUSE_ELAN_I2C_I2C=y
CONFIG_MOUSE_ELAN_I2C_SMBUS=y
CONFIG_MOUSE_VSXXXAA=y
CONFIG_MOUSE_GPIO=y
CONFIG_MOUSE_SYNAPTICS_I2C=y
CONFIG_MOUSE_SYNAPTICS_USB=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=y
CONFIG_JOYSTICK_A3D=y
CONFIG_JOYSTICK_ADC=y
CONFIG_JOYSTICK_ADI=y
CONFIG_JOYSTICK_COBRA=y
CONFIG_JOYSTICK_GF2K=y
CONFIG_JOYSTICK_GRIP=y
CONFIG_JOYSTICK_GRIP_MP=y
CONFIG_JOYSTICK_GUILLEMOT=y
CONFIG_JOYSTICK_INTERACT=y
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
CONFIG_JOYSTICK_IFORCE=y
CONFIG_JOYSTICK_IFORCE_USB=y
CONFIG_JOYSTICK_IFORCE_232=y
CONFIG_JOYSTICK_WARRIOR=y
CONFIG_JOYSTICK_MAGELLAN=y
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
CONFIG_JOYSTICK_STINGER=y
CONFIG_JOYSTICK_TWIDJOY=y
CONFIG_JOYSTICK_ZHENHUA=y
CONFIG_JOYSTICK_DB9=y
CONFIG_JOYSTICK_GAMECON=y
CONFIG_JOYSTICK_TURBOGRAFX=y
CONFIG_JOYSTICK_AS5011=y
CONFIG_JOYSTICK_JOYDUMP=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_JOYSTICK_WALKERA0701=y
CONFIG_JOYSTICK_PSXPAD_SPI=y
CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
CONFIG_JOYSTICK_PXRC=y
CONFIG_JOYSTICK_QWIIC=y
CONFIG_JOYSTICK_FSIA6B=y
CONFIG_JOYSTICK_SENSEHAT=y
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_HANWANG=y
CONFIG_TABLET_USB_KBTAB=y
CONFIG_TABLET_USB_PEGASUS=y
CONFIG_TABLET_SERIAL_WACOM4=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_88PM860X=y
CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_TOUCHSCREEN_AD7877=y
CONFIG_TOUCHSCREEN_AD7879=y
CONFIG_TOUCHSCREEN_AD7879_I2C=y
CONFIG_TOUCHSCREEN_AD7879_SPI=y
CONFIG_TOUCHSCREEN_ADC=y
CONFIG_TOUCHSCREEN_AR1021_I2C=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y
CONFIG_TOUCHSCREEN_AUO_PIXCIR=y
CONFIG_TOUCHSCREEN_BU21013=y
CONFIG_TOUCHSCREEN_BU21029=y
CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=y
CONFIG_TOUCHSCREEN_CY8CTMA140=y
CONFIG_TOUCHSCREEN_CY8CTMG110=y
CONFIG_TOUCHSCREEN_CYTTSP_CORE=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
CONFIG_TOUCHSCREEN_CYTTSP_SPI=y
CONFIG_TOUCHSCREEN_CYTTSP4_CORE=y
CONFIG_TOUCHSCREEN_CYTTSP4_I2C=y
CONFIG_TOUCHSCREEN_CYTTSP4_SPI=y
CONFIG_TOUCHSCREEN_CYTTSP5=y
CONFIG_TOUCHSCREEN_DA9034=y
CONFIG_TOUCHSCREEN_DA9052=y
CONFIG_TOUCHSCREEN_DYNAPRO=y
CONFIG_TOUCHSCREEN_HAMPSHIRE=y
CONFIG_TOUCHSCREEN_EETI=y
CONFIG_TOUCHSCREEN_EGALAX=y
CONFIG_TOUCHSCREEN_EGALAX_SERIAL=y
CONFIG_TOUCHSCREEN_EXC3000=y
CONFIG_TOUCHSCREEN_FUJITSU=y
CONFIG_TOUCHSCREEN_GOODIX=y
CONFIG_TOUCHSCREEN_HIDEEP=y
CONFIG_TOUCHSCREEN_HYCON_HY46XX=y
CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=y
CONFIG_TOUCHSCREEN_ILI210X=y
CONFIG_TOUCHSCREEN_ILITEK=y
CONFIG_TOUCHSCREEN_IPROC=y
CONFIG_TOUCHSCREEN_S6SY761=y
CONFIG_TOUCHSCREEN_GUNZE=y
CONFIG_TOUCHSCREEN_EKTF2127=y
CONFIG_TOUCHSCREEN_ELAN=y
CONFIG_TOUCHSCREEN_ELO=y
CONFIG_TOUCHSCREEN_WACOM_W8001=y
CONFIG_TOUCHSCREEN_WACOM_I2C=y
CONFIG_TOUCHSCREEN_MAX11801=y
CONFIG_TOUCHSCREEN_MCS5000=y
CONFIG_TOUCHSCREEN_MMS114=y
CONFIG_TOUCHSCREEN_MELFAS_MIP4=y
CONFIG_TOUCHSCREEN_MSG2638=y
CONFIG_TOUCHSCREEN_MTOUCH=y
CONFIG_TOUCHSCREEN_IMAGIS=y
CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
CONFIG_TOUCHSCREEN_INEXIO=y
CONFIG_TOUCHSCREEN_MK712=y
CONFIG_TOUCHSCREEN_PENMOUNT=y
CONFIG_TOUCHSCREEN_EDT_FT5X06=y
CONFIG_TOUCHSCREEN_RASPBERRYPI_FW=y
CONFIG_TOUCHSCREEN_MIGOR=y
CONFIG_TOUCHSCREEN_TOUCHRIGHT=y
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=y
CONFIG_TOUCHSCREEN_PIXCIR=y
CONFIG_TOUCHSCREEN_WDT87XX_I2C=y
CONFIG_TOUCHSCREEN_WM831X=y
CONFIG_TOUCHSCREEN_WM97XX=y
CONFIG_TOUCHSCREEN_WM9705=y
CONFIG_TOUCHSCREEN_WM9712=y
CONFIG_TOUCHSCREEN_WM9713=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_TOUCHSCREEN_MXS_LRADC=y
CONFIG_TOUCHSCREEN_MX25=y
CONFIG_TOUCHSCREEN_MC13783=y
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
CONFIG_TOUCHSCREEN_TOUCHIT213=y
CONFIG_TOUCHSCREEN_TS4800=y
CONFIG_TOUCHSCREEN_TSC_SERIO=y
CONFIG_TOUCHSCREEN_TSC200X_CORE=y
CONFIG_TOUCHSCREEN_TSC2004=y
CONFIG_TOUCHSCREEN_TSC2005=y
CONFIG_TOUCHSCREEN_TSC2007=y
CONFIG_TOUCHSCREEN_TSC2007_IIO=y
CONFIG_TOUCHSCREEN_PCAP=y
CONFIG_TOUCHSCREEN_RM_TS=y
CONFIG_TOUCHSCREEN_SILEAD=y
CONFIG_TOUCHSCREEN_SIS_I2C=y
CONFIG_TOUCHSCREEN_ST1232=y
CONFIG_TOUCHSCREEN_STMFTS=y
CONFIG_TOUCHSCREEN_STMPE=y
CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_TOUCHSCREEN_SUR40=y
CONFIG_TOUCHSCREEN_SURFACE3_SPI=y
CONFIG_TOUCHSCREEN_SX8654=y
CONFIG_TOUCHSCREEN_TPS6507X=y
CONFIG_TOUCHSCREEN_ZET6223=y
CONFIG_TOUCHSCREEN_ZFORCE=y
CONFIG_TOUCHSCREEN_COLIBRI_VF50=y
CONFIG_TOUCHSCREEN_ROHM_BU21023=y
CONFIG_TOUCHSCREEN_IQS5XX=y
CONFIG_TOUCHSCREEN_ZINITIX=y
CONFIG_TOUCHSCREEN_HIMAX_HX83112B=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_88PM860X_ONKEY=y
CONFIG_INPUT_88PM80X_ONKEY=y
CONFIG_INPUT_AB8500_PONKEY=y
CONFIG_INPUT_AD714X=y
CONFIG_INPUT_AD714X_I2C=y
CONFIG_INPUT_AD714X_SPI=y
CONFIG_INPUT_ARIEL_PWRBUTTON=y
CONFIG_INPUT_ARIZONA_HAPTICS=y
CONFIG_INPUT_ATC260X_ONKEY=y
CONFIG_INPUT_ATMEL_CAPTOUCH=y
CONFIG_INPUT_BMA150=y
CONFIG_INPUT_E3X0_BUTTON=y
CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_PM8XXX_VIBRATOR=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_MAX77650_ONKEY=y
CONFIG_INPUT_MAX77693_HAPTIC=y
CONFIG_INPUT_MAX8925_ONKEY=y
CONFIG_INPUT_MAX8997_HAPTIC=y
CONFIG_INPUT_MC13783_PWRBUTTON=y
CONFIG_INPUT_MMA8450=y
CONFIG_INPUT_GPIO_BEEPER=y
CONFIG_INPUT_GPIO_DECODER=y
CONFIG_INPUT_GPIO_VIBRA=y
CONFIG_INPUT_CPCAP_PWRBUTTON=y
CONFIG_INPUT_ATI_REMOTE2=y
CONFIG_INPUT_KEYSPAN_REMOTE=y
CONFIG_INPUT_KXTJ9=y
CONFIG_INPUT_POWERMATE=y
CONFIG_INPUT_YEALINK=y
CONFIG_INPUT_CM109=y
CONFIG_INPUT_REGULATOR_HAPTIC=y
CONFIG_INPUT_RETU_PWRBUTTON=y
CONFIG_INPUT_TPS65218_PWRBUTTON=y
CONFIG_INPUT_TPS65219_PWRBUTTON=y
CONFIG_INPUT_AXP20X_PEK=y
CONFIG_INPUT_TWL4030_PWRBUTTON=y
CONFIG_INPUT_TWL4030_VIBRA=y
CONFIG_INPUT_TWL6040_VIBRA=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PALMAS_PWRBUTTON=y
CONFIG_INPUT_PCF50633_PMU=y
CONFIG_INPUT_PCF8574=y
CONFIG_INPUT_PWM_BEEPER=y
CONFIG_INPUT_PWM_VIBRA=y
CONFIG_INPUT_RK805_PWRKEY=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
CONFIG_INPUT_DA7280_HAPTICS=y
CONFIG_INPUT_DA9052_ONKEY=y
CONFIG_INPUT_DA9055_ONKEY=y
CONFIG_INPUT_DA9063_ONKEY=y
CONFIG_INPUT_WM831X_ON=y
CONFIG_INPUT_PCAP=y
CONFIG_INPUT_ADXL34X=y
CONFIG_INPUT_ADXL34X_I2C=y
CONFIG_INPUT_ADXL34X_SPI=y
CONFIG_INPUT_IBM_PANEL=y
CONFIG_INPUT_IMS_PCU=y
CONFIG_INPUT_IQS269A=y
CONFIG_INPUT_IQS626A=y
CONFIG_INPUT_IQS7222=y
CONFIG_INPUT_CMA3000=y
CONFIG_INPUT_CMA3000_I2C=y
CONFIG_INPUT_DRV260X_HAPTICS=y
CONFIG_INPUT_DRV2665_HAPTICS=y
CONFIG_INPUT_DRV2667_HAPTICS=y
CONFIG_INPUT_HISI_POWERKEY=y
CONFIG_INPUT_RAVE_SP_PWRBUTTON=y
CONFIG_INPUT_SC27XX_VIBRA=y
CONFIG_INPUT_RT5120_PWRKEY=y
CONFIG_INPUT_STPMIC1_ONKEY=y
CONFIG_RMI4_CORE=y
CONFIG_RMI4_I2C=y
CONFIG_RMI4_SPI=y
CONFIG_RMI4_SMB=y
CONFIG_RMI4_F03=y
CONFIG_RMI4_F03_SERIO=y
CONFIG_RMI4_2D_SENSOR=y
CONFIG_RMI4_F11=y
CONFIG_RMI4_F12=y
CONFIG_RMI4_F30=y
CONFIG_RMI4_F34=y
CONFIG_RMI4_F3A=y
CONFIG_RMI4_F54=y
CONFIG_RMI4_F55=y
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_PARKBD=y
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIO_PCIPS2=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_SERIO_ALTERA_PS2=y
CONFIG_SERIO_PS2MULT=y
CONFIG_SERIO_ARC_PS2=y
CONFIG_SERIO_APBPS2=y
CONFIG_SERIO_OLPC_APSP=y
CONFIG_SERIO_SUN4I_PS2=y
CONFIG_SERIO_GPIO_PS2=y
CONFIG_USERIO=y
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=y
CONFIG_GAMEPORT_L4=y
CONFIG_GAMEPORT_EMU10K1=y
CONFIG_GAMEPORT_FM801=y
# end of Hardware I/O ports
# end of Input device support
#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LEGACY_TIOCSTI=y
CONFIG_LDISC_AUTOLOAD=y
#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_16550A_VARIANTS=y
CONFIG_SERIAL_8250_FINTEK=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_EXAR=y
CONFIG_SERIAL_8250_CS=y
CONFIG_SERIAL_8250_MEN_MCB=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_ASPEED_VUART=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_DWLIB=y
CONFIG_SERIAL_8250_BCM2835AUX=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_EM=y
CONFIG_SERIAL_8250_IOC3=y
CONFIG_SERIAL_8250_RT288X=y
CONFIG_SERIAL_8250_OMAP=y
CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP=y
CONFIG_SERIAL_8250_LPC18XX=y
CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_8250_UNIPHIER=y
CONFIG_SERIAL_8250_INGENIC=y
CONFIG_SERIAL_8250_LPSS=y
CONFIG_SERIAL_8250_MID=y
CONFIG_SERIAL_8250_PERICOM=y
CONFIG_SERIAL_8250_PXA=y
CONFIG_SERIAL_8250_TEGRA=y
CONFIG_SERIAL_8250_BCM7271=y
CONFIG_SERIAL_OF_PLATFORM=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_AMBA_PL010=y
CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST=y
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_SERIAL_ATMEL_PDC=y
CONFIG_SERIAL_ATMEL_TTYAT=y
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_SERIAL_MESON=y
CONFIG_SERIAL_MESON_CONSOLE=y
CONFIG_SERIAL_CLPS711X=y
CONFIG_SERIAL_CLPS711X_CONSOLE=y
CONFIG_SERIAL_SAMSUNG=y
CONFIG_SERIAL_SAMSUNG_UARTS_4=y
CONFIG_SERIAL_SAMSUNG_UARTS=4
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_TEGRA=y
CONFIG_SERIAL_TEGRA_TCU=y
CONFIG_SERIAL_TEGRA_TCU_CONSOLE=y
CONFIG_SERIAL_MAX3100=y
CONFIG_SERIAL_MAX310X=y
CONFIG_SERIAL_PXA=y
CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_IMX_EARLYCON=y
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_SERIAL_UARTLITE_NR_UARTS=1
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=18
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_SH_SCI_EARLYCON=y
CONFIG_SERIAL_SH_SCI_DMA=y
CONFIG_SERIAL_HS_LPC32XX=y
CONFIG_SERIAL_HS_LPC32XX_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_ICOM=y
CONFIG_SERIAL_JSM=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_QCOM_GENI=y
CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
CONFIG_SERIAL_VT8500=y
CONFIG_SERIAL_VT8500_CONSOLE=y
CONFIG_SERIAL_OMAP=y
CONFIG_SERIAL_OMAP_CONSOLE=y
CONFIG_SERIAL_SIFIVE=y
CONFIG_SERIAL_SIFIVE_CONSOLE=y
CONFIG_SERIAL_LANTIQ=y
CONFIG_SERIAL_LANTIQ_CONSOLE=y
CONFIG_SERIAL_QE=y
CONFIG_SERIAL_SCCNXP=y
CONFIG_SERIAL_SCCNXP_CONSOLE=y
CONFIG_SERIAL_SC16IS7XX_CORE=y
CONFIG_SERIAL_SC16IS7XX=y
CONFIG_SERIAL_SC16IS7XX_I2C=y
CONFIG_SERIAL_SC16IS7XX_SPI=y
CONFIG_SERIAL_TIMBERDALE=y
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
CONFIG_SERIAL_ALTERA_JTAGUART=y
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE=y
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS=y
CONFIG_SERIAL_ALTERA_UART=y
CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
CONFIG_SERIAL_ALTERA_UART_CONSOLE=y
CONFIG_SERIAL_PCH_UART=y
CONFIG_SERIAL_PCH_UART_CONSOLE=y
CONFIG_SERIAL_MXS_AUART=y
CONFIG_SERIAL_MXS_AUART_CONSOLE=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SERIAL_MPS2_UART_CONSOLE=y
CONFIG_SERIAL_MPS2_UART=y
CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
CONFIG_SERIAL_ARC_NR_PORTS=1
CONFIG_SERIAL_RP2=y
CONFIG_SERIAL_RP2_NR_UARTS=32
CONFIG_SERIAL_FSL_LPUART=y
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_FSL_LINFLEXUART=y
CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_SERIAL_MEN_Z135=y
CONFIG_SERIAL_SPRD=y
CONFIG_SERIAL_SPRD_CONSOLE=y
CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_MVEBU_CONSOLE=y
CONFIG_SERIAL_OWL=y
CONFIG_SERIAL_OWL_CONSOLE=y
CONFIG_SERIAL_RDA=y
CONFIG_SERIAL_RDA_CONSOLE=y
CONFIG_SERIAL_MILBEAUT_USIO=y
CONFIG_SERIAL_MILBEAUT_USIO_PORTS=4
CONFIG_SERIAL_MILBEAUT_USIO_CONSOLE=y
CONFIG_SERIAL_LITEUART=y
CONFIG_SERIAL_LITEUART_MAX_PORTS=1
CONFIG_SERIAL_LITEUART_CONSOLE=y
CONFIG_SERIAL_SUNPLUS=y
CONFIG_SERIAL_SUNPLUS_CONSOLE=y
# end of Serial drivers
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_MOXA_INTELLIO=y
CONFIG_MOXA_SMARTIO=y
CONFIG_SYNCLINK_GT=y
CONFIG_N_HDLC=y
CONFIG_GOLDFISH_TTY=y
CONFIG_GOLDFISH_TTY_EARLY_CONSOLE=y
CONFIG_N_GSM=y
CONFIG_NOZOMI=y
CONFIG_NULL_TTY=y
CONFIG_HVC_DRIVER=y
CONFIG_HVC_DCC=y
CONFIG_HVC_DCC_SERIALIZE_SMP=y
CONFIG_RPMSG_TTY=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
CONFIG_TTY_PRINTK=y
CONFIG_TTY_PRINTK_LEVEL=6
CONFIG_PRINTER=y
CONFIG_LP_CONSOLE=y
CONFIG_PPDEV=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_IPMI_HANDLER=y
CONFIG_IPMI_DMI_DECODE=y
CONFIG_IPMI_PLAT_DATA=y
CONFIG_IPMI_PANIC_EVENT=y
CONFIG_IPMI_PANIC_STRING=y
CONFIG_IPMI_DEVICE_INTERFACE=y
CONFIG_IPMI_SI=y
CONFIG_IPMI_SSIF=y
CONFIG_IPMI_IPMB=y
CONFIG_IPMI_WATCHDOG=y
CONFIG_IPMI_POWEROFF=y
CONFIG_IPMI_KCS_BMC=y
CONFIG_ASPEED_KCS_IPMI_BMC=y
CONFIG_NPCM7XX_KCS_IPMI_BMC=y
CONFIG_IPMI_KCS_BMC_CDEV_IPMI=y
CONFIG_IPMI_KCS_BMC_SERIO=y
CONFIG_ASPEED_BT_IPMI_BMC=y
CONFIG_SSIF_IPMI_BMC=y
CONFIG_IPMB_DEVICE_INTERFACE=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_HW_RANDOM_ATMEL=y
CONFIG_HW_RANDOM_BA431=y
CONFIG_HW_RANDOM_BCM2835=y
CONFIG_HW_RANDOM_IPROC_RNG200=y
CONFIG_HW_RANDOM_IXP4XX=y
CONFIG_HW_RANDOM_OMAP=y
CONFIG_HW_RANDOM_OMAP3_ROM=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_HW_RANDOM_MXC_RNGA=y
CONFIG_HW_RANDOM_IMX_RNGC=y
CONFIG_HW_RANDOM_NOMADIK=y
CONFIG_HW_RANDOM_HISI=y
CONFIG_HW_RANDOM_ST=y
CONFIG_HW_RANDOM_STM32=y
CONFIG_HW_RANDOM_POLARFIRE_SOC=y
CONFIG_HW_RANDOM_MESON=y
CONFIG_HW_RANDOM_MTK=y
CONFIG_HW_RANDOM_EXYNOS=y
CONFIG_HW_RANDOM_OPTEE=y
CONFIG_HW_RANDOM_NPCM=y
CONFIG_HW_RANDOM_KEYSTONE=y
CONFIG_HW_RANDOM_CCTRNG=y
CONFIG_HW_RANDOM_XIPHERA=y
CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y
CONFIG_APPLICOM=y
#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=y
CONFIG_CARDMAN_4000=y
CONFIG_CARDMAN_4040=y
CONFIG_SCR24X=y
CONFIG_IPWIRELESS=y
# end of PCMCIA character devices
CONFIG_DEVMEM=y
CONFIG_DEVPORT=y
CONFIG_TCG_TPM=y
CONFIG_HW_RANDOM_TPM=y
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS=y
CONFIG_TCG_TIS_SPI=y
CONFIG_TCG_TIS_SPI_CR50=y
CONFIG_TCG_TIS_I2C=y
CONFIG_TCG_TIS_SYNQUACER=y
CONFIG_TCG_TIS_I2C_CR50=y
CONFIG_TCG_TIS_I2C_ATMEL=y
CONFIG_TCG_TIS_I2C_INFINEON=y
CONFIG_TCG_TIS_I2C_NUVOTON=y
CONFIG_TCG_VTPM_PROXY=y
CONFIG_TCG_FTPM_TEE=y
CONFIG_TCG_TIS_ST33ZP24=y
CONFIG_TCG_TIS_ST33ZP24_I2C=y
CONFIG_TCG_TIS_ST33ZP24_SPI=y
CONFIG_XILLYBUS_CLASS=y
CONFIG_XILLYBUS=y
CONFIG_XILLYBUS_PCIE=y
CONFIG_XILLYBUS_OF=y
CONFIG_XILLYUSB=y
# end of Character devices
#
# I2C support
#
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
#
# Multiplexer I2C Chip support
#
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_I2C_MUX_GPIO=y
CONFIG_I2C_MUX_GPMUX=y
CONFIG_I2C_MUX_LTC4306=y
CONFIG_I2C_MUX_PCA9541=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_MUX_REG=y
CONFIG_I2C_DEMUX_PINCTRL=y
CONFIG_I2C_MUX_MLXCPLD=y
# end of Multiplexer I2C Chip support
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCA=y
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
CONFIG_I2C_CCGX_UCSI=y
CONFIG_I2C_ALI1535=y
CONFIG_I2C_ALI1563=y
CONFIG_I2C_ALI15X3=y
CONFIG_I2C_AMD756=y
CONFIG_I2C_AMD8111=y
CONFIG_I2C_HIX5HD2=y
CONFIG_I2C_I801=y
CONFIG_I2C_ISCH=y
CONFIG_I2C_PIIX4=y
CONFIG_I2C_NFORCE2=y
CONFIG_I2C_NVIDIA_GPU=y
CONFIG_I2C_SIS5595=y
CONFIG_I2C_SIS630=y
CONFIG_I2C_SIS96X=y
CONFIG_I2C_VIA=y
CONFIG_I2C_VIAPRO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_ALTERA=y
CONFIG_I2C_ASPEED=y
CONFIG_I2C_AT91=y
CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL=y
CONFIG_I2C_AXXIA=y
CONFIG_I2C_BCM2835=y
CONFIG_I2C_BCM_IPROC=y
CONFIG_I2C_BCM_KONA=y
CONFIG_I2C_BRCMSTB=y
CONFIG_I2C_CADENCE=y
CONFIG_I2C_CBUS_GPIO=y
CONFIG_I2C_DAVINCI=y
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_SLAVE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_DESIGNWARE_PCI=y
CONFIG_I2C_DIGICOLOR=y
CONFIG_I2C_EG20T=y
CONFIG_I2C_EMEV2=y
CONFIG_I2C_EXYNOS5=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_GPIO_FAULT_INJECTOR=y
CONFIG_I2C_HIGHLANDER=y
CONFIG_I2C_HISI=y
CONFIG_I2C_IMG=y
CONFIG_I2C_IMX=y
CONFIG_I2C_IMX_LPI2C=y
CONFIG_I2C_IOP3XX=y
CONFIG_I2C_JZ4780=y
CONFIG_I2C_KEMPLD=y
CONFIG_I2C_LPC2K=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MICROCHIP_CORE=y
CONFIG_I2C_MT65XX=y
CONFIG_I2C_MT7621=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_MXS=y
CONFIG_I2C_NOMADIK=y
CONFIG_I2C_NPCM=y
CONFIG_I2C_OCORES=y
CONFIG_I2C_OMAP=y
CONFIG_I2C_OWL=y
CONFIG_I2C_APPLE=y
CONFIG_I2C_PCA_PLATFORM=y
CONFIG_I2C_PNX=y
CONFIG_I2C_PXA=y
CONFIG_I2C_PXA_SLAVE=y
CONFIG_I2C_QCOM_CCI=y
CONFIG_I2C_QCOM_GENI=y
CONFIG_I2C_QUP=y
CONFIG_I2C_RIIC=y
CONFIG_I2C_RK3X=y
CONFIG_I2C_RZV2M=y
CONFIG_I2C_S3C2410=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_I2C_SIMTEC=y
CONFIG_I2C_SPRD=y
CONFIG_I2C_ST=y
CONFIG_I2C_STM32F4=y
CONFIG_I2C_STM32F7=y
CONFIG_I2C_SUN6I_P2WI=y
CONFIG_I2C_SYNQUACER=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_TEGRA_BPMP=y
CONFIG_I2C_UNIPHIER=y
CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_VERSATILE=y
CONFIG_I2C_WMT=y
CONFIG_I2C_XILINX=y
CONFIG_I2C_XLP9XX=y
CONFIG_I2C_RCAR=y
#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_DIOLAN_U2C=y
CONFIG_I2C_DLN2=y
CONFIG_I2C_CP2615=y
CONFIG_I2C_PARPORT=y
CONFIG_I2C_PCI1XXXX=y
CONFIG_I2C_ROBOTFUZZ_OSIF=y
CONFIG_I2C_TAOS_EVM=y
CONFIG_I2C_TINY_USB=y
CONFIG_I2C_VIPERBOARD=y
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_MLXCPLD=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_FSI=y
CONFIG_I2C_VIRTIO=y
# end of I2C Hardware Bus support
CONFIG_I2C_STUB=m
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y
CONFIG_I2C_SLAVE_TESTUNIT=y
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
# end of I2C support
CONFIG_I3C=y
CONFIG_CDNS_I3C_MASTER=y
CONFIG_DW_I3C_MASTER=y
CONFIG_SVC_I3C_MASTER=y
CONFIG_MIPI_I3C_HCI=y
CONFIG_SPI=y
CONFIG_SPI_DEBUG=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
#
# SPI Master Controller Drivers
#
CONFIG_SPI_ALTERA=y
CONFIG_SPI_ALTERA_CORE=y
CONFIG_SPI_ALTERA_DFL=y
CONFIG_SPI_AR934X=y
CONFIG_SPI_ATH79=y
CONFIG_SPI_ARMADA_3700=y
CONFIG_SPI_ASPEED_SMC=y
CONFIG_SPI_ATMEL=y
CONFIG_SPI_AT91_USART=y
CONFIG_SPI_ATMEL_QUADSPI=y
CONFIG_SPI_AXI_SPI_ENGINE=y
CONFIG_SPI_BCM2835=y
CONFIG_SPI_BCM2835AUX=y
CONFIG_SPI_BCM63XX=y
CONFIG_SPI_BCM63XX_HSSPI=y
CONFIG_SPI_BCM_QSPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_BUTTERFLY=y
CONFIG_SPI_CADENCE=y
CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_SPI_CADENCE_XSPI=y
CONFIG_SPI_CLPS711X=y
CONFIG_SPI_DAVINCI=y
CONFIG_SPI_DESIGNWARE=y
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_PCI=y
CONFIG_SPI_DW_MMIO=y
CONFIG_SPI_DW_BT1=y
CONFIG_SPI_DW_BT1_DIRMAP=y
CONFIG_SPI_DLN2=y
CONFIG_SPI_EP93XX=y
CONFIG_SPI_FSI=y
CONFIG_SPI_FSL_LPSPI=y
CONFIG_SPI_FSL_QUADSPI=y
CONFIG_SPI_GXP=y
CONFIG_SPI_HISI_KUNPENG=y
CONFIG_SPI_HISI_SFC_V3XX=y
CONFIG_SPI_NXP_FLEXSPI=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_IMG_SPFI=y
CONFIG_SPI_IMX=y
CONFIG_SPI_INGENIC=y
CONFIG_SPI_INTEL=y
CONFIG_SPI_INTEL_PCI=y
CONFIG_SPI_INTEL_PLATFORM=y
CONFIG_SPI_JCORE=y
CONFIG_SPI_LM70_LLP=y
CONFIG_SPI_LP8841_RTC=y
CONFIG_SPI_FSL_LIB=y
CONFIG_SPI_FSL_SPI=y
CONFIG_SPI_FSL_DSPI=y
CONFIG_SPI_MESON_SPICC=y
CONFIG_SPI_MESON_SPIFC=y
CONFIG_SPI_MICROCHIP_CORE=y
CONFIG_SPI_MICROCHIP_CORE_QSPI=y
CONFIG_SPI_MT65XX=y
CONFIG_SPI_MT7621=y
CONFIG_SPI_MTK_NOR=y
CONFIG_SPI_MTK_SNFI=y
CONFIG_SPI_WPCM_FIU=y
CONFIG_SPI_NPCM_FIU=y
CONFIG_SPI_NPCM_PSPI=y
CONFIG_SPI_LANTIQ_SSC=y
CONFIG_SPI_OC_TINY=y
CONFIG_SPI_OMAP_UWIRE=y
CONFIG_SPI_OMAP24XX=y
CONFIG_SPI_TI_QSPI=y
CONFIG_SPI_ORION=y
CONFIG_SPI_PCI1XXXX=y
CONFIG_SPI_PIC32=y
CONFIG_SPI_PIC32_SQI=y
CONFIG_SPI_PL022=y
CONFIG_SPI_PXA2XX=y
CONFIG_SPI_PXA2XX_PCI=y
CONFIG_SPI_ROCKCHIP=y
CONFIG_SPI_ROCKCHIP_SFC=y
CONFIG_SPI_RPCIF=y
CONFIG_SPI_RSPI=y
CONFIG_SPI_QCOM_QSPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_QCOM_GENI=y
CONFIG_SPI_S3C64XX=y
CONFIG_SPI_SC18IS602=y
CONFIG_SPI_SH_MSIOF=y
CONFIG_SPI_SH=y
CONFIG_SPI_SH_HSPI=y
CONFIG_SPI_SIFIVE=y
CONFIG_SPI_SLAVE_MT27XX=y
CONFIG_SPI_SN_F_OSPI=y
CONFIG_SPI_SPRD=y
CONFIG_SPI_SPRD_ADI=y
CONFIG_SPI_STM32=y
CONFIG_SPI_STM32_QSPI=y
CONFIG_SPI_ST_SSC4=y
CONFIG_SPI_SUN4I=y
CONFIG_SPI_SUN6I=y
CONFIG_SPI_SUNPLUS_SP7021=y
CONFIG_SPI_SYNQUACER=y
CONFIG_SPI_MXIC=y
CONFIG_SPI_TEGRA210_QUAD=y
CONFIG_SPI_TEGRA114=y
CONFIG_SPI_TEGRA20_SFLASH=y
CONFIG_SPI_TEGRA20_SLINK=y
CONFIG_SPI_TOPCLIFF_PCH=y
CONFIG_SPI_UNIPHIER=y
CONFIG_SPI_XCOMM=y
CONFIG_SPI_XILINX=y
CONFIG_SPI_XLP=y
CONFIG_SPI_XTENSA_XTFPGA=y
CONFIG_SPI_ZYNQ_QSPI=y
CONFIG_SPI_ZYNQMP_GQSPI=y
CONFIG_SPI_AMD=y
#
# SPI Multiplexer support
#
CONFIG_SPI_MUX=y
#
# SPI Protocol Masters
#
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_LOOPBACK_TEST=m
CONFIG_SPI_TLE62X0=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=y
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
CONFIG_SPI_DYNAMIC=y
CONFIG_SPMI=y
CONFIG_SPMI_HISI3670=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_SPMI_MTK_PMIF=y
CONFIG_HSI=y
CONFIG_HSI_BOARDINFO=y
#
# HSI controllers
#
CONFIG_OMAP_SSI=y
#
# HSI clients
#
CONFIG_NOKIA_MODEM=y
CONFIG_CMT_SPEECH=y
CONFIG_SSI_PROTOCOL=y
CONFIG_HSI_CHAR=y
CONFIG_PPS=y
CONFIG_PPS_DEBUG=y
#
# PPS clients support
#
CONFIG_PPS_CLIENT_KTIMER=y
CONFIG_PPS_CLIENT_LDISC=y
CONFIG_PPS_CLIENT_PARPORT=y
CONFIG_PPS_CLIENT_GPIO=y
#
# PPS generators support
#
#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PTP_1588_CLOCK_DTE=y
CONFIG_PTP_1588_CLOCK_QORIQ=y
CONFIG_DP83640_PHY=y
CONFIG_PTP_1588_CLOCK_INES=y
CONFIG_PTP_1588_CLOCK_PCH=y
CONFIG_PTP_1588_CLOCK_KVM=y
CONFIG_PTP_1588_CLOCK_IDT82P33=y
CONFIG_PTP_1588_CLOCK_IDTCM=y
CONFIG_PTP_1588_CLOCK_OCP=y
# end of PTP clock support
CONFIG_PINCTRL=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_PINMUX=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_PINCONF=y
CONFIG_GENERIC_PINCONF=y
CONFIG_DEBUG_PINCTRL=y
CONFIG_PINCTRL_AMD=y
CONFIG_PINCTRL_ARTPEC6=y
CONFIG_PINCTRL_AS3722=y
CONFIG_PINCTRL_AT91=y
CONFIG_PINCTRL_AT91PIO4=y
CONFIG_PINCTRL_AXP209=y
CONFIG_PINCTRL_BM1880=y
CONFIG_PINCTRL_CY8C95X0=y
CONFIG_PINCTRL_DA850_PUPD=y
CONFIG_PINCTRL_DA9062=y
CONFIG_PINCTRL_DIGICOLOR=y
CONFIG_PINCTRL_EQUILIBRIUM=y
CONFIG_PINCTRL_INGENIC=y
CONFIG_PINCTRL_LOONGSON2=y
CONFIG_PINCTRL_LPC18XX=y
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_MCP23S08_I2C=y
CONFIG_PINCTRL_MCP23S08_SPI=y
CONFIG_PINCTRL_MCP23S08=y
CONFIG_PINCTRL_MICROCHIP_SGPIO=y
CONFIG_PINCTRL_OCELOT=y
CONFIG_PINCTRL_OXNAS=y
CONFIG_PINCTRL_PALMAS=y
CONFIG_PINCTRL_PISTACHIO=y
CONFIG_PINCTRL_RK805=y
CONFIG_PINCTRL_ROCKCHIP=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_ST=y
CONFIG_PINCTRL_STMFX=y
CONFIG_PINCTRL_SX150X=y
CONFIG_PINCTRL_ZYNQ=y
CONFIG_PINCTRL_OWL=y
CONFIG_PINCTRL_S500=y
CONFIG_PINCTRL_S700=y
CONFIG_PINCTRL_S900=y
CONFIG_PINCTRL_ASPEED=y
CONFIG_PINCTRL_ASPEED_G4=y
CONFIG_PINCTRL_ASPEED_G5=y
CONFIG_PINCTRL_ASPEED_G6=y
CONFIG_PINCTRL_BCM281XX=y
CONFIG_PINCTRL_BCM2835=y
CONFIG_PINCTRL_BCM4908=y
CONFIG_PINCTRL_BCM63XX=y
CONFIG_PINCTRL_BCM6318=y
CONFIG_PINCTRL_BCM6328=y
CONFIG_PINCTRL_BCM6358=y
CONFIG_PINCTRL_BCM6362=y
CONFIG_PINCTRL_BCM6368=y
CONFIG_PINCTRL_BCM63268=y
CONFIG_PINCTRL_IPROC_GPIO=y
CONFIG_PINCTRL_CYGNUS_MUX=y
CONFIG_PINCTRL_NS=y
CONFIG_PINCTRL_NSP_GPIO=y
CONFIG_PINCTRL_NS2_MUX=y
CONFIG_PINCTRL_NSP_MUX=y
CONFIG_PINCTRL_BERLIN=y
CONFIG_PINCTRL_AS370=y
CONFIG_PINCTRL_BERLIN_BG2=y
CONFIG_PINCTRL_BERLIN_BG2CD=y
CONFIG_PINCTRL_BERLIN_BG2Q=y
CONFIG_PINCTRL_BERLIN_BG4CT=y
CONFIG_PINCTRL_LOCHNAGAR=y
CONFIG_PINCTRL_MADERA=y
CONFIG_PINCTRL_CS47L15=y
CONFIG_PINCTRL_CS47L35=y
CONFIG_PINCTRL_CS47L85=y
CONFIG_PINCTRL_CS47L90=y
CONFIG_PINCTRL_CS47L92=y
CONFIG_PINCTRL_IMX=y
CONFIG_PINCTRL_IMX35=y
CONFIG_PINCTRL_IMX50=y
CONFIG_PINCTRL_IMX51=y
CONFIG_PINCTRL_IMX53=y
CONFIG_PINCTRL_IMX6Q=y
CONFIG_PINCTRL_IMX6SL=y
CONFIG_PINCTRL_IMX6SLL=y
CONFIG_PINCTRL_IMX6SX=y
CONFIG_PINCTRL_IMX6UL=y
CONFIG_PINCTRL_IMX7D=y
CONFIG_PINCTRL_IMX7ULP=y
CONFIG_PINCTRL_IMX8MM=y
CONFIG_PINCTRL_IMX8MN=y
CONFIG_PINCTRL_IMX8MP=y
CONFIG_PINCTRL_IMX8MQ=y
CONFIG_PINCTRL_IMX8ULP=y
CONFIG_PINCTRL_IMXRT1050=y
CONFIG_PINCTRL_IMX93=y
CONFIG_PINCTRL_VF610=y
CONFIG_PINCTRL_IMXRT1170=y
#
# Intel pinctrl drivers
#
# end of Intel pinctrl drivers
#
# MediaTek pinctrl drivers
#
CONFIG_EINT_MTK=y
CONFIG_PINCTRL_MTK=y
CONFIG_PINCTRL_MTK_V2=y
CONFIG_PINCTRL_MTK_MOORE=y
CONFIG_PINCTRL_MTK_PARIS=y
CONFIG_PINCTRL_MT2701=y
CONFIG_PINCTRL_MT7623=y
CONFIG_PINCTRL_MT7629=y
CONFIG_PINCTRL_MT8135=y
CONFIG_PINCTRL_MT8127=y
CONFIG_PINCTRL_MT2712=y
CONFIG_PINCTRL_MT6765=y
CONFIG_PINCTRL_MT6779=y
CONFIG_PINCTRL_MT6795=y
CONFIG_PINCTRL_MT6797=y
CONFIG_PINCTRL_MT7622=y
CONFIG_PINCTRL_MT7986=y
CONFIG_PINCTRL_MT8167=y
CONFIG_PINCTRL_MT8173=y
CONFIG_PINCTRL_MT8183=y
CONFIG_PINCTRL_MT8186=y
CONFIG_PINCTRL_MT8188=y
CONFIG_PINCTRL_MT8192=y
CONFIG_PINCTRL_MT8195=y
CONFIG_PINCTRL_MT8365=y
CONFIG_PINCTRL_MT8516=y
CONFIG_PINCTRL_MT6397=y
# end of MediaTek pinctrl drivers
CONFIG_PINCTRL_MESON=y
CONFIG_PINCTRL_MESON8=y
CONFIG_PINCTRL_MESON8B=y
CONFIG_PINCTRL_MESON8_PMX=y
CONFIG_PINCTRL_MVEBU=y
CONFIG_PINCTRL_DOVE=y
CONFIG_PINCTRL_ARMADA_370=y
CONFIG_PINCTRL_ARMADA_375=y
CONFIG_PINCTRL_ARMADA_38X=y
CONFIG_PINCTRL_ARMADA_39X=y
CONFIG_PINCTRL_ARMADA_XP=y
CONFIG_PINCTRL_ABX500=y
CONFIG_PINCTRL_AB8500=y
CONFIG_PINCTRL_AB8505=y
CONFIG_PINCTRL_NOMADIK=y
CONFIG_PINCTRL_DB8500=y
CONFIG_PINCTRL_WPCM450=y
CONFIG_PINCTRL_NPCM7XX=y
CONFIG_PINCTRL_PXA=y
CONFIG_PINCTRL_PXA25X=y
CONFIG_PINCTRL_PXA27X=y
CONFIG_PINCTRL_MSM=y
CONFIG_PINCTRL_APQ8064=y
CONFIG_PINCTRL_APQ8084=y
CONFIG_PINCTRL_IPQ4019=y
CONFIG_PINCTRL_IPQ8064=y
CONFIG_PINCTRL_IPQ8074=y
CONFIG_PINCTRL_IPQ6018=y
CONFIG_PINCTRL_MSM8226=y
CONFIG_PINCTRL_MSM8660=y
CONFIG_PINCTRL_MSM8960=y
CONFIG_PINCTRL_MDM9607=y
CONFIG_PINCTRL_MDM9615=y
CONFIG_PINCTRL_MSM8X74=y
CONFIG_PINCTRL_MSM8909=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_MSM8953=y
CONFIG_PINCTRL_MSM8976=y
CONFIG_PINCTRL_MSM8994=y
CONFIG_PINCTRL_MSM8996=y
CONFIG_PINCTRL_MSM8998=y
CONFIG_PINCTRL_QCM2290=y
CONFIG_PINCTRL_QCS404=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_PINCTRL_QDU1000=y
CONFIG_PINCTRL_SC7180=y
CONFIG_PINCTRL_SC7280=y
CONFIG_PINCTRL_SC7280_LPASS_LPI=y
CONFIG_PINCTRL_SC8180X=y
CONFIG_PINCTRL_SC8280XP=y
CONFIG_PINCTRL_SDM660=y
CONFIG_PINCTRL_SDM670=y
CONFIG_PINCTRL_SDM845=y
CONFIG_PINCTRL_SDX55=y
CONFIG_PINCTRL_SM6115=y
CONFIG_PINCTRL_SM6125=y
CONFIG_PINCTRL_SM6350=y
CONFIG_PINCTRL_SM6375=y
CONFIG_PINCTRL_SDX65=y
CONFIG_PINCTRL_SM8150=y
CONFIG_PINCTRL_SM8250=y
CONFIG_PINCTRL_SM8250_LPASS_LPI=y
CONFIG_PINCTRL_SM8350=y
CONFIG_PINCTRL_SM8450=y
CONFIG_PINCTRL_SM8450_LPASS_LPI=y
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=y
CONFIG_PINCTRL_LPASS_LPI=y
#
# Renesas pinctrl drivers
#
CONFIG_PINCTRL_RENESAS=y
CONFIG_PINCTRL_SH_PFC=y
CONFIG_PINCTRL_SH_PFC_GPIO=y
CONFIG_PINCTRL_SH_FUNC_GPIO=y
CONFIG_PINCTRL_PFC_EMEV2=y
CONFIG_PINCTRL_PFC_R8A77995=y
CONFIG_PINCTRL_PFC_R8A7794=y
CONFIG_PINCTRL_PFC_R8A77990=y
CONFIG_PINCTRL_PFC_R8A7779=y
CONFIG_PINCTRL_PFC_R8A7790=y
CONFIG_PINCTRL_PFC_R8A77950=y
CONFIG_PINCTRL_PFC_R8A77951=y
CONFIG_PINCTRL_PFC_R8A7778=y
CONFIG_PINCTRL_PFC_R8A7793=y
CONFIG_PINCTRL_PFC_R8A7791=y
CONFIG_PINCTRL_PFC_R8A77965=y
CONFIG_PINCTRL_PFC_R8A77960=y
CONFIG_PINCTRL_PFC_R8A77961=y
CONFIG_PINCTRL_PFC_R8A779F0=y
CONFIG_PINCTRL_PFC_R8A7792=y
CONFIG_PINCTRL_PFC_R8A77980=y
CONFIG_PINCTRL_PFC_R8A77970=y
CONFIG_PINCTRL_PFC_R8A779A0=y
CONFIG_PINCTRL_PFC_R8A779G0=y
CONFIG_PINCTRL_PFC_R8A7740=y
CONFIG_PINCTRL_PFC_R8A73A4=y
CONFIG_PINCTRL_RZA1=y
CONFIG_PINCTRL_RZA2=y
CONFIG_PINCTRL_RZG2L=y
CONFIG_PINCTRL_PFC_R8A77470=y
CONFIG_PINCTRL_PFC_R8A7745=y
CONFIG_PINCTRL_PFC_R8A7742=y
CONFIG_PINCTRL_PFC_R8A7743=y
CONFIG_PINCTRL_PFC_R8A7744=y
CONFIG_PINCTRL_PFC_R8A774C0=y
CONFIG_PINCTRL_PFC_R8A774E1=y
CONFIG_PINCTRL_PFC_R8A774A1=y
CONFIG_PINCTRL_PFC_R8A774B1=y
CONFIG_PINCTRL_RZN1=y
CONFIG_PINCTRL_RZV2M=y
CONFIG_PINCTRL_PFC_SH7203=y
CONFIG_PINCTRL_PFC_SH7264=y
CONFIG_PINCTRL_PFC_SH7269=y
CONFIG_PINCTRL_PFC_SH7720=y
CONFIG_PINCTRL_PFC_SH7722=y
CONFIG_PINCTRL_PFC_SH7734=y
CONFIG_PINCTRL_PFC_SH7757=y
CONFIG_PINCTRL_PFC_SH7785=y
CONFIG_PINCTRL_PFC_SH7786=y
CONFIG_PINCTRL_PFC_SH73A0=y
CONFIG_PINCTRL_PFC_SH7723=y
CONFIG_PINCTRL_PFC_SH7724=y
CONFIG_PINCTRL_PFC_SHX3=y
# end of Renesas pinctrl drivers
CONFIG_PINCTRL_SAMSUNG=y
CONFIG_PINCTRL_EXYNOS=y
CONFIG_PINCTRL_EXYNOS_ARM=y
CONFIG_PINCTRL_EXYNOS_ARM64=y
CONFIG_PINCTRL_S3C64XX=y
CONFIG_PINCTRL_SPEAR=y
CONFIG_PINCTRL_SPEAR1310=y
CONFIG_PINCTRL_SPEAR1340=y
CONFIG_PINCTRL_SPEAR_PLGPIO=y
CONFIG_PINCTRL_SPRD=y
CONFIG_PINCTRL_SPRD_SC9860=y
CONFIG_PINCTRL_STARFIVE_JH7100=y
CONFIG_PINCTRL_STM32=y
CONFIG_PINCTRL_STM32F429=y
CONFIG_PINCTRL_STM32F469=y
CONFIG_PINCTRL_STM32F746=y
CONFIG_PINCTRL_STM32F769=y
CONFIG_PINCTRL_STM32H743=y
CONFIG_PINCTRL_STM32MP135=y
CONFIG_PINCTRL_STM32MP157=y
CONFIG_PINCTRL_SPPCTL=y
CONFIG_PINCTRL_SUNXI=y
CONFIG_PINCTRL_SUN4I_A10=y
CONFIG_PINCTRL_SUN5I=y
CONFIG_PINCTRL_SUN6I_A31=y
CONFIG_PINCTRL_SUN6I_A31_R=y
CONFIG_PINCTRL_SUN8I_A23=y
CONFIG_PINCTRL_SUN8I_A33=y
CONFIG_PINCTRL_SUN8I_A83T=y
CONFIG_PINCTRL_SUN8I_A83T_R=y
CONFIG_PINCTRL_SUN8I_A23_R=y
CONFIG_PINCTRL_SUN8I_H3=y
CONFIG_PINCTRL_SUN8I_H3_R=y
CONFIG_PINCTRL_SUN8I_V3S=y
CONFIG_PINCTRL_SUN9I_A80=y
CONFIG_PINCTRL_SUN9I_A80_R=y
CONFIG_PINCTRL_SUN20I_D1=y
CONFIG_PINCTRL_SUN50I_A64=y
CONFIG_PINCTRL_SUN50I_A64_R=y
CONFIG_PINCTRL_SUN50I_A100=y
CONFIG_PINCTRL_SUN50I_A100_R=y
CONFIG_PINCTRL_SUN50I_H5=y
CONFIG_PINCTRL_SUN50I_H6=y
CONFIG_PINCTRL_SUN50I_H6_R=y
CONFIG_PINCTRL_SUN50I_H616=y
CONFIG_PINCTRL_SUN50I_H616_R=y
CONFIG_PINCTRL_TEGRA=y
CONFIG_PINCTRL_TEGRA20=y
CONFIG_PINCTRL_TEGRA30=y
CONFIG_PINCTRL_TEGRA114=y
CONFIG_PINCTRL_TEGRA124=y
CONFIG_PINCTRL_TEGRA_XUSB=y
CONFIG_PINCTRL_TI_IODELAY=y
CONFIG_PINCTRL_UNIPHIER=y
CONFIG_PINCTRL_UNIPHIER_LD4=y
CONFIG_PINCTRL_UNIPHIER_PRO4=y
CONFIG_PINCTRL_UNIPHIER_SLD8=y
CONFIG_PINCTRL_UNIPHIER_PRO5=y
CONFIG_PINCTRL_UNIPHIER_PXS2=y
CONFIG_PINCTRL_UNIPHIER_LD6B=y
CONFIG_PINCTRL_UNIPHIER_LD11=y
CONFIG_PINCTRL_UNIPHIER_LD20=y
CONFIG_PINCTRL_UNIPHIER_PXS3=y
CONFIG_PINCTRL_UNIPHIER_NX1=y
CONFIG_PINCTRL_VISCONTI=y
CONFIG_PINCTRL_TMPV7700=y
CONFIG_PINCTRL_WMT=y
CONFIG_PINCTRL_WM8750=y
CONFIG_PINCTRL_WM8850=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=512
CONFIG_OF_GPIO=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_CDEV_V1=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_REGMAP=y
CONFIG_GPIO_MAX730X=y
CONFIG_GPIO_IDIO_16=y
#
# Memory mapped GPIO drivers
#
CONFIG_GPIO_74XX_MMIO=y
CONFIG_GPIO_ALTERA=y
CONFIG_GPIO_ASPEED=y
CONFIG_GPIO_ASPEED_SGPIO=y
CONFIG_GPIO_ATH79=y
CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_GPIO_BCM_KONA=y
CONFIG_GPIO_BCM_XGS_IPROC=y
CONFIG_GPIO_BRCMSTB=y
CONFIG_GPIO_CADENCE=y
CONFIG_GPIO_CLPS711X=y
CONFIG_GPIO_DAVINCI=y
CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_EIC_SPRD=y
CONFIG_GPIO_EM=y
CONFIG_GPIO_EN7523=y
CONFIG_GPIO_EXAR=y
CONFIG_GPIO_FTGPIO010=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_GRGPIO=y
CONFIG_GPIO_HISI=y
CONFIG_GPIO_HLWD=y
CONFIG_GPIO_IMX_SCU=y
CONFIG_GPIO_LOGICVC=y
CONFIG_GPIO_LPC18XX=y
CONFIG_GPIO_LPC32XX=y
CONFIG_GPIO_MB86S7X=y
CONFIG_GPIO_MENZ127=y
CONFIG_GPIO_MPC8XXX=y
CONFIG_GPIO_MT7621=y
CONFIG_GPIO_MVEBU=y
CONFIG_GPIO_MXC=y
CONFIG_GPIO_MXS=y
CONFIG_GPIO_OMAP=y
CONFIG_GPIO_PL061=y
CONFIG_GPIO_PMIC_EIC_SPRD=y
CONFIG_GPIO_PXA=y
CONFIG_GPIO_RCAR=y
CONFIG_GPIO_RDA=y
CONFIG_GPIO_ROCKCHIP=y
CONFIG_GPIO_SAMA5D2_PIOBU=y
CONFIG_GPIO_SIFIVE=y
CONFIG_GPIO_SIOX=y
CONFIG_GPIO_SNPS_CREG=y
CONFIG_GPIO_SPEAR_SPICS=y
CONFIG_GPIO_SPRD=y
CONFIG_GPIO_STP_XWAY=y
CONFIG_GPIO_SYSCON=y
CONFIG_GPIO_TEGRA=y
CONFIG_GPIO_TEGRA186=y
CONFIG_GPIO_TS4800=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_GPIO_VF610=y
CONFIG_GPIO_VISCONTI=y
CONFIG_GPIO_VX855=y
CONFIG_GPIO_WCD934X=y
CONFIG_GPIO_XGENE_SB=y
CONFIG_GPIO_XILINX=y
CONFIG_GPIO_XLP=y
CONFIG_GPIO_ZEVIO=y
CONFIG_GPIO_ZYNQ=y
CONFIG_GPIO_AMD_FCH=y
CONFIG_GPIO_MSC313=y
CONFIG_GPIO_IDT3243X=y
# end of Memory mapped GPIO drivers
#
# I2C GPIO expanders
#
CONFIG_GPIO_ADNP=y
CONFIG_GPIO_GW_PLD=y
CONFIG_GPIO_MAX7300=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MAX732X_IRQ=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCA9570=y
CONFIG_GPIO_PCF857X=y
CONFIG_GPIO_TPIC2810=y
CONFIG_GPIO_TS4900=y
# end of I2C GPIO expanders
#
# MFD GPIO expanders
#
CONFIG_GPIO_ADP5520=y
CONFIG_GPIO_ALTERA_A10SR=y
CONFIG_GPIO_ARIZONA=y
CONFIG_GPIO_BD71815=y
CONFIG_GPIO_BD71828=y
CONFIG_GPIO_BD9571MWV=y
CONFIG_GPIO_CRYSTAL_COVE=y
CONFIG_GPIO_DA9052=y
CONFIG_GPIO_DA9055=y
CONFIG_GPIO_DLN2=y
CONFIG_HTC_EGPIO=y
CONFIG_GPIO_JANZ_TTL=y
CONFIG_GPIO_KEMPLD=y
CONFIG_GPIO_LP3943=y
CONFIG_GPIO_LP873X=y
CONFIG_GPIO_LP87565=y
CONFIG_GPIO_MADERA=y
CONFIG_GPIO_MAX77620=y
CONFIG_GPIO_MAX77650=y
CONFIG_GPIO_PALMAS=y
CONFIG_GPIO_RC5T583=y
CONFIG_GPIO_SL28CPLD=y
CONFIG_GPIO_STMPE=y
CONFIG_GPIO_TC3589X=y
CONFIG_GPIO_TIMBERDALE=y
CONFIG_GPIO_TPS65086=y
CONFIG_GPIO_TPS65218=y
CONFIG_GPIO_TPS6586X=y
CONFIG_GPIO_TPS65910=y
CONFIG_GPIO_TPS65912=y
CONFIG_GPIO_TWL4030=y
CONFIG_GPIO_TWL6040=y
CONFIG_GPIO_WM831X=y
CONFIG_GPIO_WM8350=y
CONFIG_GPIO_WM8994=y
# end of MFD GPIO expanders
#
# PCI GPIO expanders
#
CONFIG_GPIO_ML_IOH=y
CONFIG_GPIO_PCH=y
CONFIG_GPIO_PCI_IDIO_16=y
CONFIG_GPIO_PCIE_IDIO_24=y
CONFIG_GPIO_RDC321X=y
# end of PCI GPIO expanders
#
# SPI GPIO expanders
#
CONFIG_GPIO_74X164=y
CONFIG_GPIO_MAX3191X=y
CONFIG_GPIO_MAX7301=y
CONFIG_GPIO_MC33880=y
CONFIG_GPIO_PISOSR=y
CONFIG_GPIO_XRA1403=y
CONFIG_GPIO_MOXTET=y
# end of SPI GPIO expanders
#
# USB GPIO expanders
#
CONFIG_GPIO_VIPERBOARD=y
# end of USB GPIO expanders
#
# Virtual GPIO drivers
#
CONFIG_GPIO_AGGREGATOR=y
CONFIG_GPIO_LATCH=y
CONFIG_GPIO_MOCKUP=y
CONFIG_GPIO_VIRTIO=y
CONFIG_GPIO_SIM=y
# end of Virtual GPIO drivers
CONFIG_W1=y
CONFIG_W1_CON=y
#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_MATROX=y
CONFIG_W1_MASTER_DS2490=y
CONFIG_W1_MASTER_DS2482=y
CONFIG_W1_MASTER_MXC=y
CONFIG_W1_MASTER_GPIO=y
CONFIG_HDQ_MASTER_OMAP=y
CONFIG_W1_MASTER_SGI=y
# end of 1-wire Bus Masters
#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=y
CONFIG_W1_SLAVE_SMEM=y
CONFIG_W1_SLAVE_DS2405=y
CONFIG_W1_SLAVE_DS2408=y
CONFIG_W1_SLAVE_DS2408_READBACK=y
CONFIG_W1_SLAVE_DS2413=y
CONFIG_W1_SLAVE_DS2406=y
CONFIG_W1_SLAVE_DS2423=y
CONFIG_W1_SLAVE_DS2805=y
CONFIG_W1_SLAVE_DS2430=y
CONFIG_W1_SLAVE_DS2431=y
CONFIG_W1_SLAVE_DS2433=y
CONFIG_W1_SLAVE_DS2433_CRC=y
CONFIG_W1_SLAVE_DS2438=y
CONFIG_W1_SLAVE_DS250X=y
CONFIG_W1_SLAVE_DS2780=y
CONFIG_W1_SLAVE_DS2781=y
CONFIG_W1_SLAVE_DS28E04=y
CONFIG_W1_SLAVE_DS28E17=y
# end of 1-wire Slaves
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_AT91_POWEROFF=y
CONFIG_POWER_RESET_AT91_RESET=y
CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y
CONFIG_POWER_RESET_ATC260X=y
CONFIG_POWER_RESET_BRCMKONA=y
CONFIG_POWER_RESET_BRCMSTB=y
CONFIG_POWER_RESET_GEMINI_POWEROFF=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_HISI=y
CONFIG_POWER_RESET_LINKSTATION=y
CONFIG_POWER_RESET_MSM=y
CONFIG_POWER_RESET_QCOM_PON=y
CONFIG_POWER_RESET_OCELOT_RESET=y
CONFIG_POWER_RESET_OXNAS=y
CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_LTC2952=y
CONFIG_POWER_RESET_MT6323=y
CONFIG_POWER_RESET_QNAP=y
CONFIG_POWER_RESET_REGULATOR=y
CONFIG_POWER_RESET_RESTART=y
CONFIG_POWER_RESET_ST=y
CONFIG_POWER_RESET_TPS65086=y
CONFIG_POWER_RESET_VERSATILE=y
CONFIG_POWER_RESET_VEXPRESS=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_RESET_RMOBILE=y
CONFIG_REBOOT_MODE=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_POWER_RESET_SC27XX=y
CONFIG_NVMEM_REBOOT_MODE=y
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_SUPPLY_DEBUG=y
CONFIG_POWER_SUPPLY_HWMON=y
CONFIG_APM_POWER=y
CONFIG_GENERIC_ADC_BATTERY=y
CONFIG_IP5XXX_POWER=y
CONFIG_MAX8925_POWER=y
CONFIG_WM831X_BACKUP=y
CONFIG_WM831X_POWER=y
CONFIG_WM8350_POWER=y
CONFIG_TEST_POWER=y
CONFIG_BATTERY_88PM860X=y
CONFIG_CHARGER_ADP5061=y
CONFIG_BATTERY_ACT8945A=y
CONFIG_BATTERY_CPCAP=y
CONFIG_BATTERY_CW2015=y
CONFIG_BATTERY_DS2760=y
CONFIG_BATTERY_DS2780=y
CONFIG_BATTERY_DS2781=y
CONFIG_BATTERY_DS2782=y
CONFIG_BATTERY_LEGO_EV3=y
CONFIG_BATTERY_OLPC=y
CONFIG_BATTERY_SAMSUNG_SDI=y
CONFIG_BATTERY_INGENIC=y
CONFIG_BATTERY_WM97XX=y
CONFIG_BATTERY_SBS=y
CONFIG_CHARGER_SBS=y
CONFIG_MANAGER_SBS=y
CONFIG_BATTERY_BQ27XXX=y
CONFIG_BATTERY_BQ27XXX_I2C=y
CONFIG_BATTERY_BQ27XXX_HDQ=y
CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM=y
CONFIG_BATTERY_DA9030=y
CONFIG_BATTERY_DA9052=y
CONFIG_CHARGER_DA9150=y
CONFIG_BATTERY_DA9150=y
CONFIG_CHARGER_AXP20X=y
CONFIG_BATTERY_AXP20X=y
CONFIG_AXP20X_POWER=y
CONFIG_BATTERY_MAX17040=y
CONFIG_BATTERY_MAX17042=y
CONFIG_BATTERY_MAX1721X=y
CONFIG_BATTERY_TWL4030_MADC=y
CONFIG_CHARGER_88PM860X=y
CONFIG_CHARGER_PCF50633=y
CONFIG_BATTERY_RX51=y
CONFIG_CHARGER_CPCAP=y
CONFIG_CHARGER_ISP1704=y
CONFIG_CHARGER_MAX8903=y
CONFIG_CHARGER_TWL4030=y
CONFIG_CHARGER_LP8727=y
CONFIG_CHARGER_LP8788=y
CONFIG_CHARGER_GPIO=y
CONFIG_CHARGER_MANAGER=y
CONFIG_CHARGER_LT3651=y
CONFIG_CHARGER_LTC4162L=y
CONFIG_CHARGER_MAX14577=y
CONFIG_CHARGER_DETECTOR_MAX14656=y
CONFIG_CHARGER_MAX77650=y
CONFIG_CHARGER_MAX77693=y
CONFIG_CHARGER_MAX77976=y
CONFIG_CHARGER_MAX8997=y
CONFIG_CHARGER_MAX8998=y
CONFIG_CHARGER_MP2629=y
CONFIG_CHARGER_MT6360=y
CONFIG_CHARGER_MT6370=y
CONFIG_CHARGER_QCOM_SMBB=y
CONFIG_CHARGER_BQ2415X=y
CONFIG_CHARGER_BQ24190=y
CONFIG_CHARGER_BQ24257=y
CONFIG_CHARGER_BQ24735=y
CONFIG_CHARGER_BQ2515X=y
CONFIG_CHARGER_BQ25890=y
CONFIG_CHARGER_BQ25980=y
CONFIG_CHARGER_BQ256XX=y
CONFIG_CHARGER_RK817=y
CONFIG_CHARGER_SMB347=y
CONFIG_CHARGER_TPS65090=y
CONFIG_CHARGER_TPS65217=y
CONFIG_BATTERY_GAUGE_LTC2941=y
CONFIG_AB8500_BM=y
CONFIG_BATTERY_GOLDFISH=y
CONFIG_BATTERY_RT5033=y
CONFIG_CHARGER_RT9455=y
CONFIG_CHARGER_CROS_USBPD=y
CONFIG_CHARGER_CROS_PCHG=y
CONFIG_CHARGER_SC2731=y
CONFIG_FUEL_GAUGE_SC27XX=y
CONFIG_CHARGER_UCS1002=y
CONFIG_CHARGER_BD99954=y
CONFIG_RN5T618_POWER=y
CONFIG_BATTERY_ACER_A500=y
CONFIG_BATTERY_UG3105=y
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
CONFIG_HWMON_DEBUG_CHIP=y
#
# Native drivers
#
CONFIG_SENSORS_SMPRO=y
CONFIG_SENSORS_AD7314=y
CONFIG_SENSORS_AD7414=y
CONFIG_SENSORS_AD7418=y
CONFIG_SENSORS_ADM1025=y
CONFIG_SENSORS_ADM1026=y
CONFIG_SENSORS_ADM1029=y
CONFIG_SENSORS_ADM1031=y
CONFIG_SENSORS_ADM1177=y
CONFIG_SENSORS_ADM9240=y
CONFIG_SENSORS_ADT7X10=y
CONFIG_SENSORS_ADT7310=y
CONFIG_SENSORS_ADT7410=y
CONFIG_SENSORS_ADT7411=y
CONFIG_SENSORS_ADT7462=y
CONFIG_SENSORS_ADT7470=y
CONFIG_SENSORS_ADT7475=y
CONFIG_SENSORS_AHT10=y
CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=y
CONFIG_SENSORS_AS370=y
CONFIG_SENSORS_ASC7621=y
CONFIG_SENSORS_AXI_FAN_CONTROL=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_SENSORS_ASB100=y
CONFIG_SENSORS_ASPEED=y
CONFIG_SENSORS_ATXP1=y
CONFIG_SENSORS_BT1_PVT=y
CONFIG_SENSORS_BT1_PVT_ALARMS=y
CONFIG_SENSORS_CORSAIR_CPRO=y
CONFIG_SENSORS_CORSAIR_PSU=y
CONFIG_SENSORS_DRIVETEMP=y
CONFIG_SENSORS_DS620=y
CONFIG_SENSORS_DS1621=y
CONFIG_SENSORS_DA9052_ADC=y
CONFIG_SENSORS_DA9055=y
CONFIG_SENSORS_I5K_AMB=y
CONFIG_SENSORS_SPARX5=y
CONFIG_SENSORS_F71805F=y
CONFIG_SENSORS_F71882FG=y
CONFIG_SENSORS_F75375S=y
CONFIG_SENSORS_GSC=y
CONFIG_SENSORS_MC13783_ADC=y
CONFIG_SENSORS_FSCHMD=y
CONFIG_SENSORS_FTSTEUTATES=y
CONFIG_SENSORS_GL518SM=y
CONFIG_SENSORS_GL520SM=y
CONFIG_SENSORS_G760A=y
CONFIG_SENSORS_G762=y
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_SENSORS_HIH6130=y
CONFIG_SENSORS_IBMAEM=y
CONFIG_SENSORS_IBMPEX=y
CONFIG_SENSORS_IIO_HWMON=y
CONFIG_SENSORS_IT87=y
CONFIG_SENSORS_JC42=y
CONFIG_SENSORS_POWR1220=y
CONFIG_SENSORS_LAN966X=y
CONFIG_SENSORS_LINEAGE=y
CONFIG_SENSORS_LOCHNAGAR=y
CONFIG_SENSORS_LTC2945=y
CONFIG_SENSORS_LTC2947=y
CONFIG_SENSORS_LTC2947_I2C=y
CONFIG_SENSORS_LTC2947_SPI=y
CONFIG_SENSORS_LTC2990=y
CONFIG_SENSORS_LTC2992=y
CONFIG_SENSORS_LTC4151=y
CONFIG_SENSORS_LTC4215=y
CONFIG_SENSORS_LTC4222=y
CONFIG_SENSORS_LTC4245=y
CONFIG_SENSORS_LTC4260=y
CONFIG_SENSORS_LTC4261=y
CONFIG_SENSORS_MAX1111=y
CONFIG_SENSORS_MAX127=y
CONFIG_SENSORS_MAX16065=y
CONFIG_SENSORS_MAX1619=y
CONFIG_SENSORS_MAX1668=y
CONFIG_SENSORS_MAX197=y
CONFIG_SENSORS_MAX31722=y
CONFIG_SENSORS_MAX31730=y
CONFIG_SENSORS_MAX31760=y
CONFIG_SENSORS_MAX6620=y
CONFIG_SENSORS_MAX6621=y
CONFIG_SENSORS_MAX6639=y
CONFIG_SENSORS_MAX6650=y
CONFIG_SENSORS_MAX6697=y
CONFIG_SENSORS_MAX31790=y
CONFIG_SENSORS_MCP3021=y
CONFIG_SENSORS_MLXREG_FAN=y
CONFIG_SENSORS_TC654=y
CONFIG_SENSORS_TPS23861=y
CONFIG_SENSORS_MENF21BMC_HWMON=y
CONFIG_SENSORS_MR75203=y
CONFIG_SENSORS_ADCXX=y
CONFIG_SENSORS_LM63=y
CONFIG_SENSORS_LM70=y
CONFIG_SENSORS_LM73=y
CONFIG_SENSORS_LM75=y
CONFIG_SENSORS_LM77=y
CONFIG_SENSORS_LM78=y
CONFIG_SENSORS_LM80=y
CONFIG_SENSORS_LM83=y
CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM87=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_LM92=y
CONFIG_SENSORS_LM93=y
CONFIG_SENSORS_LM95234=y
CONFIG_SENSORS_LM95241=y
CONFIG_SENSORS_LM95245=y
CONFIG_SENSORS_PC87360=y
CONFIG_SENSORS_PC87427=y
CONFIG_SENSORS_NTC_THERMISTOR=y
CONFIG_SENSORS_NCT6683=y
CONFIG_SENSORS_NCT6775_CORE=y
CONFIG_SENSORS_NCT6775=y
CONFIG_SENSORS_NCT6775_I2C=y
CONFIG_SENSORS_NCT7802=y
CONFIG_SENSORS_NCT7904=y
CONFIG_SENSORS_NPCM7XX=y
CONFIG_SENSORS_NSA320=y
CONFIG_SENSORS_NZXT_KRAKEN2=y
CONFIG_SENSORS_NZXT_SMART2=y
CONFIG_SENSORS_OCC_P8_I2C=y
CONFIG_SENSORS_OCC_P9_SBE=y
CONFIG_SENSORS_OCC=y
CONFIG_SENSORS_PCF8591=y
CONFIG_SENSORS_PECI_CPUTEMP=y
CONFIG_SENSORS_PECI_DIMMTEMP=y
CONFIG_SENSORS_PECI=y
CONFIG_PMBUS=y
CONFIG_SENSORS_PMBUS=y
CONFIG_SENSORS_ADM1266=y
CONFIG_SENSORS_ADM1275=y
CONFIG_SENSORS_BEL_PFE=y
CONFIG_SENSORS_BPA_RS600=y
CONFIG_SENSORS_DELTA_AHE50DC_FAN=y
CONFIG_SENSORS_FSP_3Y=y
CONFIG_SENSORS_IBM_CFFPS=y
CONFIG_SENSORS_DPS920AB=y
CONFIG_SENSORS_INSPUR_IPSPS=y
CONFIG_SENSORS_IR35221=y
CONFIG_SENSORS_IR36021=y
CONFIG_SENSORS_IR38064=y
CONFIG_SENSORS_IR38064_REGULATOR=y
CONFIG_SENSORS_IRPS5401=y
CONFIG_SENSORS_ISL68137=y
CONFIG_SENSORS_LM25066=y
CONFIG_SENSORS_LM25066_REGULATOR=y
CONFIG_SENSORS_LT7182S=y
CONFIG_SENSORS_LTC2978=y
CONFIG_SENSORS_LTC2978_REGULATOR=y
CONFIG_SENSORS_LTC3815=y
CONFIG_SENSORS_MAX15301=y
CONFIG_SENSORS_MAX16064=y
CONFIG_SENSORS_MAX16601=y
CONFIG_SENSORS_MAX20730=y
CONFIG_SENSORS_MAX20751=y
CONFIG_SENSORS_MAX31785=y
CONFIG_SENSORS_MAX34440=y
CONFIG_SENSORS_MAX8688=y
CONFIG_SENSORS_MP2888=y
CONFIG_SENSORS_MP2975=y
CONFIG_SENSORS_MP5023=y
CONFIG_SENSORS_MPQ7932_REGULATOR=y
CONFIG_SENSORS_MPQ7932=y
CONFIG_SENSORS_PIM4328=y
CONFIG_SENSORS_PLI1209BC=y
CONFIG_SENSORS_PLI1209BC_REGULATOR=y
CONFIG_SENSORS_PM6764TR=y
CONFIG_SENSORS_PXE1610=y
CONFIG_SENSORS_Q54SJ108A2=y
CONFIG_SENSORS_STPDDC60=y
CONFIG_SENSORS_TPS40422=y
CONFIG_SENSORS_TPS53679=y
CONFIG_SENSORS_TPS546D24=y
CONFIG_SENSORS_UCD9000=y
CONFIG_SENSORS_UCD9200=y
CONFIG_SENSORS_XDPE152=y
CONFIG_SENSORS_XDPE122=y
CONFIG_SENSORS_XDPE122_REGULATOR=y
CONFIG_SENSORS_ZL6100=y
CONFIG_SENSORS_PWM_FAN=y
CONFIG_SENSORS_RASPBERRYPI_HWMON=y
CONFIG_SENSORS_SL28CPLD=y
CONFIG_SENSORS_SBTSI=y
CONFIG_SENSORS_SBRMI=y
CONFIG_SENSORS_SHT15=y
CONFIG_SENSORS_SHT21=y
CONFIG_SENSORS_SHT3x=y
CONFIG_SENSORS_SHT4x=y
CONFIG_SENSORS_SHTC1=y
CONFIG_SENSORS_SIS5595=y
CONFIG_SENSORS_SY7636A=y
CONFIG_SENSORS_DME1737=y
CONFIG_SENSORS_EMC1403=y
CONFIG_SENSORS_EMC2103=y
CONFIG_SENSORS_EMC2305=y
CONFIG_SENSORS_EMC6W201=y
CONFIG_SENSORS_SMSC47M1=y
CONFIG_SENSORS_SMSC47M192=y
CONFIG_SENSORS_SMSC47B397=y
CONFIG_SENSORS_SCH56XX_COMMON=y
CONFIG_SENSORS_SCH5627=y
CONFIG_SENSORS_SCH5636=y
CONFIG_SENSORS_STTS751=y
CONFIG_SENSORS_SMM665=y
CONFIG_SENSORS_ADC128D818=y
CONFIG_SENSORS_ADS7828=y
CONFIG_SENSORS_ADS7871=y
CONFIG_SENSORS_AMC6821=y
CONFIG_SENSORS_INA209=y
CONFIG_SENSORS_INA2XX=y
CONFIG_SENSORS_INA238=y
CONFIG_SENSORS_INA3221=y
CONFIG_SENSORS_TC74=y
CONFIG_SENSORS_THMC50=y
CONFIG_SENSORS_TMP102=y
CONFIG_SENSORS_TMP103=y
CONFIG_SENSORS_TMP108=y
CONFIG_SENSORS_TMP401=y
CONFIG_SENSORS_TMP421=y
CONFIG_SENSORS_TMP464=y
CONFIG_SENSORS_TMP513=y
CONFIG_SENSORS_VEXPRESS=y
CONFIG_SENSORS_VIA686A=y
CONFIG_SENSORS_VT1211=y
CONFIG_SENSORS_VT8231=y
CONFIG_SENSORS_W83773G=y
CONFIG_SENSORS_W83781D=y
CONFIG_SENSORS_W83791D=y
CONFIG_SENSORS_W83792D=y
CONFIG_SENSORS_W83793=y
CONFIG_SENSORS_W83795=y
CONFIG_SENSORS_W83795_FANCTRL=y
CONFIG_SENSORS_W83L785TS=y
CONFIG_SENSORS_W83L786NG=y
CONFIG_SENSORS_W83627HF=y
CONFIG_SENSORS_W83627EHF=y
CONFIG_SENSORS_WM831X=y
CONFIG_SENSORS_WM8350=y
CONFIG_SENSORS_INTEL_M10_BMC_HWMON=y
CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_BANG_BANG=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_FREQ_THERMAL=y
CONFIG_CPU_IDLE_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_THERMAL_MMIO=y
CONFIG_HISI_THERMAL=y
CONFIG_IMX_THERMAL=y
CONFIG_IMX_SC_THERMAL=y
CONFIG_IMX8MM_THERMAL=y
CONFIG_K3_THERMAL=y
CONFIG_MAX77620_THERMAL=y
CONFIG_QORIQ_THERMAL=y
CONFIG_SPEAR_THERMAL=y
CONFIG_SUN8I_THERMAL=y
CONFIG_ROCKCHIP_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_RCAR_GEN3_THERMAL=y
CONFIG_RZG2L_THERMAL=y
CONFIG_KIRKWOOD_THERMAL=y
CONFIG_DOVE_THERMAL=y
CONFIG_DB8500_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_DA9062_THERMAL=y
CONFIG_MTK_THERMAL=y
CONFIG_AMLOGIC_THERMAL=y
#
# Intel thermal drivers
#
#
# ACPI INT340X thermal drivers
#
# end of ACPI INT340X thermal drivers
# end of Intel thermal drivers
#
# Broadcom thermal drivers
#
CONFIG_BCM2711_THERMAL=y
CONFIG_BCM2835_THERMAL=y
CONFIG_BRCMSTB_THERMAL=y
CONFIG_BCM_NS_THERMAL=y
CONFIG_BCM_SR_THERMAL=y
# end of Broadcom thermal drivers
#
# Texas Instruments thermal drivers
#
CONFIG_TI_SOC_THERMAL=y
CONFIG_TI_THERMAL=y
CONFIG_OMAP3_THERMAL=y
CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y
# end of Texas Instruments thermal drivers
#
# Samsung thermal drivers
#
CONFIG_EXYNOS_THERMAL=y
# end of Samsung thermal drivers
#
# STMicroelectronics thermal drivers
#
CONFIG_ST_THERMAL=y
CONFIG_ST_THERMAL_SYSCFG=y
CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_STM32_THERMAL=y
# end of STMicroelectronics thermal drivers
#
# NVIDIA Tegra thermal drivers
#
CONFIG_TEGRA_SOCTHERM=y
CONFIG_TEGRA_BPMP_THERMAL=y
CONFIG_TEGRA30_TSENSOR=y
# end of NVIDIA Tegra thermal drivers
CONFIG_GENERIC_ADC_THERMAL=y
#
# Qualcomm thermal drivers
#
CONFIG_QCOM_TSENS=y
CONFIG_QCOM_SPMI_ADC_TM5=y
CONFIG_QCOM_SPMI_TEMP_ALARM=y
CONFIG_QCOM_LMH=y
# end of Qualcomm thermal drivers
CONFIG_UNIPHIER_THERMAL=y
CONFIG_SPRD_THERMAL=y
CONFIG_KHADAS_MCU_FAN_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
CONFIG_WATCHDOG_OPEN_TIMEOUT=0
CONFIG_WATCHDOG_SYSFS=y
CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT=y
#
# Watchdog Pretimeout Governors
#
CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set
CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=y
CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y
CONFIG_BD957XMUF_WATCHDOG=y
CONFIG_DA9052_WATCHDOG=y
CONFIG_DA9055_WATCHDOG=y
CONFIG_DA9063_WATCHDOG=y
CONFIG_DA9062_WATCHDOG=y
CONFIG_GPIO_WATCHDOG=y
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
CONFIG_MENF21BMC_WATCHDOG=y
CONFIG_MENZ069_WATCHDOG=y
CONFIG_WM831X_WATCHDOG=y
CONFIG_WM8350_WATCHDOG=y
CONFIG_XILINX_WATCHDOG=y
CONFIG_ZIIRAVE_WATCHDOG=y
CONFIG_RAVE_SP_WATCHDOG=y
CONFIG_MLX_WDT=y
CONFIG_SL28CPLD_WATCHDOG=y
CONFIG_ARM_SP805_WATCHDOG=y
CONFIG_ARMADA_37XX_WATCHDOG=y
CONFIG_ASM9260_WATCHDOG=y
CONFIG_AT91RM9200_WATCHDOG=y
CONFIG_AT91SAM9X_WATCHDOG=y
CONFIG_SAMA5D4_WATCHDOG=y
CONFIG_CADENCE_WATCHDOG=y
CONFIG_977_WATCHDOG=y
CONFIG_FTWDT010_WATCHDOG=y
CONFIG_S3C2410_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_EP93XX_WATCHDOG=y
CONFIG_OMAP_WATCHDOG=y
CONFIG_PNX4008_WATCHDOG=y
CONFIG_DAVINCI_WATCHDOG=y
CONFIG_K3_RTI_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
CONFIG_RN5T618_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
CONFIG_NPCM7XX_WATCHDOG=y
CONFIG_TWL4030_WATCHDOG=y
CONFIG_STMP3XXX_RTC_WATCHDOG=y
CONFIG_TS4800_WATCHDOG=y
CONFIG_TS72XX_WATCHDOG=y
CONFIG_MAX63XX_WATCHDOG=y
CONFIG_MAX77620_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_IMX_SC_WDT=y
CONFIG_IMX7ULP_WDT=y
CONFIG_DB500_WATCHDOG=y
CONFIG_RETU_WATCHDOG=y
CONFIG_MOXART_WDT=y
CONFIG_ST_LPC_WATCHDOG=y
CONFIG_TEGRA_WATCHDOG=y
CONFIG_QCOM_WDT=y
CONFIG_MESON_GXBB_WATCHDOG=y
CONFIG_MESON_WATCHDOG=y
CONFIG_MEDIATEK_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_LPC18XX_WATCHDOG=y
CONFIG_RENESAS_WDT=y
CONFIG_RENESAS_RZAWDT=y
CONFIG_RENESAS_RZN1WDT=y
CONFIG_RENESAS_RZG2LWDT=y
CONFIG_ASPEED_WATCHDOG=y
CONFIG_STM32_WATCHDOG=y
CONFIG_STPMIC1_WATCHDOG=y
CONFIG_UNIPHIER_WATCHDOG=y
CONFIG_RTD119X_WATCHDOG=y
CONFIG_REALTEK_OTTO_WDT=y
CONFIG_SPRD_WATCHDOG=y
CONFIG_PM8916_WATCHDOG=y
CONFIG_VISCONTI_WATCHDOG=y
CONFIG_MSC313E_WATCHDOG=y
CONFIG_APPLE_WATCHDOG=y
CONFIG_SUNPLUS_WATCHDOG=y
CONFIG_ALIM7101_WDT=y
CONFIG_SC520_WDT=y
CONFIG_I6300ESB_WDT=y
CONFIG_KEMPLD_WDT=y
CONFIG_RDC321X_WDT=y
CONFIG_ATH79_WDT=y
CONFIG_BCM47XX_WDT=y
CONFIG_BCM2835_WDT=y
CONFIG_BCM_KONA_WDT=y
CONFIG_BCM_KONA_WDT_DEBUG=y
CONFIG_BCM7038_WDT=y
CONFIG_IMGPDC_WDT=y
CONFIG_GXP_WATCHDOG=y
CONFIG_MPC5200_WDT=y
CONFIG_MEN_A21_WDT=y
CONFIG_UML_WATCHDOG=y
#
# PCI-based Watchdog Cards
#
CONFIG_PCIPCWATCHDOG=y
CONFIG_WDTPCI=y
#
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=y
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
CONFIG_SSB_BLOCKIO=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
CONFIG_SSB_PCMCIAHOST=y
CONFIG_SSB_SDIOHOST_POSSIBLE=y
CONFIG_SSB_SDIOHOST=y
CONFIG_SSB_HOST_SOC=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_GPIO=y
CONFIG_BCMA_POSSIBLE=y
CONFIG_BCMA=y
CONFIG_BCMA_BLOCKIO=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
CONFIG_BCMA_HOST_PCI=y
CONFIG_BCMA_HOST_SOC=y
CONFIG_BCMA_DRIVER_PCI=y
CONFIG_BCMA_DRIVER_MIPS=y
CONFIG_BCMA_PFLASH=y
CONFIG_BCMA_SFLASH=y
CONFIG_BCMA_NFLASH=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_DRIVER_GPIO=y
CONFIG_BCMA_DEBUG=y
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
CONFIG_MFD_ALTERA_A10SR=y
CONFIG_MFD_ALTERA_SYSMGR=y
CONFIG_MFD_ACT8945A=y
CONFIG_MFD_AS3711=y
CONFIG_MFD_SMPRO=y
CONFIG_MFD_AS3722=y
CONFIG_PMIC_ADP5520=y
CONFIG_MFD_AAT2870_CORE=y
CONFIG_MFD_AT91_USART=y
CONFIG_MFD_ATMEL_FLEXCOM=y
CONFIG_MFD_ATMEL_HLCDC=y
CONFIG_MFD_ATMEL_SMC=y
CONFIG_MFD_BCM590XX=y
CONFIG_MFD_BD9571MWV=y
CONFIG_MFD_AC100=y
CONFIG_MFD_AXP20X=y
CONFIG_MFD_AXP20X_I2C=y
CONFIG_MFD_AXP20X_RSB=y
CONFIG_MFD_CROS_EC_DEV=y
CONFIG_MFD_MADERA=y
CONFIG_MFD_MADERA_I2C=y
CONFIG_MFD_MADERA_SPI=y
CONFIG_MFD_CS47L15=y
CONFIG_MFD_CS47L35=y
CONFIG_MFD_CS47L85=y
CONFIG_MFD_CS47L90=y
CONFIG_MFD_CS47L92=y
CONFIG_PMIC_DA903X=y
CONFIG_PMIC_DA9052=y
CONFIG_MFD_DA9052_SPI=y
CONFIG_MFD_DA9052_I2C=y
CONFIG_MFD_DA9055=y
CONFIG_MFD_DA9062=y
CONFIG_MFD_DA9063=y
CONFIG_MFD_DA9150=y
CONFIG_MFD_DLN2=y
CONFIG_MFD_ENE_KB3930=y
CONFIG_MFD_EXYNOS_LPASS=y
CONFIG_MFD_GATEWORKS_GSC=y
CONFIG_MFD_MC13XXX=y
CONFIG_MFD_MC13XXX_SPI=y
CONFIG_MFD_MC13XXX_I2C=y
CONFIG_MFD_MP2629=y
CONFIG_MFD_MXS_LRADC=y
CONFIG_MFD_MX25_TSADC=y
CONFIG_MFD_HI6421_PMIC=y
CONFIG_MFD_HI6421_SPMI=y
CONFIG_MFD_HI655X_PMIC=y
CONFIG_LPC_ICH=y
CONFIG_LPC_SCH=y
CONFIG_INTEL_SOC_PMIC=y
CONFIG_MFD_IQS62X=y
CONFIG_MFD_JANZ_CMODIO=y
CONFIG_MFD_KEMPLD=y
CONFIG_MFD_88PM800=y
CONFIG_MFD_88PM805=y
CONFIG_MFD_88PM860X=y
CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77620=y
CONFIG_MFD_MAX77650=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
CONFIG_MFD_MAX77714=y
CONFIG_MFD_MAX77843=y
CONFIG_MFD_MAX8907=y
CONFIG_MFD_MAX8925=y
CONFIG_MFD_MAX8997=y
CONFIG_MFD_MAX8998=y
CONFIG_MFD_MT6360=y
CONFIG_MFD_MT6370=y
CONFIG_MFD_MT6397=y
CONFIG_MFD_MENF21BMC=y
CONFIG_MFD_OCELOT=y
CONFIG_EZX_PCAP=y
CONFIG_MFD_CPCAP=y
CONFIG_MFD_VIPERBOARD=y
CONFIG_MFD_NTXEC=y
CONFIG_MFD_RETU=y
CONFIG_MFD_PCF50633=y
CONFIG_PCF50633_ADC=y
CONFIG_PCF50633_GPIO=y
CONFIG_MFD_PM8XXX=y
CONFIG_MFD_QCOM_RPM=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_SY7636A=y
CONFIG_MFD_RDC321X=y
CONFIG_MFD_RT4831=y
CONFIG_MFD_RT5033=y
CONFIG_MFD_RT5120=y
CONFIG_MFD_RC5T583=y
CONFIG_MFD_RK808=y
CONFIG_MFD_RN5T618=y
CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_SI476X_CORE=y
CONFIG_MFD_SIMPLE_MFD_I2C=y
CONFIG_MFD_SL28CPLD=y
CONFIG_MFD_SM501=y
CONFIG_MFD_SM501_GPIO=y
CONFIG_MFD_SKY81452=y
CONFIG_MFD_SC27XX_PMIC=y
CONFIG_ABX500_CORE=y
CONFIG_AB8500_CORE=y
CONFIG_MFD_DB8500_PRCMU=y
CONFIG_MFD_STMPE=y
#
# STMicroelectronics STMPE Interface Drivers
#
CONFIG_STMPE_I2C=y
CONFIG_STMPE_SPI=y
# end of STMicroelectronics STMPE Interface Drivers
CONFIG_MFD_SUN6I_PRCM=y
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TI_AM335X_TSCADC=y
CONFIG_MFD_LP3943=y
CONFIG_MFD_LP8788=y
CONFIG_MFD_TI_LMU=y
CONFIG_MFD_OMAP_USB_HOST=y
CONFIG_MFD_PALMAS=y
CONFIG_TPS6105X=y
CONFIG_TPS65010=y
CONFIG_TPS6507X=y
CONFIG_MFD_TPS65086=y
CONFIG_MFD_TPS65090=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TI_LP873X=y
CONFIG_MFD_TI_LP87565=y
CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS65219=y
CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
CONFIG_MFD_TPS65912=y
CONFIG_MFD_TPS65912_I2C=y
CONFIG_MFD_TPS65912_SPI=y
CONFIG_TWL4030_CORE=y
CONFIG_TWL4030_POWER=y
CONFIG_MFD_TWL4030_AUDIO=y
CONFIG_TWL6040_CORE=y
CONFIG_MENELAUS=y
CONFIG_MFD_WL1273_CORE=y
CONFIG_MFD_LM3533=y
CONFIG_MFD_TIMBERDALE=y
CONFIG_MFD_TC3589X=y
CONFIG_MFD_TQMX86=y
CONFIG_MFD_VX855=y
CONFIG_MFD_LOCHNAGAR=y
CONFIG_MFD_ARIZONA=y
CONFIG_MFD_ARIZONA_I2C=y
CONFIG_MFD_ARIZONA_SPI=y
CONFIG_MFD_CS47L24=y
CONFIG_MFD_WM5102=y
CONFIG_MFD_WM5110=y
CONFIG_MFD_WM8997=y
CONFIG_MFD_WM8998=y
CONFIG_MFD_WM8400=y
CONFIG_MFD_WM831X=y
CONFIG_MFD_WM831X_I2C=y
CONFIG_MFD_WM831X_SPI=y
CONFIG_MFD_WM8350=y
CONFIG_MFD_WM8350_I2C=y
CONFIG_MFD_WM8994=y
CONFIG_MFD_STW481X=y
CONFIG_MFD_ROHM_BD718XX=y
CONFIG_MFD_ROHM_BD71828=y
CONFIG_MFD_ROHM_BD957XMUF=y
CONFIG_MFD_STM32_LPTIMER=y
CONFIG_MFD_STM32_TIMERS=y
CONFIG_MFD_STPMIC1=y
CONFIG_MFD_STMFX=y
CONFIG_MFD_WCD934X=y
CONFIG_MFD_ATC260X=y
CONFIG_MFD_ATC260X_I2C=y
CONFIG_MFD_KHADAS_MCU=y
CONFIG_MFD_ACER_A500_EC=y
CONFIG_MFD_QCOM_PM8008=y
CONFIG_MFD_VEXPRESS_SYSREG=y
CONFIG_RAVE_SP_CORE=y
CONFIG_MFD_INTEL_M10_BMC=y
CONFIG_MFD_RSMU_I2C=y
CONFIG_MFD_RSMU_SPI=y
# end of Multifunction device drivers
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
CONFIG_REGULATOR_88PG86X=y
CONFIG_REGULATOR_88PM800=y
CONFIG_REGULATOR_88PM8607=y
CONFIG_REGULATOR_ACT8865=y
CONFIG_REGULATOR_ACT8945A=y
CONFIG_REGULATOR_AD5398=y
CONFIG_REGULATOR_ANATOP=y
CONFIG_REGULATOR_AAT2870=y
CONFIG_REGULATOR_AB8500=y
CONFIG_REGULATOR_ARIZONA_LDO1=y
CONFIG_REGULATOR_ARIZONA_MICSUPP=y
CONFIG_REGULATOR_ARM_SCMI=y
CONFIG_REGULATOR_AS3711=y
CONFIG_REGULATOR_AS3722=y
CONFIG_REGULATOR_ATC260X=y
CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_BCM590XX=y
CONFIG_REGULATOR_BD71815=y
CONFIG_REGULATOR_BD71828=y
CONFIG_REGULATOR_BD718XX=y
CONFIG_REGULATOR_BD9571MWV=y
CONFIG_REGULATOR_BD957XMUF=y
CONFIG_REGULATOR_CPCAP=y
CONFIG_REGULATOR_CROS_EC=y
CONFIG_REGULATOR_DA903X=y
CONFIG_REGULATOR_DA9052=y
CONFIG_REGULATOR_DA9055=y
CONFIG_REGULATOR_DA9062=y
CONFIG_REGULATOR_DA9063=y
CONFIG_REGULATOR_DA9121=y
CONFIG_REGULATOR_DA9210=y
CONFIG_REGULATOR_DA9211=y
CONFIG_REGULATOR_DBX500_PRCMU=y
CONFIG_REGULATOR_DB8500_PRCMU=y
CONFIG_REGULATOR_FAN53555=y
CONFIG_REGULATOR_FAN53880=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_HI6421=y
CONFIG_REGULATOR_HI6421V530=y
CONFIG_REGULATOR_HI655X=y
CONFIG_REGULATOR_HI6421V600=y
CONFIG_REGULATOR_ISL9305=y
CONFIG_REGULATOR_ISL6271A=y
CONFIG_REGULATOR_LM363X=y
CONFIG_REGULATOR_LOCHNAGAR=y
CONFIG_REGULATOR_LP3971=y
CONFIG_REGULATOR_LP3972=y
CONFIG_REGULATOR_LP872X=y
CONFIG_REGULATOR_LP873X=y
CONFIG_REGULATOR_LP8755=y
CONFIG_REGULATOR_LP87565=y
CONFIG_REGULATOR_LP8788=y
CONFIG_REGULATOR_LTC3589=y
CONFIG_REGULATOR_LTC3676=y
CONFIG_REGULATOR_MAX14577=y
CONFIG_REGULATOR_MAX1586=y
CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_MAX77650=y
CONFIG_REGULATOR_MAX8649=y
CONFIG_REGULATOR_MAX8660=y
CONFIG_REGULATOR_MAX8893=y
CONFIG_REGULATOR_MAX8907=y
CONFIG_REGULATOR_MAX8925=y
CONFIG_REGULATOR_MAX8952=y
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX8997=y
CONFIG_REGULATOR_MAX8998=y
CONFIG_REGULATOR_MAX20086=y
CONFIG_REGULATOR_MAX77686=y
CONFIG_REGULATOR_MAX77693=y
CONFIG_REGULATOR_MAX77802=y
CONFIG_REGULATOR_MAX77826=y
CONFIG_REGULATOR_MC13XXX_CORE=y
CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
CONFIG_REGULATOR_MCP16502=y
CONFIG_REGULATOR_MP5416=y
CONFIG_REGULATOR_MP8859=y
CONFIG_REGULATOR_MP886X=y
CONFIG_REGULATOR_MPQ7920=y
CONFIG_REGULATOR_MT6311=y
CONFIG_REGULATOR_MT6315=y
CONFIG_REGULATOR_MT6323=y
CONFIG_REGULATOR_MT6331=y
CONFIG_REGULATOR_MT6332=y
CONFIG_REGULATOR_MT6357=y
CONFIG_REGULATOR_MT6358=y
CONFIG_REGULATOR_MT6359=y
CONFIG_REGULATOR_MT6360=y
CONFIG_REGULATOR_MT6370=y
CONFIG_REGULATOR_MT6380=y
CONFIG_REGULATOR_MT6397=y
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_PCA9450=y
CONFIG_REGULATOR_PCAP=y
CONFIG_REGULATOR_PCF50633=y
CONFIG_REGULATOR_PF8X00=y
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_PV88060=y
CONFIG_REGULATOR_PV88080=y
CONFIG_REGULATOR_PV88090=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_RPM=y
CONFIG_REGULATOR_QCOM_RPMH=y
CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_REGULATOR_QCOM_SPMI=y
CONFIG_REGULATOR_QCOM_USB_VBUS=y
CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=y
CONFIG_REGULATOR_RC5T583=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_RN5T618=y
CONFIG_REGULATOR_ROHM=y
CONFIG_REGULATOR_RT4801=y
CONFIG_REGULATOR_RT4831=y
CONFIG_REGULATOR_RT5033=y
CONFIG_REGULATOR_RT5120=y
CONFIG_REGULATOR_RT5190A=y
CONFIG_REGULATOR_RT5759=y
CONFIG_REGULATOR_RT6160=y
CONFIG_REGULATOR_RT6190=y
CONFIG_REGULATOR_RT6245=y
CONFIG_REGULATOR_RTQ2134=y
CONFIG_REGULATOR_RTMV20=y
CONFIG_REGULATOR_RTQ6752=y
CONFIG_REGULATOR_S2MPA01=y
CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_SC2731=y
CONFIG_REGULATOR_SKY81452=y
CONFIG_REGULATOR_SLG51000=y
CONFIG_REGULATOR_STM32_BOOSTER=y
CONFIG_REGULATOR_STM32_VREFBUF=y
CONFIG_REGULATOR_STM32_PWR=y
CONFIG_REGULATOR_STPMIC1=y
CONFIG_REGULATOR_TI_ABB=y
CONFIG_REGULATOR_STW481X_VMMC=y
CONFIG_REGULATOR_SY7636A=y
CONFIG_REGULATOR_SY8106A=y
CONFIG_REGULATOR_SY8824X=y
CONFIG_REGULATOR_SY8827N=y
CONFIG_REGULATOR_TPS51632=y
CONFIG_REGULATOR_TPS6105X=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS6286X=y
CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y
CONFIG_REGULATOR_TPS65086=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_REGULATOR_TPS65132=y
CONFIG_REGULATOR_TPS65217=y
CONFIG_REGULATOR_TPS65218=y
CONFIG_REGULATOR_TPS65219=y
CONFIG_REGULATOR_TPS6524X=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TPS65912=y
CONFIG_REGULATOR_TPS68470=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_REGULATOR_UNIPHIER=y
CONFIG_REGULATOR_VCTRL=y
CONFIG_REGULATOR_VEXPRESS=y
CONFIG_REGULATOR_VQMMC_IPQ4019=y
CONFIG_REGULATOR_WM831X=y
CONFIG_REGULATOR_WM8350=y
CONFIG_REGULATOR_WM8400=y
CONFIG_REGULATOR_WM8994=y
CONFIG_REGULATOR_QCOM_LABIBB=y
CONFIG_RC_CORE=y
CONFIG_BPF_LIRC_MODE2=y
CONFIG_LIRC=y
CONFIG_RC_MAP=y
CONFIG_RC_DECODERS=y
CONFIG_IR_IMON_DECODER=y
CONFIG_IR_JVC_DECODER=y
CONFIG_IR_MCE_KBD_DECODER=y
CONFIG_IR_NEC_DECODER=y
CONFIG_IR_RC5_DECODER=y
CONFIG_IR_RC6_DECODER=y
CONFIG_IR_RCMM_DECODER=y
CONFIG_IR_SANYO_DECODER=y
CONFIG_IR_SHARP_DECODER=y
CONFIG_IR_SONY_DECODER=y
CONFIG_IR_XMP_DECODER=y
CONFIG_RC_DEVICES=y
CONFIG_IR_ENE=y
CONFIG_IR_FINTEK=y
CONFIG_IR_GPIO_CIR=y
CONFIG_IR_GPIO_TX=y
CONFIG_IR_HIX5HD2=y
CONFIG_IR_IGORPLUGUSB=y
CONFIG_IR_IGUANA=y
CONFIG_IR_IMON=y
CONFIG_IR_IMON_RAW=y
CONFIG_IR_ITE_CIR=y
CONFIG_IR_MCEUSB=y
CONFIG_IR_MESON=y
CONFIG_IR_MESON_TX=y
CONFIG_IR_MTK=y
CONFIG_IR_NUVOTON=y
CONFIG_IR_PWM_TX=y
CONFIG_IR_REDRAT3=y
CONFIG_IR_RX51=y
CONFIG_IR_SERIAL=y
CONFIG_IR_SERIAL_TRANSMITTER=y
CONFIG_IR_SPI=y
CONFIG_IR_STREAMZAP=y
CONFIG_IR_SUNXI=y
CONFIG_IR_TOY=y
CONFIG_IR_TTUSBIR=y
CONFIG_IR_WINBOND_CIR=y
CONFIG_RC_ATI_REMOTE=y
CONFIG_RC_LOOPBACK=y
CONFIG_RC_ST=y
CONFIG_RC_XBOX_DVD=y
CONFIG_IR_IMG=y
CONFIG_IR_IMG_RAW=y
CONFIG_IR_IMG_HW=y
CONFIG_IR_IMG_NEC=y
CONFIG_IR_IMG_JVC=y
CONFIG_IR_IMG_SONY=y
CONFIG_IR_IMG_SHARP=y
CONFIG_IR_IMG_SANYO=y
CONFIG_IR_IMG_RC5=y
CONFIG_IR_IMG_RC6=y
CONFIG_CEC_CORE=y
CONFIG_CEC_NOTIFIER=y
CONFIG_CEC_PIN=y
#
# CEC support
#
CONFIG_MEDIA_CEC_RC=y
CONFIG_CEC_PIN_ERROR_INJ=y
CONFIG_MEDIA_CEC_SUPPORT=y
CONFIG_CEC_CH7322=y
CONFIG_CEC_CROS_EC=y
CONFIG_CEC_MESON_AO=y
CONFIG_CEC_MESON_G12A_AO=y
CONFIG_CEC_GPIO=y
CONFIG_CEC_SAMSUNG_S5P=y
CONFIG_CEC_STI=y
CONFIG_CEC_STM32=y
CONFIG_CEC_TEGRA=y
CONFIG_CEC_SECO=y
CONFIG_CEC_SECO_RC=y
CONFIG_USB_PULSE8_CEC=y
CONFIG_USB_RAINSHADOW_CEC=y
# end of CEC support
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
#
# Media device types
#
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_SDR_SUPPORT=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_MEDIA_TEST_SUPPORT=y
# end of Media device types
CONFIG_VIDEO_DEV=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_DVB_CORE=y
#
# Video4Linux options
#
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_VIDEO_TUNER=y
CONFIG_V4L2_JPEG_HELPER=y
CONFIG_V4L2_H264=y
CONFIG_V4L2_VP9=y
CONFIG_V4L2_MEM2MEM_DEV=y
CONFIG_V4L2_FLASH_LED_CLASS=y
CONFIG_V4L2_FWNODE=y
CONFIG_V4L2_ASYNC=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_SG=y
CONFIG_VIDEOBUF_VMALLOC=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
# end of Video4Linux options
#
# Media controller options
#
CONFIG_MEDIA_CONTROLLER_DVB=y
CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
# end of Media controller options
#
# Digital TV options
#
CONFIG_DVB_MMAP=y
CONFIG_DVB_NET=y
CONFIG_DVB_MAX_ADAPTERS=16
CONFIG_DVB_DYNAMIC_MINORS=y
CONFIG_DVB_DEMUX_SECTION_LOSS_LOG=y
CONFIG_DVB_ULE_DEBUG=y
# end of Digital TV options
#
# Media drivers
#
#
# Drivers filtered as selected at 'Filter media drivers'
#
#
# Media drivers
#
CONFIG_MEDIA_USB_SUPPORT=y
#
# Webcam devices
#
CONFIG_USB_GSPCA=y
CONFIG_USB_GSPCA_BENQ=y
CONFIG_USB_GSPCA_CONEX=y
CONFIG_USB_GSPCA_CPIA1=y
CONFIG_USB_GSPCA_DTCS033=y
CONFIG_USB_GSPCA_ETOMS=y
CONFIG_USB_GSPCA_FINEPIX=y
CONFIG_USB_GSPCA_JEILINJ=y
CONFIG_USB_GSPCA_JL2005BCD=y
CONFIG_USB_GSPCA_KINECT=y
CONFIG_USB_GSPCA_KONICA=y
CONFIG_USB_GSPCA_MARS=y
CONFIG_USB_GSPCA_MR97310A=y
CONFIG_USB_GSPCA_NW80X=y
CONFIG_USB_GSPCA_OV519=y
CONFIG_USB_GSPCA_OV534=y
CONFIG_USB_GSPCA_OV534_9=y
CONFIG_USB_GSPCA_PAC207=y
CONFIG_USB_GSPCA_PAC7302=y
CONFIG_USB_GSPCA_PAC7311=y
CONFIG_USB_GSPCA_SE401=y
CONFIG_USB_GSPCA_SN9C2028=y
CONFIG_USB_GSPCA_SN9C20X=y
CONFIG_USB_GSPCA_SONIXB=y
CONFIG_USB_GSPCA_SONIXJ=y
CONFIG_USB_GSPCA_SPCA1528=y
CONFIG_USB_GSPCA_SPCA500=y
CONFIG_USB_GSPCA_SPCA501=y
CONFIG_USB_GSPCA_SPCA505=y
CONFIG_USB_GSPCA_SPCA506=y
CONFIG_USB_GSPCA_SPCA508=y
CONFIG_USB_GSPCA_SPCA561=y
CONFIG_USB_GSPCA_SQ905=y
CONFIG_USB_GSPCA_SQ905C=y
CONFIG_USB_GSPCA_SQ930X=y
CONFIG_USB_GSPCA_STK014=y
CONFIG_USB_GSPCA_STK1135=y
CONFIG_USB_GSPCA_STV0680=y
CONFIG_USB_GSPCA_SUNPLUS=y
CONFIG_USB_GSPCA_T613=y
CONFIG_USB_GSPCA_TOPRO=y
CONFIG_USB_GSPCA_TOUPTEK=y
CONFIG_USB_GSPCA_TV8532=y
CONFIG_USB_GSPCA_VC032X=y
CONFIG_USB_GSPCA_VICAM=y
CONFIG_USB_GSPCA_XIRLINK_CIT=y
CONFIG_USB_GSPCA_ZC3XX=y
CONFIG_USB_GL860=y
CONFIG_USB_M5602=y
CONFIG_USB_STV06XX=y
CONFIG_USB_PWC=y
CONFIG_USB_PWC_DEBUG=y
CONFIG_USB_PWC_INPUT_EVDEV=y
CONFIG_USB_S2255=y
CONFIG_VIDEO_USBTV=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
#
# Analog TV USB devices
#
CONFIG_VIDEO_GO7007=y
CONFIG_VIDEO_GO7007_USB=y
CONFIG_VIDEO_GO7007_LOADER=y
CONFIG_VIDEO_GO7007_USB_S2250_BOARD=y
CONFIG_VIDEO_HDPVR=y
CONFIG_VIDEO_PVRUSB2=y
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
CONFIG_VIDEO_PVRUSB2_DEBUGIFC=y
CONFIG_VIDEO_STK1160_COMMON=y
CONFIG_VIDEO_STK1160=y
#
# Analog/digital TV USB devices
#
CONFIG_VIDEO_AU0828=y
CONFIG_VIDEO_AU0828_V4L2=y
CONFIG_VIDEO_AU0828_RC=y
CONFIG_VIDEO_CX231XX=y
CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_CX231XX_ALSA=y
CONFIG_VIDEO_CX231XX_DVB=y
#
# Digital TV USB devices
#
CONFIG_DVB_AS102=y
CONFIG_DVB_B2C2_FLEXCOP_USB=y
CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG=y
CONFIG_DVB_USB_V2=y
CONFIG_DVB_USB_AF9015=y
CONFIG_DVB_USB_AF9035=y
CONFIG_DVB_USB_ANYSEE=y
CONFIG_DVB_USB_AU6610=y
CONFIG_DVB_USB_AZ6007=y
CONFIG_DVB_USB_CE6230=y
CONFIG_DVB_USB_DVBSKY=y
CONFIG_DVB_USB_EC168=y
CONFIG_DVB_USB_GL861=y
CONFIG_DVB_USB_LME2510=y
CONFIG_DVB_USB_MXL111SF=y
CONFIG_DVB_USB_RTL28XXU=y
CONFIG_DVB_USB_ZD1301=y
CONFIG_DVB_USB=y
CONFIG_DVB_USB_DEBUG=y
CONFIG_DVB_USB_A800=y
CONFIG_DVB_USB_AF9005=y
CONFIG_DVB_USB_AF9005_REMOTE=y
CONFIG_DVB_USB_AZ6027=y
CONFIG_DVB_USB_CINERGY_T2=y
CONFIG_DVB_USB_CXUSB=y
CONFIG_DVB_USB_CXUSB_ANALOG=y
CONFIG_DVB_USB_DIB0700=y
CONFIG_DVB_USB_DIB3000MC=y
CONFIG_DVB_USB_DIBUSB_MB=y
CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
CONFIG_DVB_USB_DIBUSB_MC=y
CONFIG_DVB_USB_DIGITV=y
CONFIG_DVB_USB_DTT200U=y
CONFIG_DVB_USB_DTV5100=y
CONFIG_DVB_USB_DW2102=y
CONFIG_DVB_USB_GP8PSK=y
CONFIG_DVB_USB_M920X=y
CONFIG_DVB_USB_NOVA_T_USB2=y
CONFIG_DVB_USB_OPERA1=y
CONFIG_DVB_USB_PCTV452E=y
CONFIG_DVB_USB_TECHNISAT_USB2=y
CONFIG_DVB_USB_TTUSB2=y
CONFIG_DVB_USB_UMT_010=y
CONFIG_DVB_USB_VP702X=y
CONFIG_DVB_USB_VP7045=y
CONFIG_SMS_USB_DRV=y
CONFIG_DVB_TTUSB_BUDGET=y
CONFIG_DVB_TTUSB_DEC=y
#
# Webcam, TV (analog/digital) USB devices
#
CONFIG_VIDEO_EM28XX=y
CONFIG_VIDEO_EM28XX_V4L2=y
CONFIG_VIDEO_EM28XX_ALSA=y
CONFIG_VIDEO_EM28XX_DVB=y
CONFIG_VIDEO_EM28XX_RC=y
#
# Software defined radio USB devices
#
CONFIG_USB_AIRSPY=y
CONFIG_USB_HACKRF=y
CONFIG_USB_MSI2500=y
CONFIG_MEDIA_PCI_SUPPORT=y
#
# Media capture support
#
CONFIG_VIDEO_SOLO6X10=y
CONFIG_STA2X11_VIP=y
CONFIG_VIDEO_TW5864=y
CONFIG_VIDEO_TW68=y
CONFIG_VIDEO_TW686X=y
CONFIG_VIDEO_ZORAN=y
CONFIG_VIDEO_ZORAN_DC30=y
CONFIG_VIDEO_ZORAN_ZR36060=y
CONFIG_VIDEO_ZORAN_BUZ=y
CONFIG_VIDEO_ZORAN_DC10=y
CONFIG_VIDEO_ZORAN_LML33=y
CONFIG_VIDEO_ZORAN_LML33R10=y
CONFIG_VIDEO_ZORAN_AVS6EYES=y
#
# Media capture/analog TV support
#
CONFIG_VIDEO_DT3155=y
CONFIG_VIDEO_IVTV=y
CONFIG_VIDEO_IVTV_ALSA=y
CONFIG_VIDEO_FB_IVTV=y
#
# Media capture/analog/hybrid TV support
#
CONFIG_VIDEO_BT848=y
CONFIG_DVB_BT8XX=y
CONFIG_VIDEO_COBALT=y
CONFIG_VIDEO_CX18=y
CONFIG_VIDEO_CX18_ALSA=y
CONFIG_VIDEO_CX23885=y
CONFIG_MEDIA_ALTERA_CI=y
CONFIG_VIDEO_CX25821=y
CONFIG_VIDEO_CX25821_ALSA=y
CONFIG_VIDEO_CX88=y
CONFIG_VIDEO_CX88_ALSA=y
CONFIG_VIDEO_CX88_BLACKBIRD=y
CONFIG_VIDEO_CX88_DVB=y
CONFIG_VIDEO_CX88_ENABLE_VP3054=y
CONFIG_VIDEO_CX88_VP3054=y
CONFIG_VIDEO_CX88_MPEG=y
CONFIG_VIDEO_SAA7134=y
CONFIG_VIDEO_SAA7134_ALSA=y
CONFIG_VIDEO_SAA7134_RC=y
CONFIG_VIDEO_SAA7134_DVB=y
CONFIG_VIDEO_SAA7134_GO7007=y
CONFIG_VIDEO_SAA7164=y
#
# Media digital TV PCI Adapters
#
CONFIG_DVB_B2C2_FLEXCOP_PCI=y
CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG=y
CONFIG_DVB_DDBRIDGE=y
CONFIG_DVB_DDBRIDGE_MSIENABLE=y
CONFIG_DVB_DM1105=y
CONFIG_MANTIS_CORE=y
CONFIG_DVB_MANTIS=y
CONFIG_DVB_HOPPER=y
CONFIG_DVB_NETUP_UNIDVB=y
CONFIG_DVB_NGENE=y
CONFIG_DVB_PLUTO2=y
CONFIG_DVB_PT1=y
CONFIG_DVB_PT3=y
CONFIG_DVB_SMIPCIE=y
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_MAXIRADIO=y
CONFIG_RADIO_SAA7706H=y
CONFIG_RADIO_SHARK=y
CONFIG_RADIO_SHARK2=y
CONFIG_RADIO_SI4713=y
CONFIG_RADIO_SI476X=y
CONFIG_RADIO_TEA575X=y
CONFIG_RADIO_TEA5764=y
CONFIG_RADIO_TEA5764_XTAL=y
CONFIG_RADIO_TEF6862=y
CONFIG_RADIO_TIMBERDALE=y
CONFIG_RADIO_WL1273=y
CONFIG_USB_DSBR=y
CONFIG_USB_KEENE=y
CONFIG_USB_MA901=y
CONFIG_USB_MR800=y
CONFIG_USB_RAREMONO=y
CONFIG_RADIO_SI470X=y
CONFIG_USB_SI470X=y
CONFIG_I2C_SI470X=y
CONFIG_USB_SI4713=y
CONFIG_PLATFORM_SI4713=y
CONFIG_I2C_SI4713=y
CONFIG_RADIO_WL128X=y
CONFIG_V4L_RADIO_ISA_DRIVERS=y
CONFIG_RADIO_AZTECH=y
CONFIG_RADIO_AZTECH_PORT=350
CONFIG_RADIO_CADET=y
CONFIG_RADIO_GEMTEK=y
CONFIG_RADIO_GEMTEK_PORT=34c
CONFIG_RADIO_GEMTEK_PROBE=y
CONFIG_RADIO_ISA=y
CONFIG_RADIO_RTRACK=y
CONFIG_RADIO_RTRACK2=y
CONFIG_RADIO_RTRACK2_PORT=30c
CONFIG_RADIO_RTRACK_PORT=30f
CONFIG_RADIO_SF16FMI=y
CONFIG_RADIO_SF16FMR2=y
CONFIG_RADIO_TERRATEC=y
CONFIG_RADIO_TRUST=y
CONFIG_RADIO_TRUST_PORT=350
CONFIG_RADIO_TYPHOON=y
CONFIG_RADIO_TYPHOON_MUTEFREQ=87500
CONFIG_RADIO_TYPHOON_PORT=316
CONFIG_RADIO_ZOLTRIX=y
CONFIG_RADIO_ZOLTRIX_PORT=20c
CONFIG_MEDIA_PLATFORM_DRIVERS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_DVB_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_MEM2MEM_DEINTERLACE=y
CONFIG_VIDEO_MUX=y
#
# Allegro DVT media platform drivers
#
CONFIG_VIDEO_ALLEGRO_DVT=y
#
# Amlogic media platform drivers
#
CONFIG_VIDEO_MESON_GE2D=y
#
# Amphion drivers
#
CONFIG_VIDEO_AMPHION_VPU=y
#
# Aspeed media platform drivers
#
CONFIG_VIDEO_ASPEED=y
#
# Atmel media platform drivers
#
CONFIG_VIDEO_ATMEL_ISI=y
#
# Cadence media platform drivers
#
CONFIG_VIDEO_CADENCE_CSI2RX=y
CONFIG_VIDEO_CADENCE_CSI2TX=y
#
# Chips&Media media platform drivers
#
CONFIG_VIDEO_CODA=y
CONFIG_VIDEO_IMX_VDOA=y
#
# Intel media platform drivers
#
CONFIG_VIDEO_PXA27x=y
#
# Marvell media platform drivers
#
CONFIG_VIDEO_CAFE_CCIC=y
CONFIG_VIDEO_MMP_CAMERA=y
#
# Mediatek media platform drivers
#
CONFIG_VIDEO_MEDIATEK_JPEG=y
CONFIG_VIDEO_MEDIATEK_MDP=y
CONFIG_VIDEO_MEDIATEK_VCODEC_SCP=y
CONFIG_VIDEO_MEDIATEK_VCODEC_VPU=y
CONFIG_VIDEO_MEDIATEK_VCODEC=y
CONFIG_VIDEO_MEDIATEK_VPU=y
CONFIG_VIDEO_MEDIATEK_MDP3=y
#
# Microchip Technology, Inc. media platform drivers
#
CONFIG_VIDEO_MICROCHIP_ISC=y
CONFIG_VIDEO_MICROCHIP_XISC=y
CONFIG_VIDEO_MICROCHIP_ISC_BASE=y
CONFIG_VIDEO_MICROCHIP_CSI2DC=y
#
# NVidia media platform drivers
#
CONFIG_VIDEO_TEGRA_VDE=y
#
# NXP media platform drivers
#
CONFIG_VIDEO_IMX7_CSI=y
CONFIG_VIDEO_IMX_MIPI_CSIS=y
CONFIG_VIDEO_IMX_PXP=y
CONFIG_VIDEO_MX2_EMMAPRP=y
CONFIG_VIDEO_DW100=y
CONFIG_VIDEO_IMX8_JPEG=y
#
# Qualcomm media platform drivers
#
CONFIG_VIDEO_QCOM_CAMSS=y
CONFIG_VIDEO_QCOM_VENUS=y
#
# Renesas media platform drivers
#
CONFIG_VIDEO_RENESAS_CEU=y
CONFIG_VIDEO_RCAR_ISP=y
CONFIG_VIDEO_SH_VOU=y
CONFIG_VIDEO_RCAR_CSI2=y
CONFIG_VIDEO_RCAR_VIN=y
CONFIG_VIDEO_RZG2L_CSI2=y
CONFIG_VIDEO_RZG2L_CRU=y
CONFIG_VIDEO_RENESAS_FCP=y
CONFIG_VIDEO_RENESAS_FDP1=y
CONFIG_VIDEO_RENESAS_JPU=y
CONFIG_VIDEO_RENESAS_VSP1=y
CONFIG_VIDEO_RCAR_DRIF=y
#
# Rockchip media platform drivers
#
CONFIG_VIDEO_ROCKCHIP_RGA=y
CONFIG_VIDEO_ROCKCHIP_ISP1=y
#
# Samsung media platform drivers
#
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=y
CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=y
CONFIG_VIDEO_EXYNOS4_IS_COMMON=y
CONFIG_VIDEO_S5P_FIMC=y
CONFIG_VIDEO_S5P_MIPI_CSIS=y
CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
CONFIG_VIDEO_EXYNOS4_FIMC_IS=y
CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE=y
CONFIG_VIDEO_S3C_CAMIF=y
CONFIG_VIDEO_SAMSUNG_S5P_G2D=y
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=y
CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
#
# STMicroelectronics media platform drivers
#
CONFIG_VIDEO_STI_BDISP=y
CONFIG_DVB_C8SECTPFE=y
CONFIG_VIDEO_STI_DELTA=y
CONFIG_VIDEO_STI_DELTA_MJPEG=y
CONFIG_VIDEO_STI_DELTA_DRIVER=y
CONFIG_VIDEO_STI_HVA=y
CONFIG_VIDEO_STI_HVA_DEBUGFS=y
CONFIG_VIDEO_STM32_DCMI=y
CONFIG_VIDEO_STM32_DMA2D=y
#
# Sunxi media platform drivers
#
CONFIG_VIDEO_SUN4I_CSI=y
CONFIG_VIDEO_SUN6I_CSI=y
CONFIG_VIDEO_SUN6I_MIPI_CSI2=y
CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2=y
CONFIG_VIDEO_SUN8I_DEINTERLACE=y
CONFIG_VIDEO_SUN8I_ROTATE=y
#
# Texas Instruments drivers
#
CONFIG_VIDEO_TI_VPDMA=y
CONFIG_VIDEO_TI_SC=y
CONFIG_VIDEO_TI_CSC=y
CONFIG_VIDEO_TI_CAL=y
CONFIG_VIDEO_TI_CAL_MC=y
CONFIG_VIDEO_TI_VPE=y
CONFIG_VIDEO_TI_VPE_DEBUG=y
CONFIG_VIDEO_AM437X_VPFE=y
CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY=y
CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE=y
CONFIG_VIDEO_OMAP2_VOUT_VRFB=y
CONFIG_VIDEO_OMAP2_VOUT=y
CONFIG_VIDEO_OMAP3=y
CONFIG_VIDEO_OMAP3_DEBUG=y
#
# Verisilicon media platform drivers
#
CONFIG_VIDEO_HANTRO=y
CONFIG_VIDEO_HANTRO_IMX8M=y
CONFIG_VIDEO_HANTRO_SAMA5D4=y
CONFIG_VIDEO_HANTRO_ROCKCHIP=y
CONFIG_VIDEO_HANTRO_SUNXI=y
#
# VIA media platform drivers
#
CONFIG_VIDEO_VIA_CAMERA=y
#
# Xilinx media platform drivers
#
CONFIG_VIDEO_XILINX=y
CONFIG_VIDEO_XILINX_CSI2RXSS=y
CONFIG_VIDEO_XILINX_TPG=y
CONFIG_VIDEO_XILINX_VTC=y
#
# MMC/SDIO DVB adapters
#
CONFIG_SMS_SDIO_DRV=y
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=y
CONFIG_VIDEO_VICODEC=y
CONFIG_VIDEO_VIMC=y
CONFIG_VIDEO_VIVID=y
CONFIG_VIDEO_VIVID_CEC=y
CONFIG_VIDEO_VIVID_MAX_DEVS=64
CONFIG_VIDEO_VISL=y
CONFIG_VISL_DEBUGFS=y
CONFIG_DVB_TEST_DRIVERS=y
CONFIG_DVB_VIDTV=y
#
# FireWire (IEEE 1394) Adapters
#
CONFIG_DVB_FIREDTV=y
CONFIG_DVB_FIREDTV_INPUT=y
CONFIG_MEDIA_COMMON_OPTIONS=y
#
# common driver options
#
CONFIG_CYPRESS_FIRMWARE=y
CONFIG_TTPCI_EEPROM=y
CONFIG_VIDEO_CX2341X=y
CONFIG_VIDEO_TVEEPROM=y
CONFIG_DVB_B2C2_FLEXCOP=y
CONFIG_DVB_B2C2_FLEXCOP_DEBUG=y
CONFIG_SMS_SIANO_MDTV=y
CONFIG_SMS_SIANO_RC=y
CONFIG_SMS_SIANO_DEBUGFS=y
CONFIG_VIDEO_V4L2_TPG=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_V4L2=y
CONFIG_VIDEOBUF2_MEMOPS=y
CONFIG_VIDEOBUF2_DMA_CONTIG=y
CONFIG_VIDEOBUF2_VMALLOC=y
CONFIG_VIDEOBUF2_DMA_SG=y
CONFIG_VIDEOBUF2_DVB=y
# end of Media drivers
#
# Media ancillary drivers
#
CONFIG_MEDIA_ATTACH=y
#
# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
#
CONFIG_VIDEO_IR_I2C=y
#
# Camera sensor devices
#
CONFIG_VIDEO_APTINA_PLL=y
CONFIG_VIDEO_CCS_PLL=y
CONFIG_VIDEO_AR0521=y
CONFIG_VIDEO_HI556=y
CONFIG_VIDEO_HI846=y
CONFIG_VIDEO_HI847=y
CONFIG_VIDEO_IMX208=y
CONFIG_VIDEO_IMX214=y
CONFIG_VIDEO_IMX219=y
CONFIG_VIDEO_IMX258=y
CONFIG_VIDEO_IMX274=y
CONFIG_VIDEO_IMX290=y
CONFIG_VIDEO_IMX319=y
CONFIG_VIDEO_IMX334=y
CONFIG_VIDEO_IMX335=y
CONFIG_VIDEO_IMX355=y
CONFIG_VIDEO_IMX412=y
CONFIG_VIDEO_MAX9271_LIB=y
CONFIG_VIDEO_MT9M001=y
CONFIG_VIDEO_MT9M032=y
CONFIG_VIDEO_MT9M111=y
CONFIG_VIDEO_MT9P031=y
CONFIG_VIDEO_MT9T001=y
CONFIG_VIDEO_MT9T112=y
CONFIG_VIDEO_MT9V011=y
CONFIG_VIDEO_MT9V032=y
CONFIG_VIDEO_MT9V111=y
CONFIG_VIDEO_NOON010PC30=y
CONFIG_VIDEO_OG01A1B=y
CONFIG_VIDEO_OV02A10=y
CONFIG_VIDEO_OV08D10=y
CONFIG_VIDEO_OV08X40=y
CONFIG_VIDEO_OV13858=y
CONFIG_VIDEO_OV13B10=y
CONFIG_VIDEO_OV2640=y
CONFIG_VIDEO_OV2659=y
CONFIG_VIDEO_OV2680=y
CONFIG_VIDEO_OV2685=y
CONFIG_VIDEO_OV2740=y
CONFIG_VIDEO_OV4689=y
CONFIG_VIDEO_OV5640=y
CONFIG_VIDEO_OV5645=y
CONFIG_VIDEO_OV5647=y
CONFIG_VIDEO_OV5648=y
CONFIG_VIDEO_OV5670=y
CONFIG_VIDEO_OV5675=y
CONFIG_VIDEO_OV5693=y
CONFIG_VIDEO_OV5695=y
CONFIG_VIDEO_OV6650=y
CONFIG_VIDEO_OV7251=y
CONFIG_VIDEO_OV7640=y
CONFIG_VIDEO_OV7670=y
CONFIG_VIDEO_OV772X=y
CONFIG_VIDEO_OV7740=y
CONFIG_VIDEO_OV8856=y
CONFIG_VIDEO_OV8865=y
CONFIG_VIDEO_OV9282=y
CONFIG_VIDEO_OV9640=y
CONFIG_VIDEO_OV9650=y
CONFIG_VIDEO_OV9734=y
CONFIG_VIDEO_RDACM20=y
CONFIG_VIDEO_RDACM21=y
CONFIG_VIDEO_RJ54N1=y
CONFIG_VIDEO_S5C73M3=y
CONFIG_VIDEO_S5K5BAF=y
CONFIG_VIDEO_S5K6A3=y
CONFIG_VIDEO_S5K6AA=y
CONFIG_VIDEO_SR030PC30=y
CONFIG_VIDEO_ST_VGXY61=y
CONFIG_VIDEO_VS6624=y
CONFIG_VIDEO_CCS=y
CONFIG_VIDEO_ET8EK8=y
CONFIG_VIDEO_M5MOLS=y
# end of Camera sensor devices
#
# Lens drivers
#
CONFIG_VIDEO_AD5820=y
CONFIG_VIDEO_AK7375=y
CONFIG_VIDEO_DW9714=y
CONFIG_VIDEO_DW9768=y
CONFIG_VIDEO_DW9807_VCM=y
# end of Lens drivers
#
# Flash devices
#
CONFIG_VIDEO_ADP1653=y
CONFIG_VIDEO_LM3560=y
CONFIG_VIDEO_LM3646=y
# end of Flash devices
#
# Audio decoders, processors and mixers
#
CONFIG_VIDEO_CS3308=y
CONFIG_VIDEO_CS5345=y
CONFIG_VIDEO_CS53L32A=y
CONFIG_VIDEO_MSP3400=y
CONFIG_VIDEO_SONY_BTF_MPX=y
CONFIG_VIDEO_TDA1997X=y
CONFIG_VIDEO_TDA7432=y
CONFIG_VIDEO_TDA9840=y
CONFIG_VIDEO_TEA6415C=y
CONFIG_VIDEO_TEA6420=y
CONFIG_VIDEO_TLV320AIC23B=y
CONFIG_VIDEO_TVAUDIO=y
CONFIG_VIDEO_UDA1342=y
CONFIG_VIDEO_VP27SMPX=y
CONFIG_VIDEO_WM8739=y
CONFIG_VIDEO_WM8775=y
# end of Audio decoders, processors and mixers
#
# RDS decoders
#
CONFIG_VIDEO_SAA6588=y
# end of RDS decoders
#
# Video decoders
#
CONFIG_VIDEO_ADV7180=y
CONFIG_VIDEO_ADV7183=y
CONFIG_VIDEO_ADV748X=y
CONFIG_VIDEO_ADV7604=y
CONFIG_VIDEO_ADV7604_CEC=y
CONFIG_VIDEO_ADV7842=y
CONFIG_VIDEO_ADV7842_CEC=y
CONFIG_VIDEO_BT819=y
CONFIG_VIDEO_BT856=y
CONFIG_VIDEO_BT866=y
CONFIG_VIDEO_ISL7998X=y
CONFIG_VIDEO_KS0127=y
CONFIG_VIDEO_MAX9286=y
CONFIG_VIDEO_ML86V7667=y
CONFIG_VIDEO_SAA7110=y
CONFIG_VIDEO_SAA711X=y
CONFIG_VIDEO_TC358743=y
CONFIG_VIDEO_TC358743_CEC=y
CONFIG_VIDEO_TC358746=y
CONFIG_VIDEO_TVP514X=y
CONFIG_VIDEO_TVP5150=y
CONFIG_VIDEO_TVP7002=y
CONFIG_VIDEO_TW2804=y
CONFIG_VIDEO_TW9903=y
CONFIG_VIDEO_TW9906=y
CONFIG_VIDEO_TW9910=y
CONFIG_VIDEO_VPX3220=y
#
# Video and audio decoders
#
CONFIG_VIDEO_SAA717X=y
CONFIG_VIDEO_CX25840=y
# end of Video decoders
#
# Video encoders
#
CONFIG_VIDEO_AD9389B=y
CONFIG_VIDEO_ADV7170=y
CONFIG_VIDEO_ADV7175=y
CONFIG_VIDEO_ADV7343=y
CONFIG_VIDEO_ADV7393=y
CONFIG_VIDEO_ADV7511=y
CONFIG_VIDEO_ADV7511_CEC=y
CONFIG_VIDEO_AK881X=y
CONFIG_VIDEO_SAA7127=y
CONFIG_VIDEO_SAA7185=y
CONFIG_VIDEO_THS8200=y
# end of Video encoders
#
# Video improvement chips
#
CONFIG_VIDEO_UPD64031A=y
CONFIG_VIDEO_UPD64083=y
# end of Video improvement chips
#
# Audio/Video compression chips
#
CONFIG_VIDEO_SAA6752HS=y
# end of Audio/Video compression chips
#
# SDR tuner chips
#
CONFIG_SDR_MAX2175=y
# end of SDR tuner chips
#
# Miscellaneous helper chips
#
CONFIG_VIDEO_I2C=y
CONFIG_VIDEO_M52790=y
CONFIG_VIDEO_ST_MIPID02=y
CONFIG_VIDEO_THS7303=y
# end of Miscellaneous helper chips
#
# Media SPI Adapters
#
CONFIG_CXD2880_SPI_DRV=y
CONFIG_VIDEO_GS1662=y
# end of Media SPI Adapters
CONFIG_MEDIA_TUNER=y
#
# Customize TV tuners
#
CONFIG_MEDIA_TUNER_E4000=y
CONFIG_MEDIA_TUNER_FC0011=y
CONFIG_MEDIA_TUNER_FC0012=y
CONFIG_MEDIA_TUNER_FC0013=y
CONFIG_MEDIA_TUNER_FC2580=y
CONFIG_MEDIA_TUNER_IT913X=y
CONFIG_MEDIA_TUNER_M88RS6000T=y
CONFIG_MEDIA_TUNER_MAX2165=y
CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_MEDIA_TUNER_MSI001=y
CONFIG_MEDIA_TUNER_MT2060=y
CONFIG_MEDIA_TUNER_MT2063=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_MT2131=y
CONFIG_MEDIA_TUNER_MT2266=y
CONFIG_MEDIA_TUNER_MXL301RF=y
CONFIG_MEDIA_TUNER_MXL5005S=y
CONFIG_MEDIA_TUNER_MXL5007T=y
CONFIG_MEDIA_TUNER_QM1D1B0004=y
CONFIG_MEDIA_TUNER_QM1D1C0042=y
CONFIG_MEDIA_TUNER_QT1010=y
CONFIG_MEDIA_TUNER_R820T=y
CONFIG_MEDIA_TUNER_SI2157=y
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA18212=y
CONFIG_MEDIA_TUNER_TDA18218=y
CONFIG_MEDIA_TUNER_TDA18250=y
CONFIG_MEDIA_TUNER_TDA18271=y
CONFIG_MEDIA_TUNER_TDA827X=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
CONFIG_MEDIA_TUNER_TEA5761=y
CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_TUA9001=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC4000=y
CONFIG_MEDIA_TUNER_XC5000=y
# end of Customize TV tuners
#
# Customise DVB Frontends
#
#
# Multistandard (satellite) frontends
#
CONFIG_DVB_M88DS3103=y
CONFIG_DVB_MXL5XX=y
CONFIG_DVB_STB0899=y
CONFIG_DVB_STB6100=y
CONFIG_DVB_STV090x=y
CONFIG_DVB_STV0910=y
CONFIG_DVB_STV6110x=y
CONFIG_DVB_STV6111=y
#
# Multistandard (cable + terrestrial) frontends
#
CONFIG_DVB_DRXK=y
CONFIG_DVB_MN88472=y
CONFIG_DVB_MN88473=y
CONFIG_DVB_SI2165=y
CONFIG_DVB_TDA18271C2DD=y
#
# DVB-S (satellite) frontends
#
CONFIG_DVB_CX24110=y
CONFIG_DVB_CX24116=y
CONFIG_DVB_CX24117=y
CONFIG_DVB_CX24120=y
CONFIG_DVB_CX24123=y
CONFIG_DVB_DS3000=y
CONFIG_DVB_MB86A16=y
CONFIG_DVB_MT312=y
CONFIG_DVB_S5H1420=y
CONFIG_DVB_SI21XX=y
CONFIG_DVB_STB6000=y
CONFIG_DVB_STV0288=y
CONFIG_DVB_STV0299=y
CONFIG_DVB_STV0900=y
CONFIG_DVB_STV6110=y
CONFIG_DVB_TDA10071=y
CONFIG_DVB_TDA10086=y
CONFIG_DVB_TDA8083=y
CONFIG_DVB_TDA8261=y
CONFIG_DVB_TDA826X=y
CONFIG_DVB_TS2020=y
CONFIG_DVB_TUA6100=y
CONFIG_DVB_TUNER_CX24113=y
CONFIG_DVB_TUNER_ITD1000=y
CONFIG_DVB_VES1X93=y
CONFIG_DVB_ZL10036=y
CONFIG_DVB_ZL10039=y
#
# DVB-T (terrestrial) frontends
#
CONFIG_DVB_AF9013=y
CONFIG_DVB_AS102_FE=y
CONFIG_DVB_CX22700=y
CONFIG_DVB_CX22702=y
CONFIG_DVB_CXD2820R=y
CONFIG_DVB_CXD2841ER=y
CONFIG_DVB_DIB3000MB=y
CONFIG_DVB_DIB3000MC=y
CONFIG_DVB_DIB7000M=y
CONFIG_DVB_DIB7000P=y
CONFIG_DVB_DIB9000=y
CONFIG_DVB_DRXD=y
CONFIG_DVB_EC100=y
CONFIG_DVB_GP8PSK_FE=y
CONFIG_DVB_L64781=y
CONFIG_DVB_MT352=y
CONFIG_DVB_NXT6000=y
CONFIG_DVB_RTL2830=y
CONFIG_DVB_RTL2832=y
CONFIG_DVB_RTL2832_SDR=y
CONFIG_DVB_S5H1432=y
CONFIG_DVB_SI2168=y
CONFIG_DVB_SP887X=y
CONFIG_DVB_STV0367=y
CONFIG_DVB_TDA10048=y
CONFIG_DVB_TDA1004X=y
CONFIG_DVB_ZD1301_DEMOD=y
CONFIG_DVB_ZL10353=y
CONFIG_DVB_CXD2880=y
#
# DVB-C (cable) frontends
#
CONFIG_DVB_STV0297=y
CONFIG_DVB_TDA10021=y
CONFIG_DVB_TDA10023=y
CONFIG_DVB_VES1820=y
#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
CONFIG_DVB_AU8522=y
CONFIG_DVB_AU8522_DTV=y
CONFIG_DVB_AU8522_V4L=y
CONFIG_DVB_BCM3510=y
CONFIG_DVB_LG2160=y
CONFIG_DVB_LGDT3305=y
CONFIG_DVB_LGDT3306A=y
CONFIG_DVB_LGDT330X=y
CONFIG_DVB_MXL692=y
CONFIG_DVB_NXT200X=y
CONFIG_DVB_OR51132=y
CONFIG_DVB_OR51211=y
CONFIG_DVB_S5H1409=y
CONFIG_DVB_S5H1411=y
#
# ISDB-T (terrestrial) frontends
#
CONFIG_DVB_DIB8000=y
CONFIG_DVB_MB86A20S=y
CONFIG_DVB_S921=y
#
# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
#
CONFIG_DVB_MN88443X=y
CONFIG_DVB_TC90522=y
#
# Digital terrestrial only tuners/PLL
#
CONFIG_DVB_PLL=y
CONFIG_DVB_TUNER_DIB0070=y
CONFIG_DVB_TUNER_DIB0090=y
#
# SEC control devices for DVB-S
#
CONFIG_DVB_A8293=y
CONFIG_DVB_AF9033=y
CONFIG_DVB_ASCOT2E=y
CONFIG_DVB_ATBM8830=y
CONFIG_DVB_HELENE=y
CONFIG_DVB_HORUS3A=y
CONFIG_DVB_ISL6405=y
CONFIG_DVB_ISL6421=y
CONFIG_DVB_ISL6423=y
CONFIG_DVB_IX2505V=y
CONFIG_DVB_LGS8GL5=y
CONFIG_DVB_LGS8GXX=y
CONFIG_DVB_LNBH25=y
CONFIG_DVB_LNBH29=y
CONFIG_DVB_LNBP21=y
CONFIG_DVB_LNBP22=y
CONFIG_DVB_M88RS2000=y
CONFIG_DVB_TDA665x=y
CONFIG_DVB_DRX39XYJ=y
#
# Common Interface (EN50221) controller drivers
#
CONFIG_DVB_CXD2099=y
CONFIG_DVB_SP2=y
# end of Customise DVB Frontends
#
# Tools to develop new frontends
#
CONFIG_DVB_DUMMY_FE=y
# end of Media ancillary drivers
#
# Graphics support
#
CONFIG_APERTURE_HELPERS=y
CONFIG_VIDEO_NOMODESET=y
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
CONFIG_TEGRA_HOST1X=y
CONFIG_TEGRA_HOST1X_FIREWALL=y
CONFIG_IMX_IPUV3_CORE=y
CONFIG_DRM=y
CONFIG_DRM_MIPI_DBI=y
CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_DEBUG_MM=y
CONFIG_DRM_USE_DYNAMIC_DEBUG=y
CONFIG_DRM_KUNIT_TEST_HELPERS=y
CONFIG_DRM_KUNIT_TEST=y
CONFIG_DRM_KMS_HELPER=y
CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS=y
CONFIG_DRM_DEBUG_MODESET_LOCK=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM=y
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
CONFIG_DRM_DP_AUX_BUS=y
CONFIG_DRM_DISPLAY_HELPER=y
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_HDCP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DP_AUX_CHARDEV=y
CONFIG_DRM_DP_CEC=y
CONFIG_DRM_TTM=y
CONFIG_DRM_BUDDY=y
CONFIG_DRM_VRAM_HELPER=y
CONFIG_DRM_TTM_HELPER=y
CONFIG_DRM_GEM_DMA_HELPER=y
CONFIG_DRM_GEM_SHMEM_HELPER=y
CONFIG_DRM_SCHED=y
#
# I2C encoder or helper chips
#
CONFIG_DRM_I2C_CH7006=y
CONFIG_DRM_I2C_SIL164=y
CONFIG_DRM_I2C_NXP_TDA998X=y
CONFIG_DRM_I2C_NXP_TDA9950=y
# end of I2C encoder or helper chips
#
# ARM devices
#
CONFIG_DRM_HDLCD=y
CONFIG_DRM_HDLCD_SHOW_UNDERRUN=y
CONFIG_DRM_MALI_DISPLAY=y
CONFIG_DRM_KOMEDA=y
# end of ARM devices
CONFIG_DRM_RADEON=y
CONFIG_DRM_RADEON_USERPTR=y
CONFIG_DRM_AMDGPU=y
CONFIG_DRM_AMDGPU_SI=y
CONFIG_DRM_AMDGPU_CIK=y
CONFIG_DRM_AMDGPU_USERPTR=y
#
# ACP (Audio CoProcessor) Configuration
#
CONFIG_DRM_AMD_ACP=y
# end of ACP (Audio CoProcessor) Configuration
#
# Display Engine Configuration
#
CONFIG_DRM_AMD_DC=y
CONFIG_DRM_AMD_DC_HDCP=y
CONFIG_DRM_AMD_DC_SI=y
CONFIG_DEBUG_KERNEL_DC=y
# end of Display Engine Configuration
CONFIG_DRM_NOUVEAU=y
CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y
CONFIG_NOUVEAU_PLATFORM_DRIVER=y
CONFIG_NOUVEAU_DEBUG=5
CONFIG_NOUVEAU_DEBUG_DEFAULT=3
CONFIG_NOUVEAU_DEBUG_MMU=y
CONFIG_NOUVEAU_DEBUG_PUSH=y
CONFIG_DRM_NOUVEAU_BACKLIGHT=y
CONFIG_DRM_KMB_DISPLAY=y
CONFIG_DRM_VGEM=y
CONFIG_DRM_VKMS=y
CONFIG_DRM_EXYNOS=y
#
# CRTCs
#
CONFIG_DRM_EXYNOS5433_DECON=y
CONFIG_DRM_EXYNOS_MIXER=y
CONFIG_DRM_EXYNOS_VIDI=y
#
# Encoders and Bridges
#
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_EXYNOS_MIC=y
#
# Sub-drivers
#
CONFIG_DRM_EXYNOS_G2D=y
CONFIG_DRM_EXYNOS_IPP=y
CONFIG_DRM_EXYNOS_FIMC=y
CONFIG_DRM_EXYNOS_ROTATOR=y
CONFIG_DRM_EXYNOS_SCALER=y
CONFIG_DRM_EXYNOS_GSC=y
CONFIG_DRM_ROCKCHIP=y
CONFIG_ROCKCHIP_VOP=y
CONFIG_ROCKCHIP_VOP2=y
CONFIG_ROCKCHIP_ANALOGIX_DP=y
CONFIG_ROCKCHIP_CDN_DP=y
CONFIG_ROCKCHIP_DW_HDMI=y
CONFIG_ROCKCHIP_DW_MIPI_DSI=y
CONFIG_ROCKCHIP_INNO_HDMI=y
CONFIG_ROCKCHIP_LVDS=y
CONFIG_ROCKCHIP_RGB=y
CONFIG_ROCKCHIP_RK3066_HDMI=y
CONFIG_DRM_UDL=y
CONFIG_DRM_AST=y
CONFIG_DRM_MGAG200=y
CONFIG_DRM_ARMADA=y
CONFIG_DRM_ATMEL_HLCDC=y
CONFIG_DRM_RCAR_DU=y
CONFIG_DRM_RCAR_USE_CMM=y
CONFIG_DRM_RCAR_CMM=y
CONFIG_DRM_RCAR_DW_HDMI=y
CONFIG_DRM_RCAR_USE_LVDS=y
CONFIG_DRM_RCAR_LVDS=y
CONFIG_DRM_RCAR_USE_MIPI_DSI=y
CONFIG_DRM_RCAR_MIPI_DSI=y
CONFIG_DRM_RZG2L_MIPI_DSI=y
CONFIG_DRM_RCAR_VSP=y
CONFIG_DRM_SHMOBILE=y
CONFIG_DRM_SUN4I=y
CONFIG_DRM_SUN4I_HDMI=y
CONFIG_DRM_SUN4I_HDMI_CEC=y
CONFIG_DRM_SUN4I_BACKEND=y
CONFIG_DRM_SUN6I_DSI=y
CONFIG_DRM_SUN8I_DW_HDMI=y
CONFIG_DRM_SUN8I_MIXER=y
CONFIG_DRM_SUN8I_TCON_TOP=y
CONFIG_DRM_OMAP=y
CONFIG_OMAP2_DSS_DEBUG=y
CONFIG_OMAP2_DSS_DEBUGFS=y
CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS=y
CONFIG_OMAP2_DSS_DPI=y
CONFIG_OMAP2_DSS_VENC=y
CONFIG_OMAP2_DSS_HDMI_COMMON=y
CONFIG_OMAP4_DSS_HDMI=y
CONFIG_OMAP4_DSS_HDMI_CEC=y
CONFIG_OMAP5_DSS_HDMI=y
CONFIG_OMAP2_DSS_SDI=y
CONFIG_OMAP2_DSS_DSI=y
CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
CONFIG_DRM_TILCDC=y
CONFIG_DRM_QXL=y
CONFIG_DRM_VIRTIO_GPU=y
CONFIG_DRM_MSM=y
CONFIG_DRM_MSM_GPU_STATE=y
CONFIG_DRM_MSM_GPU_SUDO=y
CONFIG_DRM_MSM_MDSS=y
CONFIG_DRM_MSM_MDP4=y
CONFIG_DRM_MSM_MDP5=y
CONFIG_DRM_MSM_DPU=y
CONFIG_DRM_MSM_DP=y
CONFIG_DRM_MSM_DSI=y
CONFIG_DRM_MSM_DSI_28NM_PHY=y
CONFIG_DRM_MSM_DSI_20NM_PHY=y
CONFIG_DRM_MSM_DSI_28NM_8960_PHY=y
CONFIG_DRM_MSM_DSI_14NM_PHY=y
CONFIG_DRM_MSM_DSI_10NM_PHY=y
CONFIG_DRM_MSM_DSI_7NM_PHY=y
CONFIG_DRM_MSM_HDMI=y
CONFIG_DRM_MSM_HDMI_HDCP=y
CONFIG_DRM_FSL_DCU=y
CONFIG_DRM_TEGRA=y
CONFIG_DRM_TEGRA_DEBUG=y
CONFIG_DRM_TEGRA_STAGING=y
CONFIG_DRM_STM=y
CONFIG_DRM_STM_DSI=y
CONFIG_DRM_PANEL=y
#
# Display Panels
#
CONFIG_DRM_PANEL_ABT_Y030XX067A=y
CONFIG_DRM_PANEL_ARM_VERSATILE=y
CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596=y
CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0=y
CONFIG_DRM_PANEL_BOE_HIMAX8279D=y
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=y
CONFIG_DRM_PANEL_DSI_CM=y
CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PANEL_EBBG_FT8719=y
CONFIG_DRM_PANEL_ELIDA_KD35T133=y
CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=y
CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=y
CONFIG_DRM_PANEL_ILITEK_IL9322=y
CONFIG_DRM_PANEL_ILITEK_ILI9341=y
CONFIG_DRM_PANEL_ILITEK_ILI9881C=y
CONFIG_DRM_PANEL_INNOLUX_EJ030NA=y
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y
CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=y
CONFIG_DRM_PANEL_JDI_LT070ME05000=y
CONFIG_DRM_PANEL_JDI_R63452=y
CONFIG_DRM_PANEL_KHADAS_TS050=y
CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=y
CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W=y
CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
CONFIG_DRM_PANEL_LG_LB035Q02=y
CONFIG_DRM_PANEL_LG_LG4573=y
CONFIG_DRM_PANEL_NEC_NL8048HL11=y
CONFIG_DRM_PANEL_NEWVISION_NV3051D=y
CONFIG_DRM_PANEL_NEWVISION_NV3052C=y
CONFIG_DRM_PANEL_NOVATEK_NT35510=y
CONFIG_DRM_PANEL_NOVATEK_NT35560=y
CONFIG_DRM_PANEL_NOVATEK_NT35950=y
CONFIG_DRM_PANEL_NOVATEK_NT36672A=y
CONFIG_DRM_PANEL_NOVATEK_NT39016=y
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=y
CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=y
CONFIG_DRM_PANEL_ORISETECH_OTA5601A=y
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=y
CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=y
CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=y
CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y
CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
CONFIG_DRM_PANEL_RAYDIUM_RM68200=y
CONFIG_DRM_PANEL_RONBO_RB070D30=y
CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y
CONFIG_DRM_PANEL_SAMSUNG_DB7430=y
CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=y
CONFIG_DRM_PANEL_SAMSUNG_S6D27A1=y
CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI=y
CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
CONFIG_DRM_PANEL_SAMSUNG_SOFEF00=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=y
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=y
CONFIG_DRM_PANEL_SHARP_LS043T1LE01=y
CONFIG_DRM_PANEL_SHARP_LS060T1SX01=y
CONFIG_DRM_PANEL_SITRONIX_ST7701=y
CONFIG_DRM_PANEL_SITRONIX_ST7703=y
CONFIG_DRM_PANEL_SITRONIX_ST7789V=y
CONFIG_DRM_PANEL_SONY_ACX565AKM=y
CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521=y
CONFIG_DRM_PANEL_TDO_TL070WSH30=y
CONFIG_DRM_PANEL_TPO_TD028TTEC1=y
CONFIG_DRM_PANEL_TPO_TD043MTEA1=y
CONFIG_DRM_PANEL_TPO_TPG110=y
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=y
CONFIG_DRM_PANEL_VISIONOX_RM69299=y
CONFIG_DRM_PANEL_VISIONOX_VTDR6130=y
CONFIG_DRM_PANEL_WIDECHIPS_WS2401=y
CONFIG_DRM_PANEL_XINPENG_XPP055C272=y
# end of Display Panels
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
#
# Display Interface Bridges
#
CONFIG_DRM_CDNS_DSI=y
CONFIG_DRM_CHIPONE_ICN6211=y
CONFIG_DRM_CHRONTEL_CH7033=y
CONFIG_DRM_CROS_EC_ANX7688=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_FSL_LDB=y
CONFIG_DRM_ITE_IT6505=y
CONFIG_DRM_LONTIUM_LT8912B=y
CONFIG_DRM_LONTIUM_LT9211=y
CONFIG_DRM_LONTIUM_LT9611=y
CONFIG_DRM_LONTIUM_LT9611UXC=y
CONFIG_DRM_ITE_IT66121=y
CONFIG_DRM_LVDS_CODEC=y
CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW=y
CONFIG_DRM_NWL_MIPI_DSI=y
CONFIG_DRM_NXP_PTN3460=y
CONFIG_DRM_PARADE_PS8622=y
CONFIG_DRM_PARADE_PS8640=y
CONFIG_DRM_SIL_SII8620=y
CONFIG_DRM_SII902X=y
CONFIG_DRM_SII9234=y
CONFIG_DRM_SIMPLE_BRIDGE=y
CONFIG_DRM_THINE_THC63LVD1024=y
CONFIG_DRM_TOSHIBA_TC358762=y
CONFIG_DRM_TOSHIBA_TC358764=y
CONFIG_DRM_TOSHIBA_TC358767=y
CONFIG_DRM_TOSHIBA_TC358768=y
CONFIG_DRM_TOSHIBA_TC358775=y
CONFIG_DRM_TI_DLPC3433=y
CONFIG_DRM_TI_TFP410=y
CONFIG_DRM_TI_SN65DSI83=y
CONFIG_DRM_TI_SN65DSI86=y
CONFIG_DRM_TI_TPD12S015=y
CONFIG_DRM_ANALOGIX_ANX6345=y
CONFIG_DRM_ANALOGIX_ANX78XX=y
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_ANALOGIX_ANX7625=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_DRM_I2C_ADV7511_CEC=y
CONFIG_DRM_CDNS_MHDP8546=y
CONFIG_DRM_CDNS_MHDP8546_J721E=y
CONFIG_DRM_IMX8QM_LDB=y
CONFIG_DRM_IMX8QXP_LDB=y
CONFIG_DRM_IMX8QXP_PIXEL_COMBINER=y
CONFIG_DRM_IMX8QXP_PIXEL_LINK=y
CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI=y
CONFIG_DRM_DW_HDMI=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=y
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
CONFIG_DRM_DW_HDMI_GP_AUDIO=y
CONFIG_DRM_DW_HDMI_CEC=y
CONFIG_DRM_DW_MIPI_DSI=y
# end of Display Interface Bridges
CONFIG_DRM_STI=y
CONFIG_DRM_IMX=y
CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
CONFIG_DRM_IMX_TVE=y
CONFIG_DRM_IMX_LDB=y
CONFIG_DRM_IMX_HDMI=y
CONFIG_DRM_INGENIC=y
CONFIG_DRM_INGENIC_IPU=y
CONFIG_DRM_V3D=y
CONFIG_DRM_VC4=y
CONFIG_DRM_VC4_HDMI_CEC=y
CONFIG_DRM_VC4_KUNIT_TEST=y
CONFIG_DRM_ETNAVIV=y
CONFIG_DRM_ETNAVIV_THERMAL=y
CONFIG_DRM_HISI_HIBMC=y
CONFIG_DRM_LOGICVC=y
CONFIG_DRM_MEDIATEK=y
CONFIG_DRM_MEDIATEK_DP=y
CONFIG_DRM_MEDIATEK_HDMI=y
CONFIG_DRM_MXS=y
CONFIG_DRM_MXSFB=y
CONFIG_DRM_IMX_LCDIF=y
CONFIG_DRM_MESON=y
CONFIG_DRM_MESON_DW_HDMI=y
CONFIG_DRM_ARCPGU=y
CONFIG_DRM_BOCHS=y
CONFIG_DRM_CIRRUS_QEMU=y
CONFIG_DRM_GM12U320=y
CONFIG_DRM_OFDRM=y
CONFIG_DRM_PANEL_MIPI_DBI=y
CONFIG_DRM_SIMPLEDRM=y
CONFIG_TINYDRM_HX8357D=y
CONFIG_TINYDRM_ILI9163=y
CONFIG_TINYDRM_ILI9225=y
CONFIG_TINYDRM_ILI9341=y
CONFIG_TINYDRM_ILI9486=y
CONFIG_TINYDRM_MI0283QT=y
CONFIG_TINYDRM_REPAPER=y
CONFIG_TINYDRM_ST7586=y
CONFIG_TINYDRM_ST7735R=y
CONFIG_DRM_PL111=y
CONFIG_DRM_TVE200=y
CONFIG_DRM_LIMA=y
CONFIG_DRM_PANFROST=y
CONFIG_DRM_ASPEED_GFX=y
CONFIG_DRM_MCDE=y
CONFIG_DRM_TIDSS=y
CONFIG_DRM_ZYNQMP_DPSUB=y
CONFIG_DRM_GUD=y
CONFIG_DRM_SSD130X=y
CONFIG_DRM_SSD130X_I2C=y
CONFIG_DRM_SSD130X_SPI=y
CONFIG_DRM_SPRD=y
CONFIG_DRM_LEGACY=y
CONFIG_DRM_TDFX=y
CONFIG_DRM_R128=y
CONFIG_DRM_MGA=y
CONFIG_DRM_VIA=y
CONFIG_DRM_SAVAGE=y
CONFIG_DRM_EXPORT_FOR_TESTS=y
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
CONFIG_DRM_LIB_RANDOM=y
#
# Frame buffer Devices
#
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DDC=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_CFB_REV_PIXELS_IN_BYTE=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA=y
CONFIG_FB_FOREIGN_ENDIAN=y
CONFIG_FB_BOTH_ENDIAN=y
# CONFIG_FB_BIG_ENDIAN is not set
# CONFIG_FB_LITTLE_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_SVGALIB=y
CONFIG_FB_MACMODES=y
CONFIG_FB_BACKLIGHT=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
#
# Frame buffer hardware drivers
#
CONFIG_FB_CIRRUS=y
CONFIG_FB_PM2=y
CONFIG_FB_PM2_FIFO_DISCONNECT=y
CONFIG_FB_ARMCLCD=y
CONFIG_FB_CLPS711X=y
CONFIG_FB_IMX=y
CONFIG_FB_CYBER2000=y
CONFIG_FB_CYBER2000_DDC=y
CONFIG_FB_ARC=y
CONFIG_FB_CONTROL=y
CONFIG_FB_ASILIANT=y
CONFIG_FB_IMSTT=y
CONFIG_FB_UVESA=y
CONFIG_FB_EFI=y
CONFIG_FB_GBE=y
CONFIG_FB_GBE_MEM=4
CONFIG_FB_PVR2=y
CONFIG_FB_OPENCORES=y
CONFIG_FB_S1D13XXX=y
CONFIG_FB_ATMEL=y
CONFIG_FB_NVIDIA=y
CONFIG_FB_NVIDIA_I2C=y
CONFIG_FB_NVIDIA_DEBUG=y
CONFIG_FB_NVIDIA_BACKLIGHT=y
CONFIG_FB_RIVA=y
CONFIG_FB_RIVA_I2C=y
CONFIG_FB_RIVA_DEBUG=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_I740=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_I2C=y
CONFIG_FB_MATROX_MAVEN=y
CONFIG_FB_RADEON=y
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_BACKLIGHT=y
CONFIG_FB_RADEON_DEBUG=y
CONFIG_FB_ATY128=y
CONFIG_FB_ATY128_BACKLIGHT=y
CONFIG_FB_ATY=y
CONFIG_FB_ATY_CT=y
CONFIG_FB_ATY_GENERIC_LCD=y
CONFIG_FB_ATY_GX=y
CONFIG_FB_ATY_BACKLIGHT=y
CONFIG_FB_S3=y
CONFIG_FB_S3_DDC=y
CONFIG_FB_SAVAGE=y
CONFIG_FB_SAVAGE_I2C=y
CONFIG_FB_SAVAGE_ACCEL=y
CONFIG_FB_SIS=y
CONFIG_FB_SIS_300=y
CONFIG_FB_SIS_315=y
CONFIG_FB_VIA=y
CONFIG_FB_VIA_DIRECT_PROCFS=y
CONFIG_FB_VIA_X_COMPATIBILITY=y
CONFIG_FB_NEOMAGIC=y
CONFIG_FB_KYRO=y
CONFIG_FB_3DFX=y
CONFIG_FB_3DFX_ACCEL=y
CONFIG_FB_3DFX_I2C=y
CONFIG_FB_VOODOO1=y
CONFIG_FB_VT8623=y
CONFIG_FB_TRIDENT=y
CONFIG_FB_ARK=y
CONFIG_FB_PM3=y
CONFIG_FB_CARMINE=y
CONFIG_FB_CARMINE_DRAM_EVAL=y
# CONFIG_CARMINE_DRAM_CUSTOM is not set
CONFIG_FB_VT8500=y
CONFIG_FB_WM8505=y
CONFIG_FB_WMT_GE_ROPS=y
CONFIG_FB_PXA168=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FB_S3C=y
CONFIG_FB_S3C_DEBUG_REGWRITE=y
CONFIG_FB_SM501=y
CONFIG_FB_SMSCUFX=y
CONFIG_FB_UDL=y
CONFIG_FB_IBM_GXT4500=y
CONFIG_FB_XILINX=y
CONFIG_FB_GOLDFISH=y
CONFIG_FB_DA8XX=y
CONFIG_FB_VIRTUAL=y
CONFIG_FB_METRONOME=y
CONFIG_FB_MB862XX=y
CONFIG_FB_MB862XX_PCI_GDC=y
CONFIG_FB_MB862XX_I2C=y
CONFIG_FB_MX3=y
CONFIG_FB_BROADSHEET=y
CONFIG_FB_SSD1307=y
CONFIG_FB_SM712=y
CONFIG_FB_OMAP=y
CONFIG_FB_OMAP_LCDC_EXTERNAL=y
CONFIG_FB_OMAP_LCDC_HWA742=y
CONFIG_FB_OMAP_MANUAL_UPDATE=y
CONFIG_FB_OMAP_LCD_MIPID=y
CONFIG_FB_OMAP_DMA_TUNE=y
CONFIG_OMAP2_VRFB=y
CONFIG_MMP_DISP=y
CONFIG_MMP_DISP_CONTROLLER=y
CONFIG_MMP_DISP_SPI=y
CONFIG_MMP_PANEL_TPOHVGA=y
CONFIG_MMP_FB=y
# end of Frame buffer Devices
#
# Backlight & LCD device support
#
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_L4F00242T03=y
CONFIG_LCD_LMS283GF05=y
CONFIG_LCD_LTV350QV=y
CONFIG_LCD_ILI922X=y
CONFIG_LCD_ILI9320=y
CONFIG_LCD_TDO24M=y
CONFIG_LCD_VGG2432A4=y
CONFIG_LCD_PLATFORM=y
CONFIG_LCD_AMS369FG06=y
CONFIG_LCD_LMS501KF03=y
CONFIG_LCD_HX8357=y
CONFIG_LCD_OTM3225A=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_ATMEL_LCDC=y
CONFIG_BACKLIGHT_KTD253=y
CONFIG_BACKLIGHT_LM3533=y
CONFIG_BACKLIGHT_OMAP1=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_DA903X=y
CONFIG_BACKLIGHT_DA9052=y
CONFIG_BACKLIGHT_MAX8925=y
CONFIG_BACKLIGHT_MT6370=y
CONFIG_BACKLIGHT_QCOM_WLED=y
CONFIG_BACKLIGHT_RT4831=y
CONFIG_BACKLIGHT_WM831X=y
CONFIG_BACKLIGHT_ADP5520=y
CONFIG_BACKLIGHT_ADP8860=y
CONFIG_BACKLIGHT_ADP8870=y
CONFIG_BACKLIGHT_88PM860X=y
CONFIG_BACKLIGHT_PCF50633=y
CONFIG_BACKLIGHT_AAT2870=y
CONFIG_BACKLIGHT_LM3630A=y
CONFIG_BACKLIGHT_LM3639=y
CONFIG_BACKLIGHT_LP855X=y
CONFIG_BACKLIGHT_LP8788=y
CONFIG_BACKLIGHT_PANDORA=y
CONFIG_BACKLIGHT_SKY81452=y
CONFIG_BACKLIGHT_TPS65217=y
CONFIG_BACKLIGHT_AS3711=y
CONFIG_BACKLIGHT_GPIO=y
CONFIG_BACKLIGHT_LV5207LP=y
CONFIG_BACKLIGHT_BD6107=y
CONFIG_BACKLIGHT_ARCXCNN=y
CONFIG_BACKLIGHT_RAVE_SP=y
CONFIG_BACKLIGHT_LED=y
# end of Backlight & LCD device support
CONFIG_VGASTATE=y
CONFIG_VIDEOMODE_HELPERS=y
CONFIG_HDMI=y
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
# end of Console display driver support
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
# end of Graphics support
CONFIG_DRM_ACCEL=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_PCM_ELD=y
CONFIG_SND_PCM_IEC958=y
CONFIG_SND_DMAENGINE_PCM=y
CONFIG_SND_HWDEP=y
CONFIG_SND_SEQ_DEVICE=y
CONFIG_SND_RAWMIDI=y
CONFIG_SND_COMPRESS_OFFLOAD=y
CONFIG_SND_JACK=y
CONFIG_SND_JACK_INPUT_DEV=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_PCM_TIMER=y
CONFIG_SND_HRTIMER=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_MAX_CARDS=32
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_PROC_FS=y
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_CTL_FAST_LOOKUP=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_PCM_XRUN_DEBUG=y
CONFIG_SND_CTL_INPUT_VALIDATION=y
CONFIG_SND_CTL_DEBUG=y
CONFIG_SND_JACK_INJECTION_DEBUG=y
CONFIG_SND_VMASTER=y
CONFIG_SND_CTL_LED=y
CONFIG_SND_SEQUENCER=y
CONFIG_SND_SEQ_DUMMY=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
CONFIG_SND_SEQ_MIDI_EVENT=y
CONFIG_SND_SEQ_MIDI=y
CONFIG_SND_SEQ_MIDI_EMUL=y
CONFIG_SND_SEQ_VIRMIDI=y
CONFIG_SND_MPU401_UART=y
CONFIG_SND_OPL3_LIB=y
CONFIG_SND_OPL3_LIB_SEQ=y
CONFIG_SND_VX_LIB=y
CONFIG_SND_AC97_CODEC=y
CONFIG_SND_DRIVERS=y
CONFIG_SND_DUMMY=y
CONFIG_SND_ALOOP=y
CONFIG_SND_VIRMIDI=y
CONFIG_SND_MTPAV=y
CONFIG_SND_MTS64=y
CONFIG_SND_SERIAL_U16550=y
CONFIG_SND_SERIAL_GENERIC=y
CONFIG_SND_MPU401=y
CONFIG_SND_PORTMAN2X4=y
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
CONFIG_SND_PCI=y
CONFIG_SND_AD1889=y
CONFIG_SND_ALS300=y
CONFIG_SND_ALI5451=y
CONFIG_SND_ATIIXP=y
CONFIG_SND_ATIIXP_MODEM=y
CONFIG_SND_AU8810=y
CONFIG_SND_AU8820=y
CONFIG_SND_AU8830=y
CONFIG_SND_AW2=y
CONFIG_SND_AZT3328=y
CONFIG_SND_BT87X=y
CONFIG_SND_BT87X_OVERCLOCK=y
CONFIG_SND_CA0106=y
CONFIG_SND_CMIPCI=y
CONFIG_SND_OXYGEN_LIB=y
CONFIG_SND_OXYGEN=y
CONFIG_SND_CS4281=y
CONFIG_SND_CS46XX=y
CONFIG_SND_CS46XX_NEW_DSP=y
CONFIG_SND_CS5535AUDIO=y
CONFIG_SND_CTXFI=y
CONFIG_SND_DARLA20=y
CONFIG_SND_GINA20=y
CONFIG_SND_LAYLA20=y
CONFIG_SND_DARLA24=y
CONFIG_SND_GINA24=y
CONFIG_SND_LAYLA24=y
CONFIG_SND_MONA=y
CONFIG_SND_MIA=y
CONFIG_SND_ECHO3G=y
CONFIG_SND_INDIGO=y
CONFIG_SND_INDIGOIO=y
CONFIG_SND_INDIGODJ=y
CONFIG_SND_INDIGOIOX=y
CONFIG_SND_INDIGODJX=y
CONFIG_SND_EMU10K1=y
CONFIG_SND_EMU10K1_SEQ=y
CONFIG_SND_EMU10K1X=y
CONFIG_SND_ENS1370=y
CONFIG_SND_ENS1371=y
CONFIG_SND_ES1938=y
CONFIG_SND_ES1968=y
CONFIG_SND_ES1968_INPUT=y
CONFIG_SND_ES1968_RADIO=y
CONFIG_SND_FM801=y
CONFIG_SND_FM801_TEA575X_BOOL=y
CONFIG_SND_HDSP=y
#
# Don't forget to add built-in firmwares for HDSP driver
#
CONFIG_SND_HDSPM=y
CONFIG_SND_ICE1712=y
CONFIG_SND_ICE1724=y
CONFIG_SND_INTEL8X0=y
CONFIG_SND_INTEL8X0M=y
CONFIG_SND_KORG1212=y
CONFIG_SND_LOLA=y
CONFIG_SND_MAESTRO3=y
CONFIG_SND_MAESTRO3_INPUT=y
CONFIG_SND_MIXART=y
CONFIG_SND_NM256=y
CONFIG_SND_PCXHR=y
CONFIG_SND_RIPTIDE=y
CONFIG_SND_RME32=y
CONFIG_SND_RME96=y
CONFIG_SND_RME9652=y
CONFIG_SND_SONICVIBES=y
CONFIG_SND_TRIDENT=y
CONFIG_SND_VIA82XX=y
CONFIG_SND_VIA82XX_MODEM=y
CONFIG_SND_VIRTUOSO=y
CONFIG_SND_VX222=y
CONFIG_SND_YMFPCI=y
#
# HD-Audio
#
CONFIG_SND_HDA=y
CONFIG_SND_HDA_GENERIC_LEDS=y
CONFIG_SND_HDA_INTEL=y
CONFIG_SND_HDA_TEGRA=y
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_RECONFIG=y
CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_INPUT_BEEP_MODE=1
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_CODEC_REALTEK=y
CONFIG_SND_HDA_CODEC_ANALOG=y
CONFIG_SND_HDA_CODEC_SIGMATEL=y
CONFIG_SND_HDA_CODEC_VIA=y
CONFIG_SND_HDA_CODEC_HDMI=y
CONFIG_SND_HDA_CODEC_CIRRUS=y
CONFIG_SND_HDA_CODEC_CS8409=y
CONFIG_SND_HDA_CODEC_CONEXANT=y
CONFIG_SND_HDA_CODEC_CA0110=y
CONFIG_SND_HDA_CODEC_CA0132=y
CONFIG_SND_HDA_CODEC_CA0132_DSP=y
CONFIG_SND_HDA_CODEC_CMEDIA=y
CONFIG_SND_HDA_CODEC_SI3054=y
CONFIG_SND_HDA_GENERIC=y
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM=y
# end of HD-Audio
CONFIG_SND_HDA_CORE=y
CONFIG_SND_HDA_DSP_LOADER=y
CONFIG_SND_HDA_ALIGNED_MMIO=y
CONFIG_SND_HDA_COMPONENT=y
CONFIG_SND_HDA_EXT_CORE=y
CONFIG_SND_HDA_PREALLOC_SIZE=64
CONFIG_SND_INTEL_DSP_CONFIG=y
CONFIG_SND_ARM=y
CONFIG_SND_ARMAACI=y
CONFIG_SND_PXA2XX_LIB=y
#
# Atmel devices (AT91)
#
CONFIG_SND_ATMEL_AC97C=y
# end of Atmel devices (AT91)
CONFIG_SND_SPI=y
CONFIG_SND_AT73C213=y
CONFIG_SND_AT73C213_TARGET_BITRATE=48000
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
CONFIG_SND_USB_UA101=y
CONFIG_SND_USB_CAIAQ=y
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_US122L=y
CONFIG_SND_USB_6FIRE=y
CONFIG_SND_USB_HIFACE=y
CONFIG_SND_BCD2000=y
CONFIG_SND_USB_LINE6=y
CONFIG_SND_USB_POD=y
CONFIG_SND_USB_PODHD=y
CONFIG_SND_USB_TONEPORT=y
CONFIG_SND_USB_VARIAX=y
CONFIG_SND_FIREWIRE=y
CONFIG_SND_FIREWIRE_LIB=y
CONFIG_SND_DICE=y
CONFIG_SND_OXFW=y
CONFIG_SND_ISIGHT=y
CONFIG_SND_FIREWORKS=y
CONFIG_SND_BEBOB=y
CONFIG_SND_FIREWIRE_DIGI00X=y
CONFIG_SND_FIREWIRE_TASCAM=y
CONFIG_SND_FIREWIRE_MOTU=y
CONFIG_SND_FIREFACE=y
CONFIG_SND_PCMCIA=y
CONFIG_SND_VXPOCKET=y
CONFIG_SND_PDAUDIOCF=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_SOC_COMPRESS=y
CONFIG_SND_SOC_TOPOLOGY=y
CONFIG_SND_SOC_TOPOLOGY_KUNIT_TEST=y
CONFIG_SND_SOC_UTILS_KUNIT_TEST=y
CONFIG_SND_SOC_ADI=y
CONFIG_SND_SOC_ADI_AXI_I2S=y
CONFIG_SND_SOC_ADI_AXI_SPDIF=y
CONFIG_SND_SOC_AMD_ACP=y
CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=y
CONFIG_SND_AMD_ACP_CONFIG=y
CONFIG_SND_SOC_APPLE_MCA=y
CONFIG_SND_ATMEL_SOC=y
CONFIG_SND_ATMEL_SOC_PDC=y
CONFIG_SND_ATMEL_SOC_DMA=y
CONFIG_SND_ATMEL_SOC_SSC=y
CONFIG_SND_ATMEL_SOC_SSC_PDC=y
CONFIG_SND_ATMEL_SOC_SSC_DMA=y
CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y
CONFIG_SND_ATMEL_SOC_WM8904=y
CONFIG_SND_AT91_SOC_SAM9X5_WM8731=y
CONFIG_SND_ATMEL_SOC_CLASSD=y
CONFIG_SND_ATMEL_SOC_PDMIC=y
CONFIG_SND_ATMEL_SOC_TSE850_PCM5142=y
CONFIG_SND_ATMEL_SOC_I2S=y
CONFIG_SND_SOC_MIKROE_PROTO=y
CONFIG_SND_MCHP_SOC_I2S_MCC=y
CONFIG_SND_MCHP_SOC_SPDIFTX=y
CONFIG_SND_MCHP_SOC_SPDIFRX=y
CONFIG_SND_MCHP_SOC_PDMC=y
CONFIG_SND_BCM2835_SOC_I2S=y
CONFIG_SND_SOC_CYGNUS=y
CONFIG_SND_BCM63XX_I2S_WHISTLER=y
CONFIG_SND_EP93XX_SOC=y
CONFIG_SND_DESIGNWARE_I2S=y
CONFIG_SND_DESIGNWARE_PCM=y
#
# SoC Audio for Freescale CPUs
#
#
# Common SoC Audio options for Freescale CPUs:
#
CONFIG_SND_SOC_FSL_ASRC=y
CONFIG_SND_SOC_FSL_SAI=y
CONFIG_SND_SOC_FSL_MQS=y
CONFIG_SND_SOC_FSL_AUDMIX=y
CONFIG_SND_SOC_FSL_SSI=y
CONFIG_SND_SOC_FSL_SPDIF=y
CONFIG_SND_SOC_FSL_ESAI=y
CONFIG_SND_SOC_FSL_MICFIL=y
CONFIG_SND_SOC_FSL_EASRC=y
CONFIG_SND_SOC_FSL_XCVR=y
CONFIG_SND_SOC_FSL_AUD2HTX=y
CONFIG_SND_SOC_FSL_UTILS=y
CONFIG_SND_SOC_FSL_RPMSG=y
CONFIG_SND_SOC_IMX_PCM_DMA=y
CONFIG_SND_SOC_IMX_AUDIO_RPMSG=y
CONFIG_SND_SOC_IMX_PCM_RPMSG=y
CONFIG_SND_SOC_IMX_AUDMUX=y
CONFIG_SND_IMX_SOC=y
CONFIG_SND_SOC_IMX_PCM_FIQ=y
#
# SoC Audio support for Freescale i.MX boards:
#
CONFIG_SND_SOC_EUKREA_TLV320=y
CONFIG_SND_SOC_IMX_ES8328=y
CONFIG_SND_SOC_IMX_SGTL5000=y
CONFIG_SND_SOC_IMX_SPDIF=y
CONFIG_SND_SOC_FSL_ASOC_CARD=y
CONFIG_SND_SOC_IMX_AUDMIX=y
CONFIG_SND_SOC_IMX_HDMI=y
CONFIG_SND_SOC_IMX_RPMSG=y
CONFIG_SND_SOC_IMX_CARD=y
# end of SoC Audio for Freescale CPUs
CONFIG_SND_I2S_HI6210_I2S=y
CONFIG_SND_JZ4740_SOC_I2S=y
CONFIG_SND_KIRKWOOD_SOC=y
CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB=y
CONFIG_SND_SOC_IMG=y
CONFIG_SND_SOC_IMG_I2S_IN=y
CONFIG_SND_SOC_IMG_I2S_OUT=y
CONFIG_SND_SOC_IMG_PARALLEL_OUT=y
CONFIG_SND_SOC_IMG_SPDIF_IN=y
CONFIG_SND_SOC_IMG_SPDIF_OUT=y
CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=y
CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
CONFIG_SND_SOC_ACPI_INTEL_MATCH=y
CONFIG_SND_SOC_INTEL_KEEMBAY=y
CONFIG_SND_SOC_INTEL_AVS=y
#
# Intel AVS Machine drivers
#
#
# Available DSP configurations
#
CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219=y
CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC=y
CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO=y
CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST=y
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927=y
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A=y
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373=y
CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825=y
CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE=y
CONFIG_SND_SOC_INTEL_AVS_MACH_RT274=y
CONFIG_SND_SOC_INTEL_AVS_MACH_RT286=y
CONFIG_SND_SOC_INTEL_AVS_MACH_RT298=y
CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682=y
CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567=y
# end of Intel AVS Machine drivers
CONFIG_SND_SOC_INTEL_MACH=y
CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES=y
CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=y
CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=y
CONFIG_SND_SOC_INTEL_BROADWELL_MACH=y
CONFIG_SND_SOC_MEDIATEK=y
CONFIG_SND_SOC_MT2701=y
CONFIG_SND_SOC_MT2701_CS42448=y
CONFIG_SND_SOC_MT2701_WM8960=y
CONFIG_SND_SOC_MT6797=y
CONFIG_SND_SOC_MT6797_MT6351=y
CONFIG_SND_SOC_MT8173=y
CONFIG_SND_SOC_MT8173_MAX98090=y
CONFIG_SND_SOC_MT8173_RT5650=y
CONFIG_SND_SOC_MT8173_RT5650_RT5514=y
CONFIG_SND_SOC_MT8173_RT5650_RT5676=y
CONFIG_SND_SOC_MT8183=y
CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A=y
CONFIG_SND_SOC_MT8183_DA7219_MAX98357A=y
CONFIG_SND_SOC_MT8186=y
CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357=y
CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S=y
CONFIG_SND_SOC_MTK_BTCVSD=y
CONFIG_SND_SOC_MT8192=y
CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682=y
CONFIG_SND_SOC_MT8195=y
CONFIG_SND_SOC_MT8195_MT6359=y
#
# ASoC support for Amlogic platforms
#
CONFIG_SND_MESON_AIU=y
CONFIG_SND_MESON_AXG_FIFO=y
CONFIG_SND_MESON_AXG_FRDDR=y
CONFIG_SND_MESON_AXG_TODDR=y
CONFIG_SND_MESON_AXG_TDM_FORMATTER=y
CONFIG_SND_MESON_AXG_TDM_INTERFACE=y
CONFIG_SND_MESON_AXG_TDMIN=y
CONFIG_SND_MESON_AXG_TDMOUT=y
CONFIG_SND_MESON_AXG_SOUND_CARD=y
CONFIG_SND_MESON_AXG_SPDIFOUT=y
CONFIG_SND_MESON_AXG_SPDIFIN=y
CONFIG_SND_MESON_AXG_PDM=y
CONFIG_SND_MESON_CARD_UTILS=y
CONFIG_SND_MESON_CODEC_GLUE=y
CONFIG_SND_MESON_GX_SOUND_CARD=y
CONFIG_SND_MESON_G12A_TOACODEC=y
CONFIG_SND_MESON_G12A_TOHDMITX=y
CONFIG_SND_SOC_MESON_T9015=y
# end of ASoC support for Amlogic platforms
CONFIG_SND_MXS_SOC=y
CONFIG_SND_SOC_MXS_SGTL5000=y
CONFIG_SND_PXA2XX_SOC=y
CONFIG_SND_PXA_SOC_SSP=y
CONFIG_SND_MMP_SOC_SSPA=y
CONFIG_SND_PXA910_SOC=y
CONFIG_SND_SOC_QCOM=y
CONFIG_SND_SOC_LPASS_CPU=y
CONFIG_SND_SOC_LPASS_HDMI=y
CONFIG_SND_SOC_LPASS_PLATFORM=y
CONFIG_SND_SOC_LPASS_CDC_DMA=y
CONFIG_SND_SOC_LPASS_IPQ806X=y
CONFIG_SND_SOC_LPASS_APQ8016=y
CONFIG_SND_SOC_LPASS_SC7180=y
CONFIG_SND_SOC_LPASS_SC7280=y
CONFIG_SND_SOC_STORM=y
CONFIG_SND_SOC_APQ8016_SBC=y
CONFIG_SND_SOC_QCOM_COMMON=y
CONFIG_SND_SOC_QCOM_SDW=y
CONFIG_SND_SOC_QDSP6_COMMON=y
CONFIG_SND_SOC_QDSP6_CORE=y
CONFIG_SND_SOC_QDSP6_AFE=y
CONFIG_SND_SOC_QDSP6_AFE_DAI=y
CONFIG_SND_SOC_QDSP6_AFE_CLOCKS=y
CONFIG_SND_SOC_QDSP6_ADM=y
CONFIG_SND_SOC_QDSP6_ROUTING=y
CONFIG_SND_SOC_QDSP6_ASM=y
CONFIG_SND_SOC_QDSP6_ASM_DAI=y
CONFIG_SND_SOC_QDSP6_APM_DAI=y
CONFIG_SND_SOC_QDSP6_APM_LPASS_DAI=y
CONFIG_SND_SOC_QDSP6_APM=y
CONFIG_SND_SOC_QDSP6_PRM_LPASS_CLOCKS=y
CONFIG_SND_SOC_QDSP6_PRM=y
CONFIG_SND_SOC_QDSP6=y
CONFIG_SND_SOC_MSM8996=y
CONFIG_SND_SOC_SDM845=y
CONFIG_SND_SOC_SM8250=y
CONFIG_SND_SOC_SC8280XP=y
CONFIG_SND_SOC_SC7180=y
CONFIG_SND_SOC_SC7280=y
CONFIG_SND_SOC_ROCKCHIP=y
CONFIG_SND_SOC_ROCKCHIP_I2S=y
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y
CONFIG_SND_SOC_ROCKCHIP_PDM=y
CONFIG_SND_SOC_ROCKCHIP_SPDIF=y
CONFIG_SND_SOC_ROCKCHIP_MAX98090=y
CONFIG_SND_SOC_ROCKCHIP_RT5645=y
CONFIG_SND_SOC_RK3288_HDMI_ANALOG=y
CONFIG_SND_SOC_RK3399_GRU_SOUND=y
CONFIG_SND_SOC_SAMSUNG=y
CONFIG_SND_SAMSUNG_PCM=y
CONFIG_SND_SAMSUNG_SPDIF=y
CONFIG_SND_SAMSUNG_I2S=y
CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=y
CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=y
CONFIG_SND_SOC_SMDK_WM8994_PCM=y
CONFIG_SND_SOC_SPEYSIDE=y
CONFIG_SND_SOC_TOBERMORY=y
CONFIG_SND_SOC_BELLS=y
CONFIG_SND_SOC_LOWLAND=y
CONFIG_SND_SOC_LITTLEMILL=y
CONFIG_SND_SOC_SNOW=y
CONFIG_SND_SOC_ODROID=y
CONFIG_SND_SOC_ARNDALE=y
CONFIG_SND_SOC_SAMSUNG_TM2_WM5110=y
CONFIG_SND_SOC_SAMSUNG_ARIES_WM8994=y
CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=y
#
# SoC Audio support for Renesas SoCs
#
CONFIG_SND_SOC_SH4_FSI=y
CONFIG_SND_SOC_RCAR=y
CONFIG_SND_SOC_RZ=y
# end of SoC Audio support for Renesas SoCs
CONFIG_SND_SOC_SOF_TOPLEVEL=y
CONFIG_SND_SOC_SOF_PCI_DEV=y
CONFIG_SND_SOC_SOF_PCI=y
CONFIG_SND_SOC_SOF_ACPI=y
CONFIG_SND_SOC_SOF_ACPI_DEV=y
CONFIG_SND_SOC_SOF_OF=y
CONFIG_SND_SOC_SOF_OF_DEV=y
CONFIG_SND_SOC_SOF_COMPRESS=y
CONFIG_SND_SOC_SOF_DEBUG_PROBES=y
CONFIG_SND_SOC_SOF_CLIENT=y
CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT=y
CONFIG_SND_SOC_SOF_FORCE_PROBE_WORKQUEUE=y
CONFIG_SND_SOC_SOF_NOCODEC=y
CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT=y
CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS=y
CONFIG_SND_SOC_SOF_DEBUG=y
CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE=y
CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP=y
CONFIG_SND_SOC_SOF_DEBUG_VERBOSE_IPC=y
CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE=y
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST=y
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM=2
CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR=y
CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT=y
CONFIG_SND_SOC_SOF=y
CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y
CONFIG_SND_SOC_SOF_IPC3=y
CONFIG_SND_SOC_SOF_INTEL_IPC4=y
CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=y
CONFIG_SND_SOC_SOF_AMD_COMMON=y
CONFIG_SND_SOC_SOF_AMD_RENOIR=y
CONFIG_SND_SOC_SOF_AMD_REMBRANDT=y
CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
CONFIG_SND_SOC_SOF_IMX_COMMON=y
CONFIG_SND_SOC_SOF_IMX8=y
CONFIG_SND_SOC_SOF_IMX8M=y
CONFIG_SND_SOC_SOF_IMX8ULP=y
CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y
CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=y
CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=y
CONFIG_SND_SOC_SOF_INTEL_COMMON=y
CONFIG_SND_SOC_SOF_BAYTRAIL=y
CONFIG_SND_SOC_SOF_BROADWELL=y
CONFIG_SND_SOC_SOF_MERRIFIELD=y
CONFIG_SND_SOC_SOF_INTEL_SKL=y
CONFIG_SND_SOC_SOF_SKYLAKE=y
CONFIG_SND_SOC_SOF_KABYLAKE=y
CONFIG_SND_SOC_SOF_INTEL_APL=y
CONFIG_SND_SOC_SOF_APOLLOLAKE=y
CONFIG_SND_SOC_SOF_GEMINILAKE=y
CONFIG_SND_SOC_SOF_INTEL_CNL=y
CONFIG_SND_SOC_SOF_CANNONLAKE=y
CONFIG_SND_SOC_SOF_COFFEELAKE=y
CONFIG_SND_SOC_SOF_COMETLAKE=y
CONFIG_SND_SOC_SOF_INTEL_ICL=y
CONFIG_SND_SOC_SOF_ICELAKE=y
CONFIG_SND_SOC_SOF_JASPERLAKE=y
CONFIG_SND_SOC_SOF_INTEL_TGL=y
CONFIG_SND_SOC_SOF_TIGERLAKE=y
CONFIG_SND_SOC_SOF_ELKHARTLAKE=y
CONFIG_SND_SOC_SOF_ALDERLAKE=y
CONFIG_SND_SOC_SOF_INTEL_MTL=y
CONFIG_SND_SOC_SOF_METEORLAKE=y
CONFIG_SND_SOC_SOF_HDA_COMMON=y
CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE=y
CONFIG_SND_SOC_SOF_HDA_PROBES=y
CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE=y
CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y
CONFIG_SND_SOC_SOF_MTK_COMMON=y
CONFIG_SND_SOC_SOF_MT8186=y
CONFIG_SND_SOC_SOF_MT8195=y
CONFIG_SND_SOC_SOF_XTENSA=y
CONFIG_SND_SOC_SPRD=y
CONFIG_SND_SOC_SPRD_MCDT=y
CONFIG_SND_SOC_STI=y
#
# STMicroelectronics STM32 SOC audio support
#
CONFIG_SND_SOC_STM32_SAI=y
CONFIG_SND_SOC_STM32_I2S=y
CONFIG_SND_SOC_STM32_SPDIFRX=y
CONFIG_SND_SOC_STM32_DFSDM=y
# end of STMicroelectronics STM32 SOC audio support
#
# Allwinner SoC Audio support
#
CONFIG_SND_SUN4I_CODEC=y
CONFIG_SND_SUN8I_CODEC=y
CONFIG_SND_SUN8I_CODEC_ANALOG=y
CONFIG_SND_SUN50I_CODEC_ANALOG=y
CONFIG_SND_SUN4I_I2S=y
CONFIG_SND_SUN4I_SPDIF=y
CONFIG_SND_SUN50I_DMIC=y
CONFIG_SND_SUN8I_ADDA_PR_REGMAP=y
# end of Allwinner SoC Audio support
CONFIG_SND_SOC_TEGRA=y
CONFIG_SND_SOC_TEGRA20_AC97=y
CONFIG_SND_SOC_TEGRA20_DAS=y
CONFIG_SND_SOC_TEGRA20_I2S=y
CONFIG_SND_SOC_TEGRA20_SPDIF=y
CONFIG_SND_SOC_TEGRA30_AHUB=y
CONFIG_SND_SOC_TEGRA30_I2S=y
CONFIG_SND_SOC_TEGRA210_AHUB=y
CONFIG_SND_SOC_TEGRA210_DMIC=y
CONFIG_SND_SOC_TEGRA210_I2S=y
CONFIG_SND_SOC_TEGRA210_OPE=y
CONFIG_SND_SOC_TEGRA186_ASRC=y
CONFIG_SND_SOC_TEGRA186_DSPK=y
CONFIG_SND_SOC_TEGRA210_ADMAIF=y
CONFIG_SND_SOC_TEGRA210_MVC=y
CONFIG_SND_SOC_TEGRA210_SFC=y
CONFIG_SND_SOC_TEGRA210_AMX=y
CONFIG_SND_SOC_TEGRA210_ADX=y
CONFIG_SND_SOC_TEGRA210_MIXER=y
CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD=y
CONFIG_SND_SOC_TEGRA_MACHINE_DRV=y
CONFIG_SND_SOC_TEGRA_RT5640=y
CONFIG_SND_SOC_TEGRA_WM8753=y
CONFIG_SND_SOC_TEGRA_WM8903=y
CONFIG_SND_SOC_TEGRA_WM9712=y
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
CONFIG_SND_SOC_TEGRA_ALC5632=y
CONFIG_SND_SOC_TEGRA_MAX98090=y
CONFIG_SND_SOC_TEGRA_RT5677=y
CONFIG_SND_SOC_TEGRA_SGTL5000=y
#
# Audio support for Texas Instruments SoCs
#
CONFIG_SND_SOC_TI_EDMA_PCM=y
CONFIG_SND_SOC_TI_SDMA_PCM=y
CONFIG_SND_SOC_TI_UDMA_PCM=y
#
# Texas Instruments DAI support for:
#
CONFIG_SND_SOC_DAVINCI_ASP=y
CONFIG_SND_SOC_DAVINCI_MCASP=y
CONFIG_SND_SOC_OMAP_DMIC=y
CONFIG_SND_SOC_OMAP_MCBSP=y
CONFIG_SND_SOC_OMAP_MCPDM=y
#
# Audio support for boards with Texas Instruments SoCs
#
CONFIG_SND_SOC_NOKIA_N810=y
CONFIG_SND_SOC_NOKIA_RX51=y
CONFIG_SND_SOC_OMAP3_PANDORA=y
CONFIG_SND_SOC_OMAP3_TWL4030=y
CONFIG_SND_SOC_OMAP_ABE_TWL6040=y
CONFIG_SND_SOC_OMAP_HDMI=y
CONFIG_SND_SOC_J721E_EVM=y
# end of Audio support for Texas Instruments SoCs
CONFIG_SND_SOC_UNIPHIER=y
CONFIG_SND_SOC_UNIPHIER_AIO=y
CONFIG_SND_SOC_UNIPHIER_LD11=y
CONFIG_SND_SOC_UNIPHIER_PXS2=y
CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC=y
CONFIG_SND_SOC_UX500=y
CONFIG_SND_SOC_UX500_PLAT_MSP_I2S=y
CONFIG_SND_SOC_UX500_PLAT_DMA=y
CONFIG_SND_SOC_UX500_MACH_MOP500=y
CONFIG_SND_SOC_XILINX_I2S=y
CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=y
CONFIG_SND_SOC_XILINX_SPDIF=y
CONFIG_SND_SOC_XTFPGA_I2S=y
CONFIG_SND_SOC_I2C_AND_SPI=y
#
# CODEC drivers
#
CONFIG_SND_SOC_ALL_CODECS=y
CONFIG_SND_SOC_88PM860X=y
CONFIG_SND_SOC_ARIZONA=y
CONFIG_SND_SOC_WM_HUBS=y
CONFIG_SND_SOC_WM_ADSP=y
CONFIG_SND_SOC_AB8500_CODEC=y
CONFIG_SND_SOC_AC97_CODEC=y
CONFIG_SND_SOC_AD1836=y
CONFIG_SND_SOC_AD193X=y
CONFIG_SND_SOC_AD193X_SPI=y
CONFIG_SND_SOC_AD193X_I2C=y
CONFIG_SND_SOC_AD1980=y
CONFIG_SND_SOC_AD73311=y
CONFIG_SND_SOC_ADAU_UTILS=y
CONFIG_SND_SOC_ADAU1372=y
CONFIG_SND_SOC_ADAU1372_I2C=y
CONFIG_SND_SOC_ADAU1372_SPI=y
CONFIG_SND_SOC_ADAU1373=y
CONFIG_SND_SOC_ADAU1701=y
CONFIG_SND_SOC_ADAU17X1=y
CONFIG_SND_SOC_ADAU1761=y
CONFIG_SND_SOC_ADAU1761_I2C=y
CONFIG_SND_SOC_ADAU1761_SPI=y
CONFIG_SND_SOC_ADAU1781=y
CONFIG_SND_SOC_ADAU1781_I2C=y
CONFIG_SND_SOC_ADAU1781_SPI=y
CONFIG_SND_SOC_ADAU1977=y
CONFIG_SND_SOC_ADAU1977_SPI=y
CONFIG_SND_SOC_ADAU1977_I2C=y
CONFIG_SND_SOC_ADAU7002=y
CONFIG_SND_SOC_ADAU7118=y
CONFIG_SND_SOC_ADAU7118_HW=y
CONFIG_SND_SOC_ADAU7118_I2C=y
CONFIG_SND_SOC_ADAV80X=y
CONFIG_SND_SOC_ADAV801=y
CONFIG_SND_SOC_ADAV803=y
CONFIG_SND_SOC_ADS117X=y
CONFIG_SND_SOC_AK4104=y
CONFIG_SND_SOC_AK4118=y
CONFIG_SND_SOC_AK4375=y
CONFIG_SND_SOC_AK4458=y
CONFIG_SND_SOC_AK4535=y
CONFIG_SND_SOC_AK4554=y
CONFIG_SND_SOC_AK4613=y
CONFIG_SND_SOC_AK4641=y
CONFIG_SND_SOC_AK4642=y
CONFIG_SND_SOC_AK4671=y
CONFIG_SND_SOC_AK5386=y
CONFIG_SND_SOC_AK5558=y
CONFIG_SND_SOC_ALC5623=y
CONFIG_SND_SOC_ALC5632=y
CONFIG_SND_SOC_AW8738=y
CONFIG_SND_SOC_BD28623=y
CONFIG_SND_SOC_BT_SCO=y
CONFIG_SND_SOC_CPCAP=y
CONFIG_SND_SOC_CQ0093VC=y
CONFIG_SND_SOC_CROS_EC_CODEC=y
CONFIG_SND_SOC_CS35L32=y
CONFIG_SND_SOC_CS35L33=y
CONFIG_SND_SOC_CS35L34=y
CONFIG_SND_SOC_CS35L35=y
CONFIG_SND_SOC_CS35L36=y
CONFIG_SND_SOC_CS35L41_LIB=y
CONFIG_SND_SOC_CS35L41=y
CONFIG_SND_SOC_CS35L41_SPI=y
CONFIG_SND_SOC_CS35L41_I2C=y
CONFIG_SND_SOC_CS35L45_TABLES=y
CONFIG_SND_SOC_CS35L45=y
CONFIG_SND_SOC_CS35L45_SPI=y
CONFIG_SND_SOC_CS35L45_I2C=y
CONFIG_SND_SOC_CS42L42_CORE=y
CONFIG_SND_SOC_CS42L42=y
CONFIG_SND_SOC_CS42L51=y
CONFIG_SND_SOC_CS42L51_I2C=y
CONFIG_SND_SOC_CS42L52=y
CONFIG_SND_SOC_CS42L56=y
CONFIG_SND_SOC_CS42L73=y
CONFIG_SND_SOC_CS42L83=y
CONFIG_SND_SOC_CS4234=y
CONFIG_SND_SOC_CS4265=y
CONFIG_SND_SOC_CS4270=y
CONFIG_SND_SOC_CS4271=y
CONFIG_SND_SOC_CS4271_I2C=y
CONFIG_SND_SOC_CS4271_SPI=y
CONFIG_SND_SOC_CS42XX8=y
CONFIG_SND_SOC_CS42XX8_I2C=y
CONFIG_SND_SOC_CS43130=y
CONFIG_SND_SOC_CS4341=y
CONFIG_SND_SOC_CS4349=y
CONFIG_SND_SOC_CS47L15=y
CONFIG_SND_SOC_CS47L24=y
CONFIG_SND_SOC_CS47L35=y
CONFIG_SND_SOC_CS47L85=y
CONFIG_SND_SOC_CS47L90=y
CONFIG_SND_SOC_CS47L92=y
CONFIG_SND_SOC_CS53L30=y
CONFIG_SND_SOC_CX20442=y
CONFIG_SND_SOC_CX2072X=y
CONFIG_SND_SOC_JZ4740_CODEC=y
CONFIG_SND_SOC_JZ4725B_CODEC=y
CONFIG_SND_SOC_JZ4760_CODEC=y
CONFIG_SND_SOC_JZ4770_CODEC=y
CONFIG_SND_SOC_L3=y
CONFIG_SND_SOC_DA7210=y
CONFIG_SND_SOC_DA7213=y
CONFIG_SND_SOC_DA7218=y
CONFIG_SND_SOC_DA7219=y
CONFIG_SND_SOC_DA732X=y
CONFIG_SND_SOC_DA9055=y
CONFIG_SND_SOC_DMIC=y
CONFIG_SND_SOC_HDMI_CODEC=y
CONFIG_SND_SOC_ES7134=y
CONFIG_SND_SOC_ES7241=y
CONFIG_SND_SOC_ES8316=y
CONFIG_SND_SOC_ES8326=y
CONFIG_SND_SOC_ES8328=y
CONFIG_SND_SOC_ES8328_I2C=y
CONFIG_SND_SOC_ES8328_SPI=y
CONFIG_SND_SOC_GTM601=y
CONFIG_SND_SOC_HDAC_HDMI=y
CONFIG_SND_SOC_HDAC_HDA=y
CONFIG_SND_SOC_HDA=y
CONFIG_SND_SOC_ICS43432=y
CONFIG_SND_SOC_INNO_RK3036=y
CONFIG_SND_SOC_ISABELLE=y
CONFIG_SND_SOC_LM49453=y
CONFIG_SND_SOC_LOCHNAGAR_SC=y
CONFIG_SND_SOC_MADERA=y
CONFIG_SND_SOC_MAX98088=y
CONFIG_SND_SOC_MAX98090=y
CONFIG_SND_SOC_MAX98095=y
CONFIG_SND_SOC_MAX98357A=y
CONFIG_SND_SOC_MAX98371=y
CONFIG_SND_SOC_MAX98504=y
CONFIG_SND_SOC_MAX9867=y
CONFIG_SND_SOC_MAX98925=y
CONFIG_SND_SOC_MAX98926=y
CONFIG_SND_SOC_MAX98927=y
CONFIG_SND_SOC_MAX98520=y
CONFIG_SND_SOC_MAX98373=y
CONFIG_SND_SOC_MAX98373_I2C=y
CONFIG_SND_SOC_MAX98373_SDW=y
CONFIG_SND_SOC_MAX98390=y
CONFIG_SND_SOC_MAX98396=y
CONFIG_SND_SOC_MAX9850=y
CONFIG_SND_SOC_MAX9860=y
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=y
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=y
CONFIG_SND_SOC_PCM1681=y
CONFIG_SND_SOC_PCM1789=y
CONFIG_SND_SOC_PCM1789_I2C=y
CONFIG_SND_SOC_PCM179X=y
CONFIG_SND_SOC_PCM179X_I2C=y
CONFIG_SND_SOC_PCM179X_SPI=y
CONFIG_SND_SOC_PCM186X=y
CONFIG_SND_SOC_PCM186X_I2C=y
CONFIG_SND_SOC_PCM186X_SPI=y
CONFIG_SND_SOC_PCM3008=y
CONFIG_SND_SOC_PCM3060=y
CONFIG_SND_SOC_PCM3060_I2C=y
CONFIG_SND_SOC_PCM3060_SPI=y
CONFIG_SND_SOC_PCM3168A=y
CONFIG_SND_SOC_PCM3168A_I2C=y
CONFIG_SND_SOC_PCM3168A_SPI=y
CONFIG_SND_SOC_PCM5102A=y
CONFIG_SND_SOC_PCM512x=y
CONFIG_SND_SOC_PCM512x_I2C=y
CONFIG_SND_SOC_PCM512x_SPI=y
CONFIG_SND_SOC_RK3328=y
CONFIG_SND_SOC_RK817=y
CONFIG_SND_SOC_RL6231=y
CONFIG_SND_SOC_RL6347A=y
CONFIG_SND_SOC_RT274=y
CONFIG_SND_SOC_RT286=y
CONFIG_SND_SOC_RT298=y
CONFIG_SND_SOC_RT1011=y
CONFIG_SND_SOC_RT1015=y
CONFIG_SND_SOC_RT1015P=y
CONFIG_SND_SOC_RT1016=y
CONFIG_SND_SOC_RT1019=y
CONFIG_SND_SOC_RT1305=y
CONFIG_SND_SOC_RT1308=y
CONFIG_SND_SOC_RT1308_SDW=y
CONFIG_SND_SOC_RT1316_SDW=y
CONFIG_SND_SOC_RT1318_SDW=y
CONFIG_SND_SOC_RT5514=y
CONFIG_SND_SOC_RT5514_SPI=y
CONFIG_SND_SOC_RT5616=y
CONFIG_SND_SOC_RT5631=y
CONFIG_SND_SOC_RT5640=y
CONFIG_SND_SOC_RT5645=y
CONFIG_SND_SOC_RT5651=y
CONFIG_SND_SOC_RT5659=y
CONFIG_SND_SOC_RT5660=y
CONFIG_SND_SOC_RT5663=y
CONFIG_SND_SOC_RT5665=y
CONFIG_SND_SOC_RT5668=y
CONFIG_SND_SOC_RT5670=y
CONFIG_SND_SOC_RT5677=y
CONFIG_SND_SOC_RT5677_SPI=y
CONFIG_SND_SOC_RT5682=y
CONFIG_SND_SOC_RT5682_I2C=y
CONFIG_SND_SOC_RT5682_SDW=y
CONFIG_SND_SOC_RT5682S=y
CONFIG_SND_SOC_RT700=y
CONFIG_SND_SOC_RT700_SDW=y
CONFIG_SND_SOC_RT711=y
CONFIG_SND_SOC_RT711_SDW=y
CONFIG_SND_SOC_RT711_SDCA_SDW=y
CONFIG_SND_SOC_RT715=y
CONFIG_SND_SOC_RT715_SDW=y
CONFIG_SND_SOC_RT715_SDCA_SDW=y
CONFIG_SND_SOC_RT9120=y
CONFIG_SND_SOC_SDW_MOCKUP=y
CONFIG_SND_SOC_SGTL5000=y
CONFIG_SND_SOC_SI476X=y
CONFIG_SND_SOC_SIGMADSP=y
CONFIG_SND_SOC_SIGMADSP_I2C=y
CONFIG_SND_SOC_SIGMADSP_REGMAP=y
CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y
CONFIG_SND_SOC_SIMPLE_MUX=y
CONFIG_SND_SOC_SPDIF=y
CONFIG_SND_SOC_SRC4XXX_I2C=y
CONFIG_SND_SOC_SRC4XXX=y
CONFIG_SND_SOC_SSM2305=y
CONFIG_SND_SOC_SSM2518=y
CONFIG_SND_SOC_SSM2602=y
CONFIG_SND_SOC_SSM2602_SPI=y
CONFIG_SND_SOC_SSM2602_I2C=y
CONFIG_SND_SOC_SSM4567=y
CONFIG_SND_SOC_STA32X=y
CONFIG_SND_SOC_STA350=y
CONFIG_SND_SOC_STA529=y
CONFIG_SND_SOC_STAC9766=y
CONFIG_SND_SOC_STI_SAS=y
CONFIG_SND_SOC_TAS2552=y
CONFIG_SND_SOC_TAS2562=y
CONFIG_SND_SOC_TAS2764=y
CONFIG_SND_SOC_TAS2770=y
CONFIG_SND_SOC_TAS2780=y
CONFIG_SND_SOC_TAS5086=y
CONFIG_SND_SOC_TAS571X=y
CONFIG_SND_SOC_TAS5720=y
CONFIG_SND_SOC_TAS5805M=y
CONFIG_SND_SOC_TAS6424=y
CONFIG_SND_SOC_TDA7419=y
CONFIG_SND_SOC_TFA9879=y
CONFIG_SND_SOC_TFA989X=y
CONFIG_SND_SOC_TLV320ADC3XXX=y
CONFIG_SND_SOC_TLV320AIC23=y
CONFIG_SND_SOC_TLV320AIC23_I2C=y
CONFIG_SND_SOC_TLV320AIC23_SPI=y
CONFIG_SND_SOC_TLV320AIC26=y
CONFIG_SND_SOC_TLV320AIC31XX=y
CONFIG_SND_SOC_TLV320AIC32X4=y
CONFIG_SND_SOC_TLV320AIC32X4_I2C=y
CONFIG_SND_SOC_TLV320AIC32X4_SPI=y
CONFIG_SND_SOC_TLV320AIC3X=y
CONFIG_SND_SOC_TLV320AIC3X_I2C=y
CONFIG_SND_SOC_TLV320AIC3X_SPI=y
CONFIG_SND_SOC_TLV320DAC33=y
CONFIG_SND_SOC_TLV320ADCX140=y
CONFIG_SND_SOC_TS3A227E=y
CONFIG_SND_SOC_TSCS42XX=y
CONFIG_SND_SOC_TSCS454=y
CONFIG_SND_SOC_TWL4030=y
CONFIG_SND_SOC_TWL6040=y
CONFIG_SND_SOC_UDA1334=y
CONFIG_SND_SOC_UDA134X=y
CONFIG_SND_SOC_UDA1380=y
CONFIG_SND_SOC_WCD9335=y
CONFIG_SND_SOC_WCD_MBHC=y
CONFIG_SND_SOC_WCD934X=y
CONFIG_SND_SOC_WCD938X=y
CONFIG_SND_SOC_WCD938X_SDW=y
CONFIG_SND_SOC_WL1273=y
CONFIG_SND_SOC_WM0010=y
CONFIG_SND_SOC_WM1250_EV1=y
CONFIG_SND_SOC_WM2000=y
CONFIG_SND_SOC_WM2200=y
CONFIG_SND_SOC_WM5100=y
CONFIG_SND_SOC_WM5102=y
CONFIG_SND_SOC_WM5110=y
CONFIG_SND_SOC_WM8350=y
CONFIG_SND_SOC_WM8400=y
CONFIG_SND_SOC_WM8510=y
CONFIG_SND_SOC_WM8523=y
CONFIG_SND_SOC_WM8524=y
CONFIG_SND_SOC_WM8580=y
CONFIG_SND_SOC_WM8711=y
CONFIG_SND_SOC_WM8727=y
CONFIG_SND_SOC_WM8728=y
CONFIG_SND_SOC_WM8731=y
CONFIG_SND_SOC_WM8731_I2C=y
CONFIG_SND_SOC_WM8731_SPI=y
CONFIG_SND_SOC_WM8737=y
CONFIG_SND_SOC_WM8741=y
CONFIG_SND_SOC_WM8750=y
CONFIG_SND_SOC_WM8753=y
CONFIG_SND_SOC_WM8770=y
CONFIG_SND_SOC_WM8776=y
CONFIG_SND_SOC_WM8782=y
CONFIG_SND_SOC_WM8804=y
CONFIG_SND_SOC_WM8804_I2C=y
CONFIG_SND_SOC_WM8804_SPI=y
CONFIG_SND_SOC_WM8900=y
CONFIG_SND_SOC_WM8903=y
CONFIG_SND_SOC_WM8904=y
CONFIG_SND_SOC_WM8940=y
CONFIG_SND_SOC_WM8955=y
CONFIG_SND_SOC_WM8960=y
CONFIG_SND_SOC_WM8961=y
CONFIG_SND_SOC_WM8962=y
CONFIG_SND_SOC_WM8971=y
CONFIG_SND_SOC_WM8974=y
CONFIG_SND_SOC_WM8978=y
CONFIG_SND_SOC_WM8983=y
CONFIG_SND_SOC_WM8985=y
CONFIG_SND_SOC_WM8988=y
CONFIG_SND_SOC_WM8990=y
CONFIG_SND_SOC_WM8991=y
CONFIG_SND_SOC_WM8993=y
CONFIG_SND_SOC_WM8994=y
CONFIG_SND_SOC_WM8995=y
CONFIG_SND_SOC_WM8996=y
CONFIG_SND_SOC_WM8997=y
CONFIG_SND_SOC_WM8998=y
CONFIG_SND_SOC_WM9081=y
CONFIG_SND_SOC_WM9090=y
CONFIG_SND_SOC_WM9705=y
CONFIG_SND_SOC_WM9712=y
CONFIG_SND_SOC_WM9713=y
CONFIG_SND_SOC_WSA881X=y
CONFIG_SND_SOC_WSA883X=y
CONFIG_SND_SOC_ZL38060=y
CONFIG_SND_SOC_LM4857=y
CONFIG_SND_SOC_MAX9759=y
CONFIG_SND_SOC_MAX9768=y
CONFIG_SND_SOC_MAX9877=y
CONFIG_SND_SOC_MC13783=y
CONFIG_SND_SOC_ML26124=y
CONFIG_SND_SOC_MT6351=y
CONFIG_SND_SOC_MT6358=y
CONFIG_SND_SOC_MT6359=y
CONFIG_SND_SOC_MT6359_ACCDET=y
CONFIG_SND_SOC_MT6660=y
CONFIG_SND_SOC_NAU8315=y
CONFIG_SND_SOC_NAU8540=y
CONFIG_SND_SOC_NAU8810=y
CONFIG_SND_SOC_NAU8821=y
CONFIG_SND_SOC_NAU8822=y
CONFIG_SND_SOC_NAU8824=y
CONFIG_SND_SOC_NAU8825=y
CONFIG_SND_SOC_TPA6130A2=y
CONFIG_SND_SOC_LPASS_MACRO_COMMON=y
CONFIG_SND_SOC_LPASS_WSA_MACRO=y
CONFIG_SND_SOC_LPASS_VA_MACRO=y
CONFIG_SND_SOC_LPASS_RX_MACRO=y
CONFIG_SND_SOC_LPASS_TX_MACRO=y
# end of CODEC drivers
CONFIG_SND_SIMPLE_CARD_UTILS=y
CONFIG_SND_SIMPLE_CARD=y
CONFIG_SND_AUDIO_GRAPH_CARD=y
CONFIG_SND_AUDIO_GRAPH_CARD2=y
CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=y
CONFIG_SND_TEST_COMPONENT=y
CONFIG_SND_SYNTH_EMUX=y
CONFIG_SND_VIRTIO=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
CONFIG_HID_BATTERY_STRENGTH=y
CONFIG_HIDRAW=y
CONFIG_UHID=y
CONFIG_HID_GENERIC=y
#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
CONFIG_HID_ACCUTOUCH=y
CONFIG_HID_ACRUX=y
CONFIG_HID_ACRUX_FF=y
CONFIG_HID_APPLE=y
CONFIG_HID_APPLEIR=y
CONFIG_HID_ASUS=y
CONFIG_HID_AUREAL=y
CONFIG_HID_BELKIN=y
CONFIG_HID_BETOP_FF=y
CONFIG_HID_BIGBEN_FF=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CORSAIR=y
CONFIG_HID_COUGAR=y
CONFIG_HID_MACALLY=y
CONFIG_HID_PRODIKEYS=y
CONFIG_HID_CMEDIA=y
CONFIG_HID_CP2112=y
CONFIG_HID_CREATIVE_SB0540=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_DRAGONRISE=y
CONFIG_DRAGONRISE_FF=y
CONFIG_HID_EMS_FF=y
CONFIG_HID_ELAN=y
CONFIG_HID_ELECOM=y
CONFIG_HID_ELO=y
CONFIG_HID_EZKEY=y
CONFIG_HID_FT260=y
CONFIG_HID_GEMBIRD=y
CONFIG_HID_GFRM=y
CONFIG_HID_GLORIOUS=y
CONFIG_HID_HOLTEK=y
CONFIG_HOLTEK_FF=y
CONFIG_HID_VIVALDI_COMMON=y
CONFIG_HID_GOOGLE_HAMMER=y
CONFIG_HID_VIVALDI=y
CONFIG_HID_GT683R=y
CONFIG_HID_KEYTOUCH=y
CONFIG_HID_KYE=y
CONFIG_HID_UCLOGIC=y
CONFIG_HID_WALTOP=y
CONFIG_HID_VIEWSONIC=y
CONFIG_HID_VRC2=y
CONFIG_HID_XIAOMI=y
CONFIG_HID_GYRATION=y
CONFIG_HID_ICADE=y
CONFIG_HID_ITE=y
CONFIG_HID_JABRA=y
CONFIG_HID_TWINHAN=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LCPOWER=y
CONFIG_HID_LED=y
CONFIG_HID_LENOVO=y
CONFIG_HID_LETSKETCH=y
CONFIG_HID_LOGITECH=y
CONFIG_HID_LOGITECH_DJ=y
CONFIG_HID_LOGITECH_HIDPP=y
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
CONFIG_LOGIG940_FF=y
CONFIG_LOGIWHEELS_FF=y
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MALTRON=y
CONFIG_HID_MAYFLASH=y
CONFIG_HID_MEGAWORLD_FF=y
CONFIG_HID_REDRAGON=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_NINTENDO_FF=y
CONFIG_HID_NTI=y
CONFIG_HID_NTRIG=y
CONFIG_HID_ORTEK=y
CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PENMOUNT=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_PICOLCD=y
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PICOLCD_CIR=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_PLAYSTATION=y
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_PXRC=y
CONFIG_HID_RAZER=y
CONFIG_HID_PRIMAX=y
CONFIG_HID_RETRODE=y
CONFIG_HID_ROCCAT=y
CONFIG_HID_SAITEK=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SEMITEK=y
CONFIG_HID_SIGMAMICRO=y
CONFIG_HID_SONY=y
CONFIG_SONY_FF=y
CONFIG_HID_SPEEDLINK=y
CONFIG_HID_STEAM=y
CONFIG_HID_STEELSERIES=y
CONFIG_HID_SUNPLUS=y
CONFIG_HID_RMI=y
CONFIG_HID_GREENASIA=y
CONFIG_GREENASIA_FF=y
CONFIG_HID_SMARTJOYPLUS=y
CONFIG_SMARTJOYPLUS_FF=y
CONFIG_HID_TIVO=y
CONFIG_HID_TOPSEED=y
CONFIG_HID_TOPRE=y
CONFIG_HID_THINGM=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_THRUSTMASTER_FF=y
CONFIG_HID_UDRAW_PS3=y
CONFIG_HID_U2FZERO=y
CONFIG_HID_WACOM=y
CONFIG_HID_WIIMOTE=y
CONFIG_HID_XINMO=y
CONFIG_HID_ZEROPLUS=y
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=y
CONFIG_HID_SENSOR_HUB=y
CONFIG_HID_SENSOR_CUSTOM_SENSOR=y
CONFIG_HID_ALPS=y
CONFIG_HID_MCP2221=y
CONFIG_HID_KUNIT_TEST=y
# end of Special HID drivers
#
# HID-BPF support
#
# end of HID-BPF support
#
# USB HID support
#
CONFIG_USB_HID=y
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y
# end of USB HID support
#
# I2C HID support
#
CONFIG_I2C_HID_OF=y
CONFIG_I2C_HID_OF_ELAN=y
CONFIG_I2C_HID_OF_GOODIX=y
# end of I2C HID support
CONFIG_I2C_HID_CORE=y
#
# Intel ISH HID support
#
# end of Intel ISH HID support
#
# AMD SFH HID Support
#
CONFIG_AMD_SFH_HID=y
# end of AMD SFH HID Support
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_LED_TRIG=y
CONFIG_USB_ULPI_BUS=y
CONFIG_USB_CONN_GPIO=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_PCI=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_FEW_INIT_RETRIES=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
CONFIG_USB_OTG_PRODUCTLIST=y
CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB=y
CONFIG_USB_OTG_FSM=y
CONFIG_USB_LEDS_TRIGGER_USBPORT=y
CONFIG_USB_AUTOSUSPEND_DELAY=2
CONFIG_USB_MON=y
#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DBGCAP=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_XHCI_PCI_RENESAS=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_XHCI_HISTB=y
CONFIG_USB_XHCI_MTK=y
CONFIG_USB_XHCI_MVEBU=y
CONFIG_USB_XHCI_RCAR=y
CONFIG_USB_XHCI_TEGRA=y
CONFIG_USB_EHCI_BRCMSTB=y
CONFIG_USB_BRCMSTB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_PCI=y
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_EHCI_HCD_NPCM7XX=y
CONFIG_USB_EHCI_HCD_OMAP=y
CONFIG_USB_EHCI_HCD_ORION=y
CONFIG_USB_EHCI_HCD_SPEAR=y
CONFIG_USB_EHCI_HCD_STI=y
CONFIG_USB_EHCI_HCD_AT91=y
CONFIG_USB_EHCI_TEGRA=y
CONFIG_USB_EHCI_SH=y
CONFIG_USB_EHCI_EXYNOS=y
CONFIG_USB_EHCI_MV=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OXU210HP_HCD=y
CONFIG_USB_ISP116X_HCD=y
CONFIG_USB_ISP1362_HCD=y
CONFIG_USB_MAX3421_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_SPEAR=y
CONFIG_USB_OHCI_HCD_STI=y
CONFIG_USB_OHCI_HCD_S3C2410=y
CONFIG_USB_OHCI_HCD_LPC32XX=y
CONFIG_USB_OHCI_HCD_AT91=y
CONFIG_USB_OHCI_HCD_OMAP3=y
CONFIG_USB_OHCI_HCD_DAVINCI=y
CONFIG_USB_OHCI_HCD_PCI=y
CONFIG_USB_OHCI_HCD_SSB=y
CONFIG_USB_OHCI_SH=y
CONFIG_USB_OHCI_EXYNOS=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC=y
CONFIG_USB_UHCI_PLATFORM=y
CONFIG_USB_UHCI_ASPEED=y
CONFIG_USB_U132_HCD=y
CONFIG_USB_SL811_HCD=y
CONFIG_USB_SL811_HCD_ISO=y
CONFIG_USB_SL811_CS=y
CONFIG_USB_R8A66597_HCD=y
CONFIG_USB_RENESAS_USBHS_HCD=y
CONFIG_USB_HCD_BCMA=y
CONFIG_USB_HCD_SSB=y
CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_RENESAS_USBHS=y
#
# USB Device Class drivers
#
CONFIG_USB_ACM=y
CONFIG_USB_PRINTER=y
CONFIG_USB_WDM=y
CONFIG_USB_TMC=y
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_REALTEK=y
CONFIG_REALTEK_AUTOPM=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_STORAGE_ALAUDA=y
CONFIG_USB_STORAGE_ONETOUCH=y
CONFIG_USB_STORAGE_KARMA=y
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_STORAGE_ENE_UB6250=y
CONFIG_USB_UAS=y
#
# USB Imaging devices
#
CONFIG_USB_MDC800=y
CONFIG_USB_MICROTEK=y
CONFIG_USBIP_CORE=y
CONFIG_USBIP_VHCI_HCD=y
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=1
CONFIG_USBIP_HOST=y
CONFIG_USBIP_VUDC=y
CONFIG_USBIP_DEBUG=y
#
# USB dual-mode controller drivers
#
CONFIG_USB_CDNS_SUPPORT=y
CONFIG_USB_CDNS_HOST=y
CONFIG_USB_CDNS3=y
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_CDNS3_TI=y
CONFIG_USB_CDNS3_IMX=y
CONFIG_USB_FOTG210=y
CONFIG_USB_FOTG210_HCD=y
CONFIG_USB_FOTG210_UDC=y
CONFIG_USB_MTU3=y
# CONFIG_USB_MTU3_HOST is not set
# CONFIG_USB_MTU3_GADGET is not set
CONFIG_USB_MTU3_DUAL_ROLE=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_USB_MUSB_HDRC=y
# CONFIG_USB_MUSB_HOST is not set
# CONFIG_USB_MUSB_GADGET is not set
CONFIG_USB_MUSB_DUAL_ROLE=y
#
# Platform Glue Layer
#
CONFIG_USB_MUSB_SUNXI=y
CONFIG_USB_MUSB_TUSB6010=y
CONFIG_USB_MUSB_OMAP2PLUS=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_MUSB_UX500=y
CONFIG_USB_MUSB_MEDIATEK=y
CONFIG_USB_MUSB_POLARFIRE_SOC=y
#
# MUSB DMA mode
#
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_ULPI=y
# CONFIG_USB_DWC3_HOST is not set
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_DUAL_ROLE=y
#
# Platform Glue Driver Support
#
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_EXYNOS=y
CONFIG_USB_DWC3_HAPS=y
CONFIG_USB_DWC3_KEYSTONE=y
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_DWC3_OF_SIMPLE=y
CONFIG_USB_DWC3_ST=y
CONFIG_USB_DWC3_QCOM=y
CONFIG_USB_DWC3_IMX8MP=y
CONFIG_USB_DWC3_XILINX=y
CONFIG_USB_DWC3_AM62=y
CONFIG_USB_DWC2=y
# CONFIG_USB_DWC2_HOST is not set
#
# Gadget/Dual-role mode requires USB Gadget support to be enabled
#
# CONFIG_USB_DWC2_PERIPHERAL is not set
CONFIG_USB_DWC2_DUAL_ROLE=y
CONFIG_USB_DWC2_PCI=y
CONFIG_USB_DWC2_DEBUG=y
CONFIG_USB_DWC2_VERBOSE=y
CONFIG_USB_DWC2_TRACK_MISSED_SOFS=y
CONFIG_USB_DWC2_DEBUG_PERIODIC=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_CHIPIDEA_PCI=y
CONFIG_USB_CHIPIDEA_MSM=y
CONFIG_USB_CHIPIDEA_IMX=y
CONFIG_USB_CHIPIDEA_GENERIC=y
CONFIG_USB_CHIPIDEA_TEGRA=y
CONFIG_USB_ISP1760=y
CONFIG_USB_ISP1760_HCD=y
CONFIG_USB_ISP1761_UDC=y
# CONFIG_USB_ISP1760_HOST_ROLE is not set
# CONFIG_USB_ISP1760_GADGET_ROLE is not set
CONFIG_USB_ISP1760_DUAL_ROLE=y
#
# USB port drivers
#
CONFIG_USB_USS720=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=y
CONFIG_USB_SERIAL_AIRCABLE=y
CONFIG_USB_SERIAL_ARK3116=y
CONFIG_USB_SERIAL_BELKIN=y
CONFIG_USB_SERIAL_CH341=y
CONFIG_USB_SERIAL_WHITEHEAT=y
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=y
CONFIG_USB_SERIAL_CP210X=y
CONFIG_USB_SERIAL_CYPRESS_M8=y
CONFIG_USB_SERIAL_EMPEG=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_SERIAL_VISOR=y
CONFIG_USB_SERIAL_IPAQ=y
CONFIG_USB_SERIAL_IR=y
CONFIG_USB_SERIAL_EDGEPORT=y
CONFIG_USB_SERIAL_EDGEPORT_TI=y
CONFIG_USB_SERIAL_F81232=y
CONFIG_USB_SERIAL_F8153X=y
CONFIG_USB_SERIAL_GARMIN=y
CONFIG_USB_SERIAL_IPW=y
CONFIG_USB_SERIAL_IUU=y
CONFIG_USB_SERIAL_KEYSPAN_PDA=y
CONFIG_USB_SERIAL_KEYSPAN=y
CONFIG_USB_SERIAL_KLSI=y
CONFIG_USB_SERIAL_KOBIL_SCT=y
CONFIG_USB_SERIAL_MCT_U232=y
CONFIG_USB_SERIAL_METRO=y
CONFIG_USB_SERIAL_MOS7720=y
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
CONFIG_USB_SERIAL_MOS7840=y
CONFIG_USB_SERIAL_MXUPORT=y
CONFIG_USB_SERIAL_NAVMAN=y
CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_SERIAL_OTI6858=y
CONFIG_USB_SERIAL_QCAUX=y
CONFIG_USB_SERIAL_QUALCOMM=y
CONFIG_USB_SERIAL_SPCP8X5=y
CONFIG_USB_SERIAL_SAFE=y
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_SIERRAWIRELESS=y
CONFIG_USB_SERIAL_SYMBOL=y
CONFIG_USB_SERIAL_TI=y
CONFIG_USB_SERIAL_CYBERJACK=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_SERIAL_OMNINET=y
CONFIG_USB_SERIAL_OPTICON=y
CONFIG_USB_SERIAL_XSENS_MT=y
CONFIG_USB_SERIAL_WISHBONE=y
CONFIG_USB_SERIAL_SSU100=y
CONFIG_USB_SERIAL_QT2=y
CONFIG_USB_SERIAL_UPD78F0730=y
CONFIG_USB_SERIAL_XR=y
CONFIG_USB_SERIAL_DEBUG=y
#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=y
CONFIG_USB_EMI26=y
CONFIG_USB_ADUTUX=y
CONFIG_USB_SEVSEG=y
CONFIG_USB_LEGOTOWER=y
CONFIG_USB_LCD=y
CONFIG_USB_CYPRESS_CY7C63=y
CONFIG_USB_CYTHERM=y
CONFIG_USB_IDMOUSE=y
CONFIG_USB_FTDI_ELAN=y
CONFIG_USB_APPLEDISPLAY=y
CONFIG_USB_QCOM_EUD=y
CONFIG_APPLE_MFI_FASTCHARGE=y
CONFIG_USB_SISUSBVGA=y
CONFIG_USB_LD=y
CONFIG_USB_TRANCEVIBRATOR=y
CONFIG_USB_IOWARRIOR=y
CONFIG_USB_TEST=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_ISIGHTFW=y
CONFIG_USB_YUREX=y
CONFIG_USB_EZUSB_FX2=y
CONFIG_USB_HUB_USB251XB=y
CONFIG_USB_HSIC_USB3503=y
CONFIG_USB_HSIC_USB4604=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_USB_CHAOSKEY=y
CONFIG_BRCM_USB_PINMAP=y
CONFIG_USB_ONBOARD_HUB=y
CONFIG_USB_ATM=y
CONFIG_USB_SPEEDTOUCH=y
CONFIG_USB_CXACRU=y
CONFIG_USB_UEAGLEATM=y
CONFIG_USB_XUSBATM=y
#
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
CONFIG_AB8500_USB=y
CONFIG_KEYSTONE_USB_PHY=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_AM335X_CONTROL_USB=y
CONFIG_AM335X_PHY_USB=y
CONFIG_TWL6030_USB=y
CONFIG_TAHVO_USB=y
CONFIG_TAHVO_USB_HOST_BY_DEFAULT=y
CONFIG_USB_ISP1301=y
CONFIG_USB_MV_OTG=y
CONFIG_USB_MXS_PHY=y
CONFIG_USB_TEGRA_PHY=y
CONFIG_USB_ULPI=y
CONFIG_USB_ULPI_VIEWPORT=y
# end of USB Physical Layer drivers
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_VERBOSE=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_U_SERIAL_CONSOLE=y
#
# USB Peripheral Controller
#
CONFIG_USB_AT91=y
CONFIG_USB_LPC32XX=y
CONFIG_USB_ATMEL_USBA=y
CONFIG_USB_FUSB300=y
CONFIG_USB_GR_UDC=y
CONFIG_USB_R8A66597=y
CONFIG_USB_RENESAS_USBHS_UDC=y
CONFIG_USB_RENESAS_USB3=y
CONFIG_USB_PXA27X=y
CONFIG_USB_MV_UDC=y
CONFIG_USB_MV_U3D=y
CONFIG_USB_SNP_CORE=y
CONFIG_USB_SNP_UDC_PLAT=y
CONFIG_USB_M66592=y
CONFIG_USB_BDC_UDC=y
CONFIG_USB_AMD5536UDC=y
CONFIG_USB_NET2272=y
CONFIG_USB_NET2272_DMA=y
CONFIG_USB_NET2280=y
CONFIG_USB_GOKU=y
CONFIG_USB_EG20T=y
CONFIG_USB_GADGET_XILINX=y
CONFIG_USB_MAX3420_UDC=y
CONFIG_USB_TEGRA_XUDC=y
CONFIG_USB_ASPEED_UDC=y
CONFIG_USB_ASPEED_VHUB=y
CONFIG_USB_DUMMY_HCD=y
# end of USB Peripheral Controller
CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_F_ACM=y
CONFIG_USB_F_SS_LB=y
CONFIG_USB_U_SERIAL=y
CONFIG_USB_U_ETHER=y
CONFIG_USB_U_AUDIO=y
CONFIG_USB_F_SERIAL=y
CONFIG_USB_F_OBEX=y
CONFIG_USB_F_NCM=y
CONFIG_USB_F_ECM=y
CONFIG_USB_F_PHONET=y
CONFIG_USB_F_EEM=y
CONFIG_USB_F_SUBSET=y
CONFIG_USB_F_RNDIS=y
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_F_FS=y
CONFIG_USB_F_UAC1=y
CONFIG_USB_F_UAC1_LEGACY=y
CONFIG_USB_F_UAC2=y
CONFIG_USB_F_UVC=y
CONFIG_USB_F_MIDI=y
CONFIG_USB_F_HID=y
CONFIG_USB_F_PRINTER=y
CONFIG_USB_F_TCM=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_PHONET=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_CONFIGFS_F_TCM=y
#
# USB Gadget precomposed configurations
#
CONFIG_USB_ZERO=y
CONFIG_USB_ZERO_HNPTEST=y
CONFIG_USB_AUDIO=y
CONFIG_GADGET_UAC1=y
CONFIG_GADGET_UAC1_LEGACY=y
CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_ETH_EEM=y
CONFIG_USB_G_NCM=y
CONFIG_USB_GADGETFS=y
CONFIG_USB_FUNCTIONFS=y
CONFIG_USB_FUNCTIONFS_ETH=y
CONFIG_USB_FUNCTIONFS_RNDIS=y
CONFIG_USB_FUNCTIONFS_GENERIC=y
CONFIG_USB_MASS_STORAGE=y
CONFIG_USB_GADGET_TARGET=y
CONFIG_USB_G_SERIAL=y
CONFIG_USB_MIDI_GADGET=y
CONFIG_USB_G_PRINTER=y
CONFIG_USB_CDC_COMPOSITE=y
CONFIG_USB_G_NOKIA=y
CONFIG_USB_G_ACM_MS=y
CONFIG_USB_G_MULTI=y
CONFIG_USB_G_MULTI_RNDIS=y
CONFIG_USB_G_MULTI_CDC=y
CONFIG_USB_G_HID=y
CONFIG_USB_G_DBGP=y
# CONFIG_USB_G_DBGP_PRINTK is not set
CONFIG_USB_G_DBGP_SERIAL=y
CONFIG_USB_G_WEBCAM=y
CONFIG_USB_RAW_GADGET=y
# end of USB Gadget precomposed configurations
CONFIG_TYPEC=y
CONFIG_TYPEC_TCPM=y
CONFIG_TYPEC_TCPCI=y
CONFIG_TYPEC_RT1711H=y
CONFIG_TYPEC_MT6360=y
CONFIG_TYPEC_TCPCI_MT6370=y
CONFIG_TYPEC_TCPCI_MAXIM=y
CONFIG_TYPEC_FUSB302=y
CONFIG_TYPEC_UCSI=y
CONFIG_UCSI_CCG=y
CONFIG_UCSI_STM32G0=y
CONFIG_TYPEC_TPS6598X=y
CONFIG_TYPEC_ANX7411=y
CONFIG_TYPEC_RT1719=y
CONFIG_TYPEC_HD3SS3220=y
CONFIG_TYPEC_STUSB160X=y
CONFIG_TYPEC_QCOM_PMIC=y
CONFIG_TYPEC_WUSB3801=y
#
# USB Type-C Multiplexer/DeMultiplexer Switch support
#
CONFIG_TYPEC_MUX_FSA4480=y
CONFIG_TYPEC_MUX_PI3USB30532=y
# end of USB Type-C Multiplexer/DeMultiplexer Switch support
#
# USB Type-C Alternate Mode drivers
#
CONFIG_TYPEC_DP_ALTMODE=y
CONFIG_TYPEC_NVIDIA_ALTMODE=y
# end of USB Type-C Alternate Mode drivers
CONFIG_USB_ROLE_SWITCH=y
CONFIG_MMC=y
CONFIG_PWRSEQ_EMMC=y
CONFIG_PWRSEQ_SD8787=y
CONFIG_PWRSEQ_SIMPLE=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_SDIO_UART=y
CONFIG_MMC_TEST=y
CONFIG_MMC_CRYPTO=y
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_DEBUG=y
CONFIG_MMC_SUNPLUS=y
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_QCOM_DML=y
CONFIG_MMC_STM32_SDMMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PCI=y
CONFIG_MMC_RICOH_MMC=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_ARASAN=y
CONFIG_MMC_SDHCI_OF_ASPEED=y
CONFIG_MMC_SDHCI_OF_ASPEED_TEST=y
CONFIG_MMC_SDHCI_OF_AT91=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_OF_DWCMSHC=y
CONFIG_MMC_SDHCI_OF_SPARX5=y
CONFIG_MMC_SDHCI_CADENCE=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_DOVE=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_S3C=y
CONFIG_MMC_SDHCI_PXAV3=y
CONFIG_MMC_SDHCI_PXAV2=y
CONFIG_MMC_SDHCI_SPEAR=y
CONFIG_MMC_SDHCI_S3C_DMA=y
CONFIG_MMC_SDHCI_BCM_KONA=y
CONFIG_MMC_SDHCI_F_SDH30=y
CONFIG_MMC_SDHCI_MILBEAUT=y
CONFIG_MMC_SDHCI_IPROC=y
CONFIG_MMC_MESON_GX=y
CONFIG_MMC_MESON_MX_SDHC=y
CONFIG_MMC_MESON_MX_SDIO=y
CONFIG_MMC_MOXART=y
CONFIG_MMC_SDHCI_ST=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
CONFIG_MMC_ALCOR=y
CONFIG_MMC_ATMELMCI=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MXC=y
CONFIG_MMC_TIFM_SD=y
CONFIG_MMC_MVSDIO=y
CONFIG_MMC_DAVINCI=y
CONFIG_MMC_SPI=y
CONFIG_MMC_SDRICOH_CS=y
CONFIG_MMC_SDHCI_SPRD=y
CONFIG_MMC_TMIO_CORE=y
CONFIG_MMC_SDHI=y
CONFIG_MMC_SDHI_SYS_DMAC=y
CONFIG_MMC_SDHI_INTERNAL_DMAC=y
CONFIG_MMC_UNIPHIER=y
CONFIG_MMC_CB710=y
CONFIG_MMC_VIA_SDMMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_PLTFM=y
CONFIG_MMC_DW_BLUEFIELD=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_HI3798CV200=y
CONFIG_MMC_DW_K3=y
CONFIG_MMC_DW_PCI=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SH_MMCIF=y
CONFIG_MMC_VUB300=y
CONFIG_MMC_USHC=y
CONFIG_MMC_WMT=y
CONFIG_MMC_USDHI6ROL0=y
CONFIG_MMC_REALTEK_PCI=y
CONFIG_MMC_REALTEK_USB=y
CONFIG_MMC_SUNXI=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_HSQ=y
CONFIG_MMC_TOSHIBA_PCI=y
CONFIG_MMC_BCM2835=y
CONFIG_MMC_MTK=y
CONFIG_MMC_SDHCI_BRCMSTB=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_MMC_SDHCI_OMAP=y
CONFIG_MMC_SDHCI_AM654=y
CONFIG_MMC_OWL=y
CONFIG_MMC_SDHCI_EXTERNAL_DMA=y
CONFIG_MMC_LITEX=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFS_BSG=y
CONFIG_SCSI_UFS_CRYPTO=y
CONFIG_SCSI_UFS_HPB=y
CONFIG_SCSI_UFS_FAULT_INJECTION=y
CONFIG_SCSI_UFS_HWMON=y
CONFIG_SCSI_UFSHCD_PCI=y
CONFIG_SCSI_UFS_DWC_TC_PCI=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_CDNS_PLATFORM=y
CONFIG_SCSI_UFS_DWC_TC_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
CONFIG_SCSI_UFS_MEDIATEK=y
CONFIG_SCSI_UFS_HISI=y
CONFIG_SCSI_UFS_RENESAS=y
CONFIG_SCSI_UFS_TI_J721E=y
CONFIG_SCSI_UFS_EXYNOS=y
CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE=y
CONFIG_MEMSTICK=y
CONFIG_MEMSTICK_DEBUG=y
#
# MemoryStick drivers
#
CONFIG_MEMSTICK_UNSAFE_RESUME=y
CONFIG_MSPRO_BLOCK=y
CONFIG_MS_BLOCK=y
#
# MemoryStick Host Controller Drivers
#
CONFIG_MEMSTICK_TIFM_MS=y
CONFIG_MEMSTICK_JMICRON_38X=y
CONFIG_MEMSTICK_R592=y
CONFIG_MEMSTICK_REALTEK_PCI=y
CONFIG_MEMSTICK_REALTEK_USB=y
CONFIG_LEDS_GPIO_REGISTER=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_CLASS_FLASH=y
CONFIG_LEDS_CLASS_MULTICOLOR=y
CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
#
# LED drivers
#
CONFIG_LEDS_88PM860X=y
CONFIG_LEDS_AN30259A=y
CONFIG_LEDS_ARIEL=y
CONFIG_LEDS_AW2013=y
CONFIG_LEDS_BCM6328=y
CONFIG_LEDS_BCM6358=y
CONFIG_LEDS_CPCAP=y
CONFIG_LEDS_CR0014114=y
CONFIG_LEDS_EL15203000=y
CONFIG_LEDS_TURRIS_OMNIA=y
CONFIG_LEDS_LM3530=y
CONFIG_LEDS_LM3532=y
CONFIG_LEDS_LM3533=y
CONFIG_LEDS_LM3642=y
CONFIG_LEDS_LM3692X=y
CONFIG_LEDS_MT6323=y
CONFIG_LEDS_COBALT_QUBE=y
CONFIG_LEDS_COBALT_RAQ=y
CONFIG_LEDS_PCA9532=y
CONFIG_LEDS_PCA9532_GPIO=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_LP3944=y
CONFIG_LEDS_LP3952=y
CONFIG_LEDS_LP50XX=y
CONFIG_LEDS_LP55XX_COMMON=y
CONFIG_LEDS_LP5521=y
CONFIG_LEDS_LP5523=y
CONFIG_LEDS_LP5562=y
CONFIG_LEDS_LP8501=y
CONFIG_LEDS_LP8788=y
CONFIG_LEDS_LP8860=y
CONFIG_LEDS_PCA955X=y
CONFIG_LEDS_PCA955X_GPIO=y
CONFIG_LEDS_PCA963X=y
CONFIG_LEDS_WM831X_STATUS=y
CONFIG_LEDS_WM8350=y
CONFIG_LEDS_DA903X=y
CONFIG_LEDS_DA9052=y
CONFIG_LEDS_DAC124S085=y
CONFIG_LEDS_PWM=y
CONFIG_LEDS_REGULATOR=y
CONFIG_LEDS_BD2802=y
CONFIG_LEDS_LT3593=y
CONFIG_LEDS_ADP5520=y
CONFIG_LEDS_MC13783=y
CONFIG_LEDS_NS2=y
CONFIG_LEDS_NETXBIG=y
CONFIG_LEDS_TCA6507=y
CONFIG_LEDS_TLC591XX=y
CONFIG_LEDS_MAX77650=y
CONFIG_LEDS_MAX8997=y
CONFIG_LEDS_LM355x=y
CONFIG_LEDS_OT200=y
CONFIG_LEDS_MENF21BMC=y
CONFIG_LEDS_IS31FL319X=y
CONFIG_LEDS_IS31FL32XX=y
CONFIG_LEDS_SC27XX_BLTC=y
#
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
#
CONFIG_LEDS_BLINKM=y
CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_PM8058=y
CONFIG_LEDS_MLXREG=y
CONFIG_LEDS_USER=y
CONFIG_LEDS_SPI_BYTE=y
CONFIG_LEDS_TI_LMU_COMMON=y
CONFIG_LEDS_LM3697=y
CONFIG_LEDS_LM36274=y
CONFIG_LEDS_TPS6105X=y
CONFIG_LEDS_IP30=y
CONFIG_LEDS_ACER_A500=y
CONFIG_LEDS_BCM63138=y
CONFIG_LEDS_LGM=y
#
# Flash and Torch LED drivers
#
CONFIG_LEDS_AAT1290=y
CONFIG_LEDS_AS3645A=y
CONFIG_LEDS_KTD2692=y
CONFIG_LEDS_LM3601X=y
CONFIG_LEDS_MAX77693=y
CONFIG_LEDS_MT6360=y
CONFIG_LEDS_RT4505=y
CONFIG_LEDS_RT8515=y
CONFIG_LEDS_SGM3140=y
#
# RGB LED drivers
#
CONFIG_LEDS_PWM_MULTICOLOR=y
CONFIG_LEDS_QCOM_LPG=y
#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_DISK=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y
CONFIG_LEDS_TRIGGER_PATTERN=y
CONFIG_LEDS_TRIGGER_AUDIO=y
CONFIG_LEDS_TRIGGER_TTY=y
#
# Simple LED drivers
#
CONFIG_ACCESSIBILITY=y
CONFIG_A11Y_BRAILLE_CONSOLE=y
#
# Speakup console speech
#
CONFIG_SPEAKUP=y
CONFIG_SPEAKUP_SERIALIO=y
CONFIG_SPEAKUP_SYNTH_ACNTSA=y
CONFIG_SPEAKUP_SYNTH_ACNTPC=y
CONFIG_SPEAKUP_SYNTH_APOLLO=y
CONFIG_SPEAKUP_SYNTH_AUDPTR=y
CONFIG_SPEAKUP_SYNTH_BNS=y
CONFIG_SPEAKUP_SYNTH_DECTLK=y
CONFIG_SPEAKUP_SYNTH_DECEXT=y
CONFIG_SPEAKUP_SYNTH_DECPC=m
CONFIG_SPEAKUP_SYNTH_DTLK=y
CONFIG_SPEAKUP_SYNTH_KEYPC=y
CONFIG_SPEAKUP_SYNTH_LTLK=y
CONFIG_SPEAKUP_SYNTH_SOFT=y
CONFIG_SPEAKUP_SYNTH_SPKOUT=y
CONFIG_SPEAKUP_SYNTH_TXPRT=y
CONFIG_SPEAKUP_SYNTH_DUMMY=y
# end of Speakup console speech
CONFIG_INFINIBAND=y
CONFIG_INFINIBAND_USER_MAD=y
CONFIG_INFINIBAND_USER_ACCESS=y
CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ON_DEMAND_PAGING=y
CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y
CONFIG_INFINIBAND_CXGB4=y
CONFIG_INFINIBAND_IRDMA=y
CONFIG_MLX4_INFINIBAND=y
CONFIG_MLX5_INFINIBAND=y
CONFIG_INFINIBAND_MTHCA=y
CONFIG_INFINIBAND_MTHCA_DEBUG=y
CONFIG_INFINIBAND_OCRDMA=y
CONFIG_INFINIBAND_VMWARE_PVRDMA=y
CONFIG_INFINIBAND_IPOIB=y
CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_IPOIB_DEBUG=y
CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
CONFIG_INFINIBAND_SRP=y
CONFIG_INFINIBAND_SRPT=y
CONFIG_INFINIBAND_ISER=y
CONFIG_INFINIBAND_ISERT=y
CONFIG_INFINIBAND_RTRS=y
CONFIG_INFINIBAND_RTRS_CLIENT=y
CONFIG_INFINIBAND_RTRS_SERVER=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EDAC=y
CONFIG_EDAC_LEGACY_SYSFS=y
CONFIG_EDAC_DEBUG=y
CONFIG_EDAC_AL_MC=y
CONFIG_EDAC_LAYERSCAPE=y
CONFIG_EDAC_HIGHBANK_MC=y
CONFIG_EDAC_HIGHBANK_L2=y
CONFIG_EDAC_ALTERA=y
CONFIG_EDAC_ALTERA_SDRAM=y
CONFIG_EDAC_ALTERA_L2C=y
CONFIG_EDAC_ALTERA_OCRAM=y
CONFIG_EDAC_ALTERA_ETHERNET=y
CONFIG_EDAC_ALTERA_NAND=y
CONFIG_EDAC_ALTERA_DMA=y
CONFIG_EDAC_ALTERA_USB=y
CONFIG_EDAC_ALTERA_QSPI=y
CONFIG_EDAC_ALTERA_SDMMC=y
CONFIG_EDAC_ARMADA_XP=y
CONFIG_EDAC_SYNOPSYS=y
CONFIG_EDAC_XGENE=y
CONFIG_EDAC_TI=y
CONFIG_EDAC_QCOM=y
CONFIG_EDAC_ASPEED=y
CONFIG_EDAC_ZYNQMP=y
CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
CONFIG_RTC_DEBUG=y
CONFIG_RTC_LIB_KUNIT_TEST=y
CONFIG_RTC_NVMEM=y
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=y
#
# I2C RTC drivers
#
CONFIG_RTC_DRV_88PM860X=y
CONFIG_RTC_DRV_88PM80X=y
CONFIG_RTC_DRV_ABB5ZES3=y
CONFIG_RTC_DRV_ABEOZ9=y
CONFIG_RTC_DRV_ABX80X=y
CONFIG_RTC_DRV_AC100=y
CONFIG_RTC_DRV_BRCMSTB=y
CONFIG_RTC_DRV_AS3722=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_DS1307_CENTURY=y
CONFIG_RTC_DRV_DS1374=y
CONFIG_RTC_DRV_DS1374_WDT=y
CONFIG_RTC_DRV_DS1672=y
CONFIG_RTC_DRV_HYM8563=y
CONFIG_RTC_DRV_LP8788=y
CONFIG_RTC_DRV_MAX6900=y
CONFIG_RTC_DRV_MAX8907=y
CONFIG_RTC_DRV_MAX8925=y
CONFIG_RTC_DRV_MAX8998=y
CONFIG_RTC_DRV_MAX8997=y
CONFIG_RTC_DRV_MAX77686=y
CONFIG_RTC_DRV_NCT3018Y=y
CONFIG_RTC_DRV_RK808=y
CONFIG_RTC_DRV_RS5C372=y
CONFIG_RTC_DRV_ISL1208=y
CONFIG_RTC_DRV_ISL12022=y
CONFIG_RTC_DRV_ISL12026=y
CONFIG_RTC_DRV_X1205=y
CONFIG_RTC_DRV_PCF8523=y
CONFIG_RTC_DRV_PCF85063=y
CONFIG_RTC_DRV_PCF85363=y
CONFIG_RTC_DRV_PCF8563=y
CONFIG_RTC_DRV_PCF8583=y
CONFIG_RTC_DRV_M41T80=y
CONFIG_RTC_DRV_M41T80_WDT=y
CONFIG_RTC_DRV_BD70528=y
CONFIG_RTC_DRV_BQ32K=y
CONFIG_RTC_DRV_TWL92330=y
CONFIG_RTC_DRV_TWL4030=y
CONFIG_RTC_DRV_PALMAS=y
CONFIG_RTC_DRV_TPS6586X=y
CONFIG_RTC_DRV_TPS65910=y
CONFIG_RTC_DRV_RC5T583=y
CONFIG_RTC_DRV_RC5T619=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_FM3130=y
CONFIG_RTC_DRV_RX8010=y
CONFIG_RTC_DRV_RX8581=y
CONFIG_RTC_DRV_RX8025=y
CONFIG_RTC_DRV_EM3027=y
CONFIG_RTC_DRV_RV3028=y
CONFIG_RTC_DRV_RV3032=y
CONFIG_RTC_DRV_RV8803=y
CONFIG_RTC_DRV_S5M=y
CONFIG_RTC_DRV_SD3078=y
#
# SPI RTC drivers
#
CONFIG_RTC_DRV_M41T93=y
CONFIG_RTC_DRV_M41T94=y
CONFIG_RTC_DRV_DS1302=y
CONFIG_RTC_DRV_DS1305=y
CONFIG_RTC_DRV_DS1343=y
CONFIG_RTC_DRV_DS1347=y
CONFIG_RTC_DRV_DS1390=y
CONFIG_RTC_DRV_MAX6916=y
CONFIG_RTC_DRV_R9701=y
CONFIG_RTC_DRV_RX4581=y
CONFIG_RTC_DRV_RS5C348=y
CONFIG_RTC_DRV_MAX6902=y
CONFIG_RTC_DRV_PCF2123=y
CONFIG_RTC_DRV_MCP795=y
CONFIG_RTC_I2C_AND_SPI=y
#
# SPI and I2C RTC drivers
#
CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_DS3232_HWMON=y
CONFIG_RTC_DRV_PCF2127=y
CONFIG_RTC_DRV_RV3029C2=y
CONFIG_RTC_DRV_RV3029_HWMON=y
CONFIG_RTC_DRV_RX6110=y
#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1286=y
CONFIG_RTC_DRV_DS1511=y
CONFIG_RTC_DRV_DS1553=y
CONFIG_RTC_DRV_DS1685_FAMILY=y
CONFIG_RTC_DRV_DS1685=y
# CONFIG_RTC_DRV_DS1689 is not set
# CONFIG_RTC_DRV_DS17285 is not set
# CONFIG_RTC_DRV_DS17485 is not set
# CONFIG_RTC_DRV_DS17885 is not set
CONFIG_RTC_DRV_DS1742=y
CONFIG_RTC_DRV_DS2404=y
CONFIG_RTC_DRV_DA9052=y
CONFIG_RTC_DRV_DA9055=y
CONFIG_RTC_DRV_DA9063=y
CONFIG_RTC_DRV_EFI=y
CONFIG_RTC_DRV_STK17TA8=y
CONFIG_RTC_DRV_M48T86=y
CONFIG_RTC_DRV_M48T35=y
CONFIG_RTC_DRV_M48T59=y
CONFIG_RTC_DRV_MSM6242=y
CONFIG_RTC_DRV_BQ4802=y
CONFIG_RTC_DRV_RP5C01=y
CONFIG_RTC_DRV_GAMECUBE=y
CONFIG_RTC_DRV_WM831X=y
CONFIG_RTC_DRV_WM8350=y
CONFIG_RTC_DRV_SC27XX=y
CONFIG_RTC_DRV_SPEAR=y
CONFIG_RTC_DRV_PCF50633=y
CONFIG_RTC_DRV_AB8500=y
CONFIG_RTC_DRV_OPTEE=y
CONFIG_RTC_DRV_ZYNQMP=y
CONFIG_RTC_DRV_CROS_EC=y
CONFIG_RTC_DRV_NTXEC=y
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_ASM9260=y
CONFIG_RTC_DRV_DIGICOLOR=y
CONFIG_RTC_DRV_IMXDI=y
CONFIG_RTC_DRV_FSL_FTM_ALARM=y
CONFIG_RTC_DRV_MESON=y
CONFIG_RTC_DRV_MESON_VRTC=y
CONFIG_RTC_DRV_OMAP=y
CONFIG_RTC_DRV_S3C=y
CONFIG_RTC_DRV_EP93XX=y
CONFIG_RTC_DRV_SA1100=y
CONFIG_RTC_DRV_SH=y
CONFIG_RTC_DRV_SUNPLUS=y
CONFIG_RTC_DRV_PL030=y
CONFIG_RTC_DRV_PL031=y
CONFIG_RTC_DRV_AT91RM9200=y
CONFIG_RTC_DRV_AT91SAM9=y
CONFIG_RTC_DRV_RZN1=y
CONFIG_RTC_DRV_GENERIC=y
CONFIG_RTC_DRV_VT8500=y
CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_SUNXI=y
CONFIG_RTC_DRV_MV=y
CONFIG_RTC_DRV_ARMADA38X=y
CONFIG_RTC_DRV_CADENCE=y
CONFIG_RTC_DRV_FTRTC010=y
CONFIG_RTC_DRV_STMP=y
CONFIG_RTC_DRV_PCAP=y
CONFIG_RTC_DRV_MC13XXX=y
CONFIG_RTC_DRV_JZ4740=y
CONFIG_RTC_DRV_LPC24XX=y
CONFIG_RTC_DRV_LPC32XX=y
CONFIG_RTC_DRV_PM8XXX=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_MXC=y
CONFIG_RTC_DRV_MXC_V2=y
CONFIG_RTC_DRV_SNVS=y
CONFIG_RTC_DRV_IMX_SC=y
CONFIG_RTC_DRV_ST_LPC=y
CONFIG_RTC_DRV_MOXART=y
CONFIG_RTC_DRV_MT2712=y
CONFIG_RTC_DRV_MT6397=y
CONFIG_RTC_DRV_MT7622=y
CONFIG_RTC_DRV_XGENE=y
CONFIG_RTC_DRV_R7301=y
CONFIG_RTC_DRV_STM32=y
CONFIG_RTC_DRV_CPCAP=y
CONFIG_RTC_DRV_RTD119X=y
CONFIG_RTC_DRV_ASPEED=y
CONFIG_RTC_DRV_TI_K3=y
#
# HID Sensor RTC drivers
#
CONFIG_RTC_DRV_HID_SENSOR_TIME=y
CONFIG_RTC_DRV_GOLDFISH=y
CONFIG_RTC_DRV_MSC313=y
CONFIG_DMADEVICES=y
CONFIG_DMADEVICES_DEBUG=y
CONFIG_DMADEVICES_VDEBUG=y
#
# DMA Devices
#
CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMA_OF=y
CONFIG_ALTERA_MSGDMA=y
CONFIG_AMBA_PL08X=y
CONFIG_APPLE_ADMAC=y
CONFIG_AT_HDMAC=y
CONFIG_AT_XDMAC=y
CONFIG_AXI_DMAC=y
CONFIG_BCM_SBA_RAID=y
CONFIG_DMA_BCM2835=y
CONFIG_DMA_JZ4780=y
CONFIG_DMA_SA11X0=y
CONFIG_DMA_SUN4I=y
CONFIG_DMA_SUN6I=y
CONFIG_DW_AXI_DMAC=y
CONFIG_EP93XX_DMA=y
CONFIG_FSL_EDMA=y
CONFIG_FSL_QDMA=y
CONFIG_HISI_DMA=y
CONFIG_IMG_MDC_DMA=y
CONFIG_IMX_DMA=y
CONFIG_IMX_SDMA=y
CONFIG_INTEL_IDMA64=y
CONFIG_K3_DMA=y
CONFIG_LPC18XX_DMAMUX=y
CONFIG_MCF_EDMA=y
CONFIG_MILBEAUT_HDMAC=y
CONFIG_MILBEAUT_XDMAC=y
CONFIG_MMP_PDMA=y
CONFIG_MMP_TDMA=y
CONFIG_MV_XOR=y
CONFIG_MXS_DMA=y
CONFIG_MX3_IPU=y
CONFIG_MX3_IPU_IRQS=4
CONFIG_NBPFAXI_DMA=y
CONFIG_OWL_DMA=y
CONFIG_PCH_DMA=y
CONFIG_PL330_DMA=y
CONFIG_PXA_DMA=y
CONFIG_PLX_DMA=y
CONFIG_STE_DMA40=y
CONFIG_ST_FDMA=y
CONFIG_STM32_DMA=y
CONFIG_STM32_DMAMUX=y
CONFIG_STM32_MDMA=y
CONFIG_SPRD_DMA=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA210_ADMA=y
CONFIG_TIMB_DMA=y
CONFIG_UNIPHIER_MDMAC=y
CONFIG_UNIPHIER_XDMAC=y
CONFIG_XGENE_DMA=y
CONFIG_XILINX_DMA=y
CONFIG_XILINX_ZYNQMP_DMA=y
CONFIG_XILINX_ZYNQMP_DPDMA=y
CONFIG_MTK_HSDMA=y
CONFIG_MTK_CQDMA=y
CONFIG_MTK_UART_APDMA=y
CONFIG_QCOM_ADM=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_QCOM_GPI_DMA=y
CONFIG_QCOM_HIDMA_MGMT=y
CONFIG_QCOM_HIDMA=y
CONFIG_DW_DMAC_CORE=y
CONFIG_DW_DMAC=y
CONFIG_RZN1_DMAMUX=y
CONFIG_DW_DMAC_PCI=y
CONFIG_DW_EDMA=y
CONFIG_DW_EDMA_PCIE=y
CONFIG_HSU_DMA=y
CONFIG_SF_PDMA=y
CONFIG_RENESAS_DMA=y
CONFIG_SH_DMAE_BASE=y
CONFIG_SH_DMAE=y
CONFIG_RCAR_DMAC=y
CONFIG_RENESAS_USB_DMAC=y
CONFIG_RZ_DMAC=y
CONFIG_TI_CPPI41=y
CONFIG_TI_EDMA=y
CONFIG_DMA_OMAP=y
CONFIG_TI_DMA_CROSSBAR=y
CONFIG_INTEL_LDMA=y
#
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
CONFIG_DMATEST=y
CONFIG_DMA_ENGINE_RAID=y
#
# DMABUF options
#
CONFIG_SYNC_FILE=y
CONFIG_SW_SYNC=y
CONFIG_UDMABUF=y
CONFIG_DMABUF_MOVE_NOTIFY=y
CONFIG_DMABUF_DEBUG=y
CONFIG_DMABUF_SELFTESTS=y
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_SYSFS_STATS=y
CONFIG_DMABUF_HEAPS_SYSTEM=y
CONFIG_DMABUF_HEAPS_CMA=y
# end of DMABUF options
CONFIG_AUXDISPLAY=y
CONFIG_CHARLCD=y
CONFIG_LINEDISP=y
CONFIG_HD44780_COMMON=y
CONFIG_HD44780=y
CONFIG_KS0108=y
CONFIG_KS0108_PORT=0x378
CONFIG_KS0108_DELAY=2
CONFIG_IMG_ASCII_LCD=y
CONFIG_HT16K33=y
CONFIG_LCD2S=y
CONFIG_ARM_CHARLCD=y
CONFIG_PARPORT_PANEL=y
CONFIG_PANEL_PARPORT=0
CONFIG_PANEL_PROFILE=5
CONFIG_PANEL_CHANGE_MESSAGE=y
CONFIG_PANEL_BOOT_MESSAGE=""
# CONFIG_CHARLCD_BL_OFF is not set
# CONFIG_CHARLCD_BL_ON is not set
CONFIG_CHARLCD_BL_FLASH=y
CONFIG_PANEL=y
CONFIG_UIO=y
CONFIG_UIO_CIF=y
CONFIG_UIO_PDRV_GENIRQ=y
CONFIG_UIO_DMEM_GENIRQ=y
CONFIG_UIO_AEC=y
CONFIG_UIO_SERCOS3=y
CONFIG_UIO_PCI_GENERIC=y
CONFIG_UIO_NETX=y
CONFIG_UIO_PRUSS=y
CONFIG_UIO_MF624=y
CONFIG_UIO_DFL=y
CONFIG_VFIO=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=y
CONFIG_VFIO_NOIOMMU=y
CONFIG_VFIO_VIRQFD=y
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_MMAP=y
CONFIG_VFIO_PCI_INTX=y
CONFIG_VFIO_PCI=y
CONFIG_MLX5_VFIO_PCI=y
CONFIG_VFIO_PLATFORM=y
CONFIG_VFIO_AMBA=y
CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET=y
CONFIG_VFIO_PLATFORM_AMDXGBE_RESET=y
CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET=y
CONFIG_VFIO_MDEV=y
CONFIG_VFIO_FSL_MC=y
CONFIG_IRQ_BYPASS_MANAGER=y
CONFIG_VIRT_DRIVERS=y
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI_LIB=y
CONFIG_VIRTIO_PCI_LIB_LEGACY=y
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_VDPA=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
CONFIG_VDPA=y
CONFIG_VDPA_SIM=y
CONFIG_VDPA_SIM_NET=y
CONFIG_VDPA_SIM_BLOCK=y
CONFIG_VDPA_USER=y
CONFIG_IFCVF=y
CONFIG_MLX5_VDPA=y
CONFIG_MLX5_VDPA_NET=y
CONFIG_MLX5_VDPA_STEERING_DEBUG=y
CONFIG_VP_VDPA=y
CONFIG_SNET_VDPA=y
CONFIG_VHOST_IOTLB=y
CONFIG_VHOST_RING=y
CONFIG_VHOST=y
CONFIG_VHOST_MENU=y
CONFIG_VHOST_NET=y
CONFIG_VHOST_SCSI=y
CONFIG_VHOST_VSOCK=y
CONFIG_VHOST_VDPA=y
CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y
#
# Microsoft Hyper-V guest support
#
# end of Microsoft Hyper-V guest support
CONFIG_GREYBUS=y
CONFIG_GREYBUS_ES2=y
CONFIG_COMEDI=y
CONFIG_COMEDI_DEBUG=y
CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048
CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480
CONFIG_COMEDI_MISC_DRIVERS=y
CONFIG_COMEDI_BOND=y
CONFIG_COMEDI_TEST=y
CONFIG_COMEDI_PARPORT=y
CONFIG_COMEDI_SSV_DNP=y
CONFIG_COMEDI_ISA_DRIVERS=y
CONFIG_COMEDI_PCL711=y
CONFIG_COMEDI_PCL724=y
CONFIG_COMEDI_PCL726=y
CONFIG_COMEDI_PCL730=y
CONFIG_COMEDI_PCL812=y
CONFIG_COMEDI_PCL816=y
CONFIG_COMEDI_PCL818=y
CONFIG_COMEDI_PCM3724=y
CONFIG_COMEDI_AMPLC_DIO200_ISA=y
CONFIG_COMEDI_AMPLC_PC236_ISA=y
CONFIG_COMEDI_AMPLC_PC263_ISA=y
CONFIG_COMEDI_RTI800=y
CONFIG_COMEDI_RTI802=y
CONFIG_COMEDI_DAC02=y
CONFIG_COMEDI_DAS16M1=y
CONFIG_COMEDI_DAS08_ISA=y
CONFIG_COMEDI_DAS16=y
CONFIG_COMEDI_DAS800=y
CONFIG_COMEDI_DAS1800=y
CONFIG_COMEDI_DAS6402=y
CONFIG_COMEDI_DT2801=y
CONFIG_COMEDI_DT2811=y
CONFIG_COMEDI_DT2814=y
CONFIG_COMEDI_DT2815=y
CONFIG_COMEDI_DT2817=y
CONFIG_COMEDI_DT282X=y
CONFIG_COMEDI_DMM32AT=y
CONFIG_COMEDI_FL512=y
CONFIG_COMEDI_AIO_AIO12_8=y
CONFIG_COMEDI_AIO_IIRO_16=y
CONFIG_COMEDI_II_PCI20KC=y
CONFIG_COMEDI_C6XDIGIO=y
CONFIG_COMEDI_MPC624=y
CONFIG_COMEDI_ADQ12B=y
CONFIG_COMEDI_NI_AT_A2150=y
CONFIG_COMEDI_NI_AT_AO=y
CONFIG_COMEDI_NI_ATMIO=y
CONFIG_COMEDI_NI_ATMIO16D=y
CONFIG_COMEDI_NI_LABPC_ISA=y
CONFIG_COMEDI_PCMAD=y
CONFIG_COMEDI_PCMDA12=y
CONFIG_COMEDI_PCMMIO=y
CONFIG_COMEDI_PCMUIO=y
CONFIG_COMEDI_MULTIQ3=y
CONFIG_COMEDI_S526=y
CONFIG_COMEDI_PCI_DRIVERS=y
CONFIG_COMEDI_8255_PCI=y
CONFIG_COMEDI_ADDI_WATCHDOG=y
CONFIG_COMEDI_ADDI_APCI_1032=y
CONFIG_COMEDI_ADDI_APCI_1500=y
CONFIG_COMEDI_ADDI_APCI_1516=y
CONFIG_COMEDI_ADDI_APCI_1564=y
CONFIG_COMEDI_ADDI_APCI_16XX=y
CONFIG_COMEDI_ADDI_APCI_2032=y
CONFIG_COMEDI_ADDI_APCI_2200=y
CONFIG_COMEDI_ADDI_APCI_3120=y
CONFIG_COMEDI_ADDI_APCI_3501=y
CONFIG_COMEDI_ADDI_APCI_3XXX=y
CONFIG_COMEDI_ADL_PCI6208=y
CONFIG_COMEDI_ADL_PCI7X3X=y
CONFIG_COMEDI_ADL_PCI8164=y
CONFIG_COMEDI_ADL_PCI9111=y
CONFIG_COMEDI_ADL_PCI9118=y
CONFIG_COMEDI_ADV_PCI1710=y
CONFIG_COMEDI_ADV_PCI1720=y
CONFIG_COMEDI_ADV_PCI1723=y
CONFIG_COMEDI_ADV_PCI1724=y
CONFIG_COMEDI_ADV_PCI1760=y
CONFIG_COMEDI_ADV_PCI_DIO=y
CONFIG_COMEDI_AMPLC_DIO200_PCI=y
CONFIG_COMEDI_AMPLC_PC236_PCI=y
CONFIG_COMEDI_AMPLC_PC263_PCI=y
CONFIG_COMEDI_AMPLC_PCI224=y
CONFIG_COMEDI_AMPLC_PCI230=y
CONFIG_COMEDI_CONTEC_PCI_DIO=y
CONFIG_COMEDI_DAS08_PCI=y
CONFIG_COMEDI_DT3000=y
CONFIG_COMEDI_DYNA_PCI10XX=y
CONFIG_COMEDI_GSC_HPDI=y
CONFIG_COMEDI_MF6X4=y
CONFIG_COMEDI_ICP_MULTI=y
CONFIG_COMEDI_DAQBOARD2000=y
CONFIG_COMEDI_JR3_PCI=y
CONFIG_COMEDI_KE_COUNTER=y
CONFIG_COMEDI_CB_PCIDAS64=y
CONFIG_COMEDI_CB_PCIDAS=y
CONFIG_COMEDI_CB_PCIDDA=y
CONFIG_COMEDI_CB_PCIMDAS=y
CONFIG_COMEDI_CB_PCIMDDA=y
CONFIG_COMEDI_ME4000=y
CONFIG_COMEDI_ME_DAQ=y
CONFIG_COMEDI_NI_6527=y
CONFIG_COMEDI_NI_65XX=y
CONFIG_COMEDI_NI_660X=y
CONFIG_COMEDI_NI_670X=y
CONFIG_COMEDI_NI_LABPC_PCI=y
CONFIG_COMEDI_NI_PCIDIO=y
CONFIG_COMEDI_NI_PCIMIO=y
CONFIG_COMEDI_RTD520=y
CONFIG_COMEDI_S626=y
CONFIG_COMEDI_MITE=y
CONFIG_COMEDI_NI_TIOCMD=y
CONFIG_COMEDI_PCMCIA_DRIVERS=y
CONFIG_COMEDI_CB_DAS16_CS=y
CONFIG_COMEDI_DAS08_CS=y
CONFIG_COMEDI_NI_DAQ_700_CS=y
CONFIG_COMEDI_NI_DAQ_DIO24_CS=y
CONFIG_COMEDI_NI_LABPC_CS=y
CONFIG_COMEDI_NI_MIO_CS=y
CONFIG_COMEDI_QUATECH_DAQP_CS=y
CONFIG_COMEDI_USB_DRIVERS=y
CONFIG_COMEDI_DT9812=y
CONFIG_COMEDI_NI_USB6501=y
CONFIG_COMEDI_USBDUX=y
CONFIG_COMEDI_USBDUXFAST=y
CONFIG_COMEDI_USBDUXSIGMA=y
CONFIG_COMEDI_VMK80XX=y
CONFIG_COMEDI_8254=y
CONFIG_COMEDI_8255=y
CONFIG_COMEDI_8255_SA=y
CONFIG_COMEDI_KCOMEDILIB=y
CONFIG_COMEDI_AMPLC_DIO200=y
CONFIG_COMEDI_AMPLC_PC236=y
CONFIG_COMEDI_DAS08=y
CONFIG_COMEDI_NI_LABPC=y
CONFIG_COMEDI_NI_TIO=y
CONFIG_COMEDI_NI_ROUTING=y
CONFIG_COMEDI_TESTS=y
CONFIG_COMEDI_TESTS_EXAMPLE=y
CONFIG_COMEDI_TESTS_NI_ROUTES=y
CONFIG_STAGING=y
CONFIG_PRISM2_USB=y
CONFIG_RTL8192U=m
CONFIG_RTLLIB=m
CONFIG_RTLLIB_CRYPTO_CCMP=m
CONFIG_RTLLIB_CRYPTO_TKIP=m
CONFIG_RTLLIB_CRYPTO_WEP=m
CONFIG_RTL8192E=m
CONFIG_RTL8723BS=m
CONFIG_R8712U=y
CONFIG_R8188EU=m
CONFIG_RTS5208=y
CONFIG_OCTEON_ETHERNET=y
CONFIG_VT6655=m
CONFIG_VT6656=m
#
# IIO staging drivers
#
#
# Accelerometers
#
CONFIG_ADIS16203=y
CONFIG_ADIS16240=y
# end of Accelerometers
#
# Analog to digital converters
#
CONFIG_AD7816=y
# end of Analog to digital converters
#
# Analog digital bi-direction converters
#
CONFIG_ADT7316=y
CONFIG_ADT7316_SPI=y
CONFIG_ADT7316_I2C=y
# end of Analog digital bi-direction converters
#
# Direct Digital Synthesis
#
CONFIG_AD9832=y
CONFIG_AD9834=y
# end of Direct Digital Synthesis
#
# Network Analyzer, Impedance Converters
#
CONFIG_AD5933=y
# end of Network Analyzer, Impedance Converters
#
# Active energy metering IC
#
CONFIG_ADE7854=y
CONFIG_ADE7854_I2C=y
CONFIG_ADE7854_SPI=y
# end of Active energy metering IC
#
# Resolver to digital converters
#
CONFIG_AD2S1210=y
# end of Resolver to digital converters
# end of IIO staging drivers
CONFIG_FB_SM750=y
CONFIG_USB_EMXX=y
CONFIG_MFD_NVEC=y
CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
CONFIG_NVEC_POWER=y
CONFIG_NVEC_PAZ00=y
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_IMX_MEDIA=y
#
# i.MX5/6/7/8 Media Sub devices
#
CONFIG_VIDEO_IMX_CSI=y
# end of i.MX5/6/7/8 Media Sub devices
CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=y
CONFIG_VIDEO_MAX96712=y
CONFIG_VIDEO_MESON_VDEC=y
CONFIG_VIDEO_OMAP4=y
CONFIG_VIDEO_ROCKCHIP_VDEC=y
CONFIG_VIDEO_SUNXI=y
CONFIG_VIDEO_SUNXI_CEDRUS=y
CONFIG_VIDEO_SUN6I_ISP=y
CONFIG_VIDEO_TEGRA=y
CONFIG_VIDEO_TEGRA_TPG=y
CONFIG_STAGING_MEDIA_DEPRECATED=y
#
# Atmel media platform drivers
#
CONFIG_VIDEO_ATMEL_ISC=y
CONFIG_VIDEO_ATMEL_XISC=y
CONFIG_VIDEO_ATMEL_ISC_BASE=y
CONFIG_VIDEO_CPIA2=y
CONFIG_VIDEO_VIU=y
CONFIG_VIDEO_SAA7146=y
CONFIG_VIDEO_SAA7146_VV=y
CONFIG_DVB_AV7110_IR=y
CONFIG_DVB_AV7110=y
CONFIG_DVB_AV7110_OSD=y
CONFIG_DVB_BUDGET_PATCH=y
CONFIG_DVB_SP8870=y
CONFIG_VIDEO_HEXIUM_GEMINI=y
CONFIG_VIDEO_HEXIUM_ORION=y
CONFIG_VIDEO_MXB=y
CONFIG_DVB_BUDGET_CORE=y
CONFIG_DVB_BUDGET=y
CONFIG_DVB_BUDGET_CI=y
CONFIG_DVB_BUDGET_AV=y
CONFIG_VIDEO_STKWEBCAM=y
CONFIG_VIDEO_TM6000=y
CONFIG_VIDEO_TM6000_ALSA=y
CONFIG_VIDEO_TM6000_DVB=y
CONFIG_USB_ZR364XX=y
CONFIG_STAGING_BOARD=y
CONFIG_LTE_GDM724X=m
CONFIG_FB_TFT=y
CONFIG_FB_TFT_AGM1264K_FL=y
CONFIG_FB_TFT_BD663474=y
CONFIG_FB_TFT_HX8340BN=y
CONFIG_FB_TFT_HX8347D=y
CONFIG_FB_TFT_HX8353D=y
CONFIG_FB_TFT_HX8357D=y
CONFIG_FB_TFT_ILI9163=y
CONFIG_FB_TFT_ILI9320=y
CONFIG_FB_TFT_ILI9325=y
CONFIG_FB_TFT_ILI9340=y
CONFIG_FB_TFT_ILI9341=y
CONFIG_FB_TFT_ILI9481=y
CONFIG_FB_TFT_ILI9486=y
CONFIG_FB_TFT_PCD8544=y
CONFIG_FB_TFT_RA8875=y
CONFIG_FB_TFT_S6D02A1=y
CONFIG_FB_TFT_S6D1121=y
CONFIG_FB_TFT_SEPS525=y
CONFIG_FB_TFT_SH1106=y
CONFIG_FB_TFT_SSD1289=y
CONFIG_FB_TFT_SSD1305=y
CONFIG_FB_TFT_SSD1306=y
CONFIG_FB_TFT_SSD1331=y
CONFIG_FB_TFT_SSD1351=y
CONFIG_FB_TFT_ST7735R=y
CONFIG_FB_TFT_ST7789V=y
CONFIG_FB_TFT_TINYLCD=y
CONFIG_FB_TFT_TLS8204=y
CONFIG_FB_TFT_UC1611=y
CONFIG_FB_TFT_UC1701=y
CONFIG_FB_TFT_UPD161704=y
CONFIG_MOST_COMPONENTS=y
CONFIG_MOST_NET=y
CONFIG_MOST_VIDEO=y
CONFIG_MOST_DIM2=y
CONFIG_MOST_I2C=y
CONFIG_KS7010=y
CONFIG_GREYBUS_AUDIO=y
CONFIG_GREYBUS_AUDIO_APB_CODEC=y
CONFIG_GREYBUS_BOOTROM=y
CONFIG_GREYBUS_FIRMWARE=y
CONFIG_GREYBUS_HID=y
CONFIG_GREYBUS_LIGHT=y
CONFIG_GREYBUS_LOG=y
CONFIG_GREYBUS_LOOPBACK=y
CONFIG_GREYBUS_POWER=y
CONFIG_GREYBUS_RAW=y
CONFIG_GREYBUS_VIBRATOR=y
CONFIG_GREYBUS_BRIDGED_PHY=y
CONFIG_GREYBUS_GPIO=y
CONFIG_GREYBUS_I2C=y
CONFIG_GREYBUS_PWM=y
CONFIG_GREYBUS_SDIO=y
CONFIG_GREYBUS_SPI=y
CONFIG_GREYBUS_UART=y
CONFIG_GREYBUS_USB=y
CONFIG_GREYBUS_ARCHE=y
CONFIG_BCM_VIDEOCORE=y
CONFIG_BCM2835_VCHIQ=y
CONFIG_VCHIQ_CDEV=y
CONFIG_SND_BCM2835=y
CONFIG_VIDEO_BCM2835=y
CONFIG_BCM2835_VCHIQ_MMAL=y
CONFIG_PI433=y
CONFIG_XIL_AXIS_FIFO=y
CONFIG_FIELDBUS_DEV=y
CONFIG_HMS_ANYBUSS_BUS=y
CONFIG_ARCX_ANYBUS_CONTROLLER=y
CONFIG_HMS_PROFINET=y
CONFIG_QLGE=y
CONFIG_VME_BUS=y
#
# VME Bridge Drivers
#
CONFIG_VME_TSI148=y
CONFIG_VME_FAKE=y
#
# VME Device Drivers
#
CONFIG_VME_USER=y
CONFIG_GOLDFISH=y
CONFIG_GOLDFISH_PIPE=y
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_RPMSG=y
CONFIG_CROS_EC_SPI=y
CONFIG_CROS_EC_PROTO=y
CONFIG_CROS_KBD_LED_BACKLIGHT=y
CONFIG_CROS_EC_CHARDEV=y
CONFIG_CROS_EC_LIGHTBAR=y
CONFIG_CROS_EC_VBC=y
CONFIG_CROS_EC_DEBUGFS=y
CONFIG_CROS_EC_SENSORHUB=y
CONFIG_CROS_EC_SYSFS=y
CONFIG_CROS_EC_TYPEC=y
CONFIG_CROS_HPS_I2C=y
CONFIG_CROS_USBPD_LOGGER=y
CONFIG_CROS_USBPD_NOTIFY=y
CONFIG_CROS_KUNIT=y
CONFIG_MELLANOX_PLATFORM=y
CONFIG_MLXREG_HOTPLUG=y
CONFIG_MLXREG_IO=y
CONFIG_MLXREG_LC=y
CONFIG_NVSW_SN2201=y
CONFIG_OLPC_EC=y
CONFIG_OLPC_XO175=y
CONFIG_OLPC_XO175_EC=y
CONFIG_SURFACE_PLATFORMS=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_WM831X=y
#
# Clock driver for ARM Reference designs
#
CONFIG_CLK_ICST=y
CONFIG_CLK_SP810=y
CONFIG_CLK_VEXPRESS_OSC=y
# end of Clock driver for ARM Reference designs
CONFIG_CLK_HSDK=y
CONFIG_LMK04832=y
CONFIG_COMMON_CLK_APPLE_NCO=y
CONFIG_COMMON_CLK_MAX77686=y
CONFIG_COMMON_CLK_MAX9485=y
CONFIG_COMMON_CLK_RK808=y
CONFIG_COMMON_CLK_HI655X=y
CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_SI5341=y
CONFIG_COMMON_CLK_SI5351=y
CONFIG_COMMON_CLK_SI514=y
CONFIG_COMMON_CLK_SI544=y
CONFIG_COMMON_CLK_SI570=y
CONFIG_COMMON_CLK_BM1880=y
CONFIG_COMMON_CLK_CDCE706=y
CONFIG_COMMON_CLK_TPS68470=y
CONFIG_COMMON_CLK_CDCE925=y
CONFIG_COMMON_CLK_CS2000_CP=y
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMMON_CLK_FSL_FLEXSPI=y
CONFIG_COMMON_CLK_FSL_SAI=y
CONFIG_COMMON_CLK_GEMINI=y
CONFIG_COMMON_CLK_LAN966X=y
CONFIG_COMMON_CLK_ASPEED=y
CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_CLK_TWL6040=y
CONFIG_COMMON_CLK_AXI_CLKGEN=y
CONFIG_CLK_QORIQ=y
CONFIG_CLK_LS1028A_PLLDIG=y
CONFIG_COMMON_CLK_XGENE=y
CONFIG_COMMON_CLK_LOCHNAGAR=y
CONFIG_COMMON_CLK_PALMAS=y
CONFIG_COMMON_CLK_PWM=y
CONFIG_COMMON_CLK_OXNAS=y
CONFIG_COMMON_CLK_RS9_PCIE=y
CONFIG_COMMON_CLK_VC5=y
CONFIG_COMMON_CLK_VC7=y
CONFIG_COMMON_CLK_STM32MP135=y
CONFIG_COMMON_CLK_STM32MP157=y
CONFIG_COMMON_CLK_MMP2=y
CONFIG_COMMON_CLK_MMP2_AUDIO=y
CONFIG_COMMON_CLK_BD718XX=y
CONFIG_COMMON_CLK_FIXED_MMIO=y
CONFIG_CLK_ACTIONS=y
CONFIG_CLK_OWL_S500=y
CONFIG_CLK_OWL_S700=y
CONFIG_CLK_OWL_S900=y
CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
CONFIG_CLK_BAIKAL_T1=y
CONFIG_CLK_BT1_CCU_PLL=y
CONFIG_CLK_BT1_CCU_DIV=y
CONFIG_CLK_BT1_CCU_RST=y
CONFIG_CLK_BCM2711_DVP=y
CONFIG_CLK_BCM2835=y
CONFIG_CLK_BCM_63XX=y
CONFIG_CLK_BCM_63XX_GATE=y
CONFIG_CLK_BCM_KONA=y
CONFIG_COMMON_CLK_IPROC=y
CONFIG_CLK_BCM_CYGNUS=y
CONFIG_CLK_BCM_HR2=y
CONFIG_CLK_BCM_NSP=y
CONFIG_CLK_BCM_NS2=y
CONFIG_CLK_BCM_SR=y
CONFIG_CLK_RASPBERRYPI=y
CONFIG_COMMON_CLK_HI3516CV300=y
CONFIG_COMMON_CLK_HI3519=y
CONFIG_COMMON_CLK_HI3559A=y
CONFIG_COMMON_CLK_HI3660=y
CONFIG_COMMON_CLK_HI3670=y
CONFIG_COMMON_CLK_HI3798CV200=y
CONFIG_COMMON_CLK_HI6220=y
CONFIG_RESET_HISI=y
CONFIG_STUB_CLK_HI6220=y
CONFIG_STUB_CLK_HI3660=y
CONFIG_COMMON_CLK_BOSTON=y
CONFIG_MXC_CLK=y
CONFIG_MXC_CLK_SCU=y
CONFIG_CLK_IMX31=y
CONFIG_CLK_IMX35=y
CONFIG_CLK_IMX5=y
CONFIG_CLK_IMX6Q=y
CONFIG_CLK_IMX6SL=y
CONFIG_CLK_IMX6SLL=y
CONFIG_CLK_IMX6SX=y
CONFIG_CLK_IMX6UL=y
CONFIG_CLK_IMX7D=y
CONFIG_CLK_IMX7ULP=y
CONFIG_CLK_VF610=y
CONFIG_CLK_IMX8MM=y
CONFIG_CLK_IMX8MN=y
CONFIG_CLK_IMX8MP=y
CONFIG_CLK_IMX8MQ=y
CONFIG_CLK_IMX8QXP=y
CONFIG_CLK_IMX8ULP=y
CONFIG_CLK_IMX93=y
#
# Ingenic SoCs drivers
#
CONFIG_INGENIC_CGU_COMMON=y
CONFIG_INGENIC_CGU_JZ4740=y
CONFIG_INGENIC_CGU_JZ4755=y
CONFIG_INGENIC_CGU_JZ4725B=y
CONFIG_INGENIC_CGU_JZ4760=y
CONFIG_INGENIC_CGU_JZ4770=y
CONFIG_INGENIC_CGU_JZ4780=y
CONFIG_INGENIC_CGU_X1000=y
CONFIG_INGENIC_CGU_X1830=y
CONFIG_INGENIC_TCU_CLK=y
# end of Ingenic SoCs drivers
CONFIG_COMMON_CLK_KEYSTONE=y
CONFIG_TI_SCI_CLK=y
CONFIG_TI_SCI_CLK_PROBE_FROM_FW=y
CONFIG_TI_SYSCON_CLK=y
#
# Clock driver for MediaTek SoC
#
CONFIG_COMMON_CLK_MEDIATEK=y
CONFIG_COMMON_CLK_MEDIATEK_FHCTL=y
CONFIG_COMMON_CLK_MT2701=y
CONFIG_COMMON_CLK_MT2701_MMSYS=y
CONFIG_COMMON_CLK_MT2701_IMGSYS=y
CONFIG_COMMON_CLK_MT2701_VDECSYS=y
CONFIG_COMMON_CLK_MT2701_HIFSYS=y
CONFIG_COMMON_CLK_MT2701_ETHSYS=y
CONFIG_COMMON_CLK_MT2701_BDPSYS=y
CONFIG_COMMON_CLK_MT2701_AUDSYS=y
CONFIG_COMMON_CLK_MT2701_G3DSYS=y
CONFIG_COMMON_CLK_MT2712=y
CONFIG_COMMON_CLK_MT2712_BDPSYS=y
CONFIG_COMMON_CLK_MT2712_IMGSYS=y
CONFIG_COMMON_CLK_MT2712_JPGDECSYS=y
CONFIG_COMMON_CLK_MT2712_MFGCFG=y
CONFIG_COMMON_CLK_MT2712_MMSYS=y
CONFIG_COMMON_CLK_MT2712_VDECSYS=y
CONFIG_COMMON_CLK_MT2712_VENCSYS=y
CONFIG_COMMON_CLK_MT6765=y
CONFIG_COMMON_CLK_MT6765_AUDIOSYS=y
CONFIG_COMMON_CLK_MT6765_CAMSYS=y
CONFIG_COMMON_CLK_MT6765_GCESYS=y
CONFIG_COMMON_CLK_MT6765_MMSYS=y
CONFIG_COMMON_CLK_MT6765_IMGSYS=y
CONFIG_COMMON_CLK_MT6765_VCODECSYS=y
CONFIG_COMMON_CLK_MT6765_MFGSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI0ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI0BSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI1ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI1BSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI2ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI2BSYS=y
CONFIG_COMMON_CLK_MT6779=y
CONFIG_COMMON_CLK_MT6779_MMSYS=y
CONFIG_COMMON_CLK_MT6779_IMGSYS=y
CONFIG_COMMON_CLK_MT6779_IPESYS=y
CONFIG_COMMON_CLK_MT6779_CAMSYS=y
CONFIG_COMMON_CLK_MT6779_VDECSYS=y
CONFIG_COMMON_CLK_MT6779_VENCSYS=y
CONFIG_COMMON_CLK_MT6779_MFGCFG=y
CONFIG_COMMON_CLK_MT6779_AUDSYS=y
CONFIG_COMMON_CLK_MT6795=y
CONFIG_COMMON_CLK_MT6795_MFGCFG=y
CONFIG_COMMON_CLK_MT6795_MMSYS=y
CONFIG_COMMON_CLK_MT6795_VDECSYS=y
CONFIG_COMMON_CLK_MT6795_VENCSYS=y
CONFIG_COMMON_CLK_MT6797=y
CONFIG_COMMON_CLK_MT6797_MMSYS=y
CONFIG_COMMON_CLK_MT6797_IMGSYS=y
CONFIG_COMMON_CLK_MT6797_VDECSYS=y
CONFIG_COMMON_CLK_MT6797_VENCSYS=y
CONFIG_COMMON_CLK_MT7622=y
CONFIG_COMMON_CLK_MT7622_ETHSYS=y
CONFIG_COMMON_CLK_MT7622_HIFSYS=y
CONFIG_COMMON_CLK_MT7622_AUDSYS=y
CONFIG_COMMON_CLK_MT7629=y
CONFIG_COMMON_CLK_MT7629_ETHSYS=y
CONFIG_COMMON_CLK_MT7629_HIFSYS=y
CONFIG_COMMON_CLK_MT7986=y
CONFIG_COMMON_CLK_MT7986_ETHSYS=y
CONFIG_COMMON_CLK_MT8135=y
CONFIG_COMMON_CLK_MT8167=y
CONFIG_COMMON_CLK_MT8167_AUDSYS=y
CONFIG_COMMON_CLK_MT8167_IMGSYS=y
CONFIG_COMMON_CLK_MT8167_MFGCFG=y
CONFIG_COMMON_CLK_MT8167_MMSYS=y
CONFIG_COMMON_CLK_MT8167_VDECSYS=y
CONFIG_COMMON_CLK_MT8173=y
CONFIG_COMMON_CLK_MT8173_MMSYS=y
CONFIG_COMMON_CLK_MT8183=y
CONFIG_COMMON_CLK_MT8183_AUDIOSYS=y
CONFIG_COMMON_CLK_MT8183_CAMSYS=y
CONFIG_COMMON_CLK_MT8183_IMGSYS=y
CONFIG_COMMON_CLK_MT8183_IPU_CORE0=y
CONFIG_COMMON_CLK_MT8183_IPU_CORE1=y
CONFIG_COMMON_CLK_MT8183_IPU_ADL=y
CONFIG_COMMON_CLK_MT8183_IPU_CONN=y
CONFIG_COMMON_CLK_MT8183_MFGCFG=y
CONFIG_COMMON_CLK_MT8183_MMSYS=y
CONFIG_COMMON_CLK_MT8183_VDECSYS=y
CONFIG_COMMON_CLK_MT8183_VENCSYS=y
CONFIG_COMMON_CLK_MT8186=y
CONFIG_COMMON_CLK_MT8192=y
CONFIG_COMMON_CLK_MT8192_AUDSYS=y
CONFIG_COMMON_CLK_MT8192_CAMSYS=y
CONFIG_COMMON_CLK_MT8192_IMGSYS=y
CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP=y
CONFIG_COMMON_CLK_MT8192_IPESYS=y
CONFIG_COMMON_CLK_MT8192_MDPSYS=y
CONFIG_COMMON_CLK_MT8192_MFGCFG=y
CONFIG_COMMON_CLK_MT8192_MMSYS=y
CONFIG_COMMON_CLK_MT8192_MSDC=y
CONFIG_COMMON_CLK_MT8192_SCP_ADSP=y
CONFIG_COMMON_CLK_MT8192_VDECSYS=y
CONFIG_COMMON_CLK_MT8192_VENCSYS=y
CONFIG_COMMON_CLK_MT8195=y
CONFIG_COMMON_CLK_MT8365=y
CONFIG_COMMON_CLK_MT8365_APU=y
CONFIG_COMMON_CLK_MT8365_CAM=y
CONFIG_COMMON_CLK_MT8365_MFG=y
CONFIG_COMMON_CLK_MT8365_MMSYS=y
CONFIG_COMMON_CLK_MT8365_VDEC=y
CONFIG_COMMON_CLK_MT8365_VENC=y
CONFIG_COMMON_CLK_MT8516=y
CONFIG_COMMON_CLK_MT8516_AUDSYS=y
# end of Clock driver for MediaTek SoC
#
# Clock support for Amlogic platforms
#
CONFIG_COMMON_CLK_MESON_REGMAP=y
CONFIG_COMMON_CLK_MESON_MPLL=y
CONFIG_COMMON_CLK_MESON_PLL=y
CONFIG_COMMON_CLK_MESON8B=y
# CONFIG_COMMON_CLK_AXG_AUDIO is not set
# end of Clock support for Amlogic platforms
CONFIG_MSTAR_MSC313_CPUPLL=y
CONFIG_MSTAR_MSC313_MPLL=y
CONFIG_MCHP_CLK_MPFS=y
CONFIG_MVEBU_CLK_COMMON=y
CONFIG_MVEBU_CLK_CPU=y
CONFIG_MVEBU_CLK_COREDIV=y
CONFIG_ARMADA_AP_CP_HELPER=y
CONFIG_ARMADA_370_CLK=y
CONFIG_ARMADA_375_CLK=y
CONFIG_ARMADA_38X_CLK=y
CONFIG_ARMADA_39X_CLK=y
CONFIG_ARMADA_XP_CLK=y
CONFIG_ARMADA_AP_CPU_CLK=y
CONFIG_DOVE_CLK=y
CONFIG_COMMON_CLK_PISTACHIO=y
CONFIG_KRAIT_CLOCKS=y
CONFIG_QCOM_GDSC=y
CONFIG_QCOM_RPMCC=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_QCOM_A53PLL=y
CONFIG_QCOM_A7PLL=y
CONFIG_QCOM_CLK_APCS_MSM8916=y
CONFIG_QCOM_CLK_APCS_SDX55=y
CONFIG_QCOM_CLK_RPM=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_QCOM_CLK_RPMH=y
CONFIG_APQ_GCC_8084=y
CONFIG_APQ_MMCC_8084=y
CONFIG_IPQ_APSS_PLL=y
CONFIG_IPQ_APSS_6018=y
CONFIG_IPQ_GCC_4019=y
CONFIG_IPQ_GCC_6018=y
CONFIG_IPQ_GCC_806X=y
CONFIG_IPQ_LCC_806X=y
CONFIG_IPQ_GCC_8074=y
CONFIG_MSM_GCC_8660=y
CONFIG_MSM_GCC_8909=y
CONFIG_MSM_GCC_8916=y
CONFIG_MSM_GCC_8939=y
CONFIG_MSM_GCC_8960=y
CONFIG_MSM_LCC_8960=y
CONFIG_MDM_GCC_9607=y
CONFIG_MDM_GCC_9615=y
CONFIG_MDM_LCC_9615=y
CONFIG_MSM_MMCC_8960=y
CONFIG_MSM_GCC_8953=y
CONFIG_MSM_GCC_8974=y
CONFIG_MSM_MMCC_8974=y
CONFIG_MSM_GCC_8976=y
CONFIG_MSM_MMCC_8994=y
CONFIG_MSM_GCC_8994=y
CONFIG_MSM_GCC_8996=y
CONFIG_MSM_MMCC_8996=y
CONFIG_MSM_GCC_8998=y
CONFIG_MSM_GPUCC_8998=y
CONFIG_MSM_MMCC_8998=y
CONFIG_QCM_GCC_2290=y
CONFIG_QCM_DISPCC_2290=y
CONFIG_QCS_GCC_404=y
CONFIG_SC_CAMCC_7180=y
CONFIG_SC_CAMCC_7280=y
CONFIG_SC_DISPCC_7180=y
CONFIG_SC_DISPCC_7280=y
CONFIG_SC_DISPCC_8280XP=y
CONFIG_SC_GCC_7180=y
CONFIG_SC_GCC_7280=y
CONFIG_SC_GCC_8180X=y
CONFIG_SC_GCC_8280XP=y
CONFIG_SC_GPUCC_7180=y
CONFIG_SC_GPUCC_7280=y
CONFIG_SC_GPUCC_8280XP=y
CONFIG_SC_LPASSCC_7280=y
CONFIG_SC_LPASS_CORECC_7180=y
CONFIG_SC_LPASS_CORECC_7280=y
CONFIG_SC_MSS_7180=y
CONFIG_SC_VIDEOCC_7180=y
CONFIG_SC_VIDEOCC_7280=y
CONFIG_SDM_CAMCC_845=y
CONFIG_SDM_GCC_660=y
CONFIG_SDM_MMCC_660=y
CONFIG_SDM_GPUCC_660=y
CONFIG_QCS_TURING_404=y
CONFIG_QCS_Q6SSTOP_404=y
CONFIG_SDM_GCC_845=y
CONFIG_SDM_GPUCC_845=y
CONFIG_SDM_VIDEOCC_845=y
CONFIG_SDM_DISPCC_845=y
CONFIG_SDM_LPASSCC_845=y
CONFIG_SDX_GCC_55=y
CONFIG_SDX_GCC_65=y
CONFIG_SM_CAMCC_6350=y
CONFIG_SM_CAMCC_8250=y
CONFIG_SM_CAMCC_8450=y
CONFIG_SM_DISPCC_6115=y
CONFIG_SM_DISPCC_6125=y
CONFIG_SM_DISPCC_8250=y
CONFIG_SM_DISPCC_6350=y
CONFIG_SM_DISPCC_6375=y
CONFIG_SM_DISPCC_8450=y
CONFIG_SM_GCC_6115=y
CONFIG_SM_GCC_6125=y
CONFIG_SM_GCC_6350=y
CONFIG_SM_GCC_6375=y
CONFIG_SM_GCC_8150=y
CONFIG_SM_GCC_8250=y
CONFIG_SM_GCC_8350=y
CONFIG_SM_GCC_8450=y
CONFIG_SM_GCC_8550=y
CONFIG_SM_GPUCC_6350=y
CONFIG_SM_GPUCC_8150=y
CONFIG_SM_GPUCC_8250=y
CONFIG_SM_GPUCC_8350=y
CONFIG_SM_TCSRCC_8550=y
CONFIG_SM_VIDEOCC_8150=y
CONFIG_SM_VIDEOCC_8250=y
CONFIG_SPMI_PMIC_CLKDIV=y
CONFIG_QCOM_HFPLL=y
CONFIG_KPSS_XCC=y
CONFIG_KRAITCC=y
CONFIG_CLK_GFM_LPASS_SM8250=y
CONFIG_CLK_MT7621=y
CONFIG_CLK_RENESAS=y
CONFIG_CLK_EMEV2=y
CONFIG_CLK_RZA1=y
CONFIG_CLK_R7S9210=y
CONFIG_CLK_R8A73A4=y
CONFIG_CLK_R8A7740=y
CONFIG_CLK_R8A7742=y
CONFIG_CLK_R8A7743=y
CONFIG_CLK_R8A7745=y
CONFIG_CLK_R8A77470=y
CONFIG_CLK_R8A774A1=y
CONFIG_CLK_R8A774B1=y
CONFIG_CLK_R8A774C0=y
CONFIG_CLK_R8A774E1=y
CONFIG_CLK_R8A7778=y
CONFIG_CLK_R8A7779=y
CONFIG_CLK_R8A7790=y
CONFIG_CLK_R8A7791=y
CONFIG_CLK_R8A7792=y
CONFIG_CLK_R8A7794=y
CONFIG_CLK_R8A7795=y
CONFIG_CLK_R8A77960=y
CONFIG_CLK_R8A77961=y
CONFIG_CLK_R8A77965=y
CONFIG_CLK_R8A77970=y
CONFIG_CLK_R8A77980=y
CONFIG_CLK_R8A77990=y
CONFIG_CLK_R8A77995=y
CONFIG_CLK_R8A779A0=y
CONFIG_CLK_R8A779F0=y
CONFIG_CLK_R8A779G0=y
CONFIG_CLK_R9A06G032=y
CONFIG_CLK_R9A07G043=y
CONFIG_CLK_R9A07G044=y
CONFIG_CLK_R9A07G054=y
CONFIG_CLK_R9A09G011=y
CONFIG_CLK_SH73A0=y
CONFIG_CLK_RCAR_CPG_LIB=y
CONFIG_CLK_RCAR_GEN2_CPG=y
CONFIG_CLK_RCAR_GEN3_CPG=y
CONFIG_CLK_RCAR_GEN4_CPG=y
CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
CONFIG_CLK_RZG2L=y
CONFIG_CLK_RENESAS_CPG_MSSR=y
CONFIG_CLK_RENESAS_CPG_MSTP=y
CONFIG_CLK_RENESAS_DIV6=y
CONFIG_COMMON_CLK_ROCKCHIP=y
CONFIG_CLK_PX30=y
CONFIG_CLK_RV110X=y
CONFIG_CLK_RV1126=y
CONFIG_CLK_RK3036=y
CONFIG_CLK_RK312X=y
CONFIG_CLK_RK3188=y
CONFIG_CLK_RK322X=y
CONFIG_CLK_RK3288=y
CONFIG_CLK_RK3308=y
CONFIG_CLK_RK3328=y
CONFIG_CLK_RK3368=y
CONFIG_CLK_RK3399=y
CONFIG_CLK_RK3568=y
CONFIG_CLK_RK3588=y
CONFIG_COMMON_CLK_SAMSUNG=y
CONFIG_S3C64XX_COMMON_CLK=y
CONFIG_S5PV210_COMMON_CLK=y
CONFIG_EXYNOS_3250_COMMON_CLK=y
CONFIG_EXYNOS_4_COMMON_CLK=y
CONFIG_EXYNOS_5250_COMMON_CLK=y
CONFIG_EXYNOS_5260_COMMON_CLK=y
CONFIG_EXYNOS_5410_COMMON_CLK=y
CONFIG_EXYNOS_5420_COMMON_CLK=y
CONFIG_EXYNOS_ARM64_COMMON_CLK=y
CONFIG_EXYNOS_AUDSS_CLK_CON=y
CONFIG_EXYNOS_CLKOUT=y
CONFIG_TESLA_FSD_COMMON_CLK=y
CONFIG_CLK_SIFIVE=y
CONFIG_CLK_SIFIVE_PRCI=y
CONFIG_CLK_INTEL_SOCFPGA=y
CONFIG_CLK_INTEL_SOCFPGA32=y
CONFIG_CLK_INTEL_SOCFPGA64=y
CONFIG_SPRD_COMMON_CLK=y
CONFIG_SPRD_SC9860_CLK=y
CONFIG_SPRD_SC9863A_CLK=y
CONFIG_SPRD_UMS512_CLK=y
CONFIG_CLK_STARFIVE_JH7100=y
CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
CONFIG_CLK_SUNXI=y
CONFIG_CLK_SUNXI_CLOCKS=y
CONFIG_CLK_SUNXI_PRCM_SUN6I=y
CONFIG_CLK_SUNXI_PRCM_SUN8I=y
CONFIG_CLK_SUNXI_PRCM_SUN9I=y
CONFIG_SUNXI_CCU=y
CONFIG_SUNIV_F1C100S_CCU=y
CONFIG_SUN20I_D1_CCU=y
CONFIG_SUN20I_D1_R_CCU=y
CONFIG_SUN50I_A64_CCU=y
CONFIG_SUN50I_A100_CCU=y
CONFIG_SUN50I_A100_R_CCU=y
CONFIG_SUN50I_H6_CCU=y
CONFIG_SUN50I_H616_CCU=y
CONFIG_SUN50I_H6_R_CCU=y
CONFIG_SUN4I_A10_CCU=y
CONFIG_SUN5I_CCU=y
CONFIG_SUN6I_A31_CCU=y
CONFIG_SUN6I_RTC_CCU=y
CONFIG_SUN8I_A23_CCU=y
CONFIG_SUN8I_A33_CCU=y
CONFIG_SUN8I_A83T_CCU=y
CONFIG_SUN8I_H3_CCU=y
CONFIG_SUN8I_V3S_CCU=y
CONFIG_SUN8I_DE2_CCU=y
CONFIG_SUN8I_R40_CCU=y
CONFIG_SUN9I_A80_CCU=y
CONFIG_SUN8I_R_CCU=y
CONFIG_CLK_TEGRA_BPMP=y
CONFIG_TEGRA_CLK_DFLL=y
CONFIG_TEGRA124_CLK_EMC=y
CONFIG_COMMON_CLK_TI_ADPLL=y
CONFIG_CLK_UNIPHIER=y
CONFIG_COMMON_CLK_VISCONTI=y
CONFIG_CLK_LGM_CGU=y
CONFIG_XILINX_VCU=y
CONFIG_COMMON_CLK_XLNX_CLKWZRD=y
CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_CLK_KUNIT_TEST=y
CONFIG_CLK_GATE_KUNIT_TEST=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_OMAP=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_HWSPINLOCK_SPRD=y
CONFIG_HWSPINLOCK_STM32=y
CONFIG_HWSPINLOCK_SUN6I=y
CONFIG_HSEM_U8500=y
#
# Clock Source drivers
#
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_OMAP_DM_SYSTIMER=y
CONFIG_CLKSRC_MMIO=y
CONFIG_BCM2835_TIMER=y
CONFIG_BCM_KONA_TIMER=y
CONFIG_DAVINCI_TIMER=y
CONFIG_DIGICOLOR_TIMER=y
CONFIG_OMAP_DM_TIMER=y
CONFIG_DW_APB_TIMER=y
CONFIG_DW_APB_TIMER_OF=y
CONFIG_FTTMR010_TIMER=y
CONFIG_IXP4XX_TIMER=y
CONFIG_ROCKCHIP_TIMER=y
CONFIG_ARMADA_370_XP_TIMER=y
CONFIG_MESON6_TIMER=y
CONFIG_ORION_TIMER=y
CONFIG_OWL_TIMER=y
CONFIG_RDA_TIMER=y
CONFIG_SUN4I_TIMER=y
CONFIG_SUN5I_HSTIMER=y
CONFIG_TEGRA_TIMER=y
CONFIG_TEGRA186_TIMER=y
CONFIG_VT8500_TIMER=y
CONFIG_NPCM7XX_TIMER=y
CONFIG_CADENCE_TTC_TIMER=y
CONFIG_ASM9260_TIMER=y
CONFIG_CLKSRC_NOMADIK_MTU=y
CONFIG_CLKSRC_DBX500_PRCMU=y
CONFIG_CLPS711X_TIMER=y
CONFIG_MXS_TIMER=y
CONFIG_NSPIRE_TIMER=y
CONFIG_KEYSTONE_TIMER=y
CONFIG_INTEGRATOR_AP_TIMER=y
CONFIG_CLKSRC_LPC32XX=y
CONFIG_CLKSRC_PISTACHIO=y
CONFIG_CLKSRC_TI_32K=y
CONFIG_CLKSRC_STM32=y
CONFIG_CLKSRC_STM32_LP=y
CONFIG_CLKSRC_MPS2=y
CONFIG_ARC_TIMERS=y
CONFIG_ARC_TIMERS_64BIT=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_GLOBAL_TIMER=y
CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2
CONFIG_ARM_TIMER_SP804=y
CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
CONFIG_ARMV7M_SYSTICK=y
CONFIG_ATMEL_PIT=y
CONFIG_ATMEL_ST=y
CONFIG_ATMEL_TCB_CLKSRC=y
CONFIG_CLKSRC_EXYNOS_MCT=y
CONFIG_CLKSRC_SAMSUNG_PWM=y
CONFIG_FSL_FTM_TIMER=y
CONFIG_OXNAS_RPS_TIMER=y
CONFIG_SYS_SUPPORTS_SH_CMT=y
CONFIG_MTK_TIMER=y
CONFIG_SPRD_TIMER=y
CONFIG_SYS_SUPPORTS_SH_MTU2=y
CONFIG_SYS_SUPPORTS_SH_TMU=y
CONFIG_SYS_SUPPORTS_EM_STI=y
CONFIG_CLKSRC_JCORE_PIT=y
CONFIG_SH_TIMER_CMT=y
CONFIG_SH_TIMER_MTU2=y
CONFIG_RENESAS_OSTM=y
CONFIG_SH_TIMER_TMU=y
CONFIG_EM_TIMER_STI=y
CONFIG_CLKSRC_QCOM=y
CONFIG_CLKSRC_VERSATILE=y
CONFIG_CLKSRC_PXA=y
CONFIG_CLKSRC_IMX_GPT=y
CONFIG_CLKSRC_IMX_TPM=y
CONFIG_TIMER_IMX_SYS_CTR=y
CONFIG_CLKSRC_ST_LPC=y
CONFIG_GXP_TIMER=y
CONFIG_MILBEAUT_TIMER=y
CONFIG_MSC313E_TIMER=y
CONFIG_INGENIC_TIMER=y
CONFIG_INGENIC_SYSOST=y
CONFIG_INGENIC_OST=y
CONFIG_MICROCHIP_PIT64B=y
CONFIG_GOLDFISH_TIMER=y
# end of Clock Source drivers
CONFIG_MAILBOX=y
CONFIG_ARM_MHU=y
CONFIG_ARM_MHU_V2=y
CONFIG_IMX_MBOX=y
CONFIG_PLATFORM_MHU=y
CONFIG_PL320_MBOX=y
CONFIG_ARMADA_37XX_RWTM_MBOX=y
CONFIG_OMAP2PLUS_MBOX=y
CONFIG_OMAP_MBOX_KFIFO_SIZE=256
CONFIG_ROCKCHIP_MBOX=y
CONFIG_ALTERA_MBOX=y
CONFIG_BCM2835_MBOX=y
CONFIG_STI_MBOX=y
CONFIG_TI_MESSAGE_MANAGER=y
CONFIG_HI3660_MBOX=y
CONFIG_HI6220_MBOX=y
CONFIG_MAILBOX_TEST=y
CONFIG_POLARFIRE_SOC_MAILBOX=y
CONFIG_QCOM_APCS_IPC=y
CONFIG_TEGRA_HSP_MBOX=y
CONFIG_BCM_PDC_MBOX=y
CONFIG_STM32_IPCC=y
CONFIG_MTK_ADSP_MBOX=y
CONFIG_MTK_CMDQ_MBOX=y
CONFIG_SUN6I_MSGBOX=y
CONFIG_SPRD_MBOX=y
CONFIG_QCOM_IPCC=y
CONFIG_IOMMU_IOVA=y
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
#
# Generic IOMMU Pagetable Support
#
CONFIG_IOMMU_IO_PGTABLE=y
CONFIG_IOMMU_IO_PGTABLE_LPAE=y
CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST=y
CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST=y
# end of Generic IOMMU Pagetable Support
CONFIG_IOMMU_DEBUGFS=y
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_MSM_IOMMU=y
CONFIG_IOMMUFD=y
CONFIG_IOMMUFD_TEST=y
CONFIG_OMAP_IOMMU=y
CONFIG_OMAP_IOMMU_DEBUG=y
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_SUN50I_IOMMU=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_EXYNOS_IOMMU=y
CONFIG_EXYNOS_IOMMU_DEBUG=y
CONFIG_IPMMU_VMSA=y
CONFIG_ARM_SMMU=y
CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS=y
CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
CONFIG_ARM_SMMU_QCOM=y
CONFIG_ARM_SMMU_QCOM_DEBUG=y
CONFIG_S390_CCW_IOMMU=y
CONFIG_S390_AP_IOMMU=y
CONFIG_MTK_IOMMU=y
CONFIG_MTK_IOMMU_V1=y
CONFIG_QCOM_IOMMU=y
CONFIG_SPRD_IOMMU=y
#
# Remoteproc drivers
#
CONFIG_REMOTEPROC=y
CONFIG_REMOTEPROC_CDEV=y
CONFIG_IMX_REMOTEPROC=y
CONFIG_IMX_DSP_REMOTEPROC=y
CONFIG_INGENIC_VPU_RPROC=y
CONFIG_MTK_SCP=y
CONFIG_OMAP_REMOTEPROC=y
CONFIG_OMAP_REMOTEPROC_WATCHDOG=y
CONFIG_WKUP_M3_RPROC=y
CONFIG_KEYSTONE_REMOTEPROC=y
CONFIG_MESON_MX_AO_ARC_REMOTEPROC=y
CONFIG_PRU_REMOTEPROC=y
CONFIG_QCOM_PIL_INFO=y
CONFIG_QCOM_RPROC_COMMON=y
CONFIG_QCOM_Q6V5_COMMON=y
CONFIG_QCOM_Q6V5_ADSP=y
CONFIG_QCOM_Q6V5_MSS=y
CONFIG_QCOM_Q6V5_PAS=y
CONFIG_QCOM_Q6V5_WCSS=y
CONFIG_QCOM_SYSMON=y
CONFIG_QCOM_WCNSS_PIL=y
CONFIG_RCAR_REMOTEPROC=y
CONFIG_ST_REMOTEPROC=y
CONFIG_ST_SLIM_REMOTEPROC=y
CONFIG_STM32_RPROC=y
# end of Remoteproc drivers
#
# Rpmsg drivers
#
CONFIG_RPMSG=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_CTRL=y
CONFIG_RPMSG_NS=y
CONFIG_RPMSG_MTK_SCP=y
CONFIG_RPMSG_QCOM_GLINK=y
CONFIG_RPMSG_QCOM_GLINK_RPM=y
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
CONFIG_RPMSG_QCOM_SMD=y
CONFIG_RPMSG_VIRTIO=y
# end of Rpmsg drivers
CONFIG_SOUNDWIRE=y
#
# SoundWire Devices
#
CONFIG_SOUNDWIRE_QCOM=y
#
# SOC (System On Chip) specific Drivers
#
CONFIG_OWL_PM_DOMAINS_HELPER=y
CONFIG_OWL_PM_DOMAINS=y
#
# Amlogic SoC drivers
#
CONFIG_MESON_CANVAS=y
CONFIG_MESON_CLK_MEASURE=y
CONFIG_MESON_GX_SOCINFO=y
CONFIG_MESON_GX_PM_DOMAINS=y
CONFIG_MESON_EE_PM_DOMAINS=y
CONFIG_MESON_MX_SOCINFO=y
# end of Amlogic SoC drivers
#
# Apple SoC drivers
#
CONFIG_APPLE_PMGR_PWRSTATE=y
CONFIG_APPLE_RTKIT=y
CONFIG_APPLE_SART=y
# end of Apple SoC drivers
#
# ASPEED SoC drivers
#
CONFIG_ASPEED_LPC_CTRL=y
CONFIG_ASPEED_LPC_SNOOP=y
CONFIG_ASPEED_UART_ROUTING=y
CONFIG_ASPEED_P2A_CTRL=y
CONFIG_ASPEED_SOCINFO=y
# end of ASPEED SoC drivers
CONFIG_AT91_SOC_ID=y
CONFIG_AT91_SOC_SFR=y
#
# Broadcom SoC drivers
#
CONFIG_BCM2835_POWER=y
CONFIG_RASPBERRYPI_POWER=y
CONFIG_SOC_BCM63XX=y
CONFIG_SOC_BRCMSTB=y
CONFIG_BCM63XX_POWER=y
CONFIG_BCM_PMB=y
CONFIG_BRCMSTB_PM=y
# end of Broadcom SoC drivers
#
# NXP/Freescale QorIQ SoC drivers
#
CONFIG_QUICC_ENGINE=y
CONFIG_UCC_SLOW=y
CONFIG_UCC_FAST=y
CONFIG_UCC=y
CONFIG_QE_TDM=y
CONFIG_FSL_GUTS=y
CONFIG_FSL_MC_DPIO=y
CONFIG_DPAA2_CONSOLE=y
CONFIG_FSL_RCPM=y
# end of NXP/Freescale QorIQ SoC drivers
#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers
#
# i.MX SoC drivers
#
CONFIG_IMX_GPCV2_PM_DOMAINS=y
CONFIG_SOC_IMX8M=y
CONFIG_SOC_IMX9=y
CONFIG_IMX8M_BLK_CTRL=y
CONFIG_IMX9_BLK_CTRL=y
# end of i.MX SoC drivers
#
# IXP4xx SoC drivers
#
CONFIG_IXP4XX_QMGR=y
CONFIG_IXP4XX_NPE=y
# end of IXP4xx SoC drivers
#
# Enable LiteX SoC Builder specific drivers
#
CONFIG_LITEX=y
CONFIG_LITEX_SOC_CONTROLLER=y
# end of Enable LiteX SoC Builder specific drivers
CONFIG_LOONGSON2_GUTS=y
#
# MediaTek SoC drivers
#
CONFIG_MTK_CMDQ=y
CONFIG_MTK_DEVAPC=y
CONFIG_MTK_INFRACFG=y
CONFIG_MTK_PMIC_WRAP=y
CONFIG_MTK_SCPSYS=y
CONFIG_MTK_SCPSYS_PM_DOMAINS=y
CONFIG_MTK_MMSYS=y
CONFIG_MTK_SVS=y
# end of MediaTek SoC drivers
CONFIG_POLARFIRE_SOC_SYS_CTRL=y
CONFIG_WPCM450_SOC=y
CONFIG_PLAT_PXA=y
CONFIG_PXA_SSP=y
#
# Qualcomm SoC drivers
#
CONFIG_QCOM_AOSS_QMP=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_QCOM_CPR=y
CONFIG_QCOM_CPR_COMMON=y
CONFIG_QCOM_CPR3=y
CONFIG_QCOM_GENI_SE=y
CONFIG_QCOM_GSBI=y
CONFIG_QCOM_LLCC=y
CONFIG_QCOM_DCC=y
CONFIG_QCOM_MDT_LOADER=y
CONFIG_QCOM_OCMEM=y
CONFIG_QCOM_PDR_HELPERS=y
CONFIG_QCOM_QMI_HELPERS=y
CONFIG_QCOM_RAMP_CTRL=y
CONFIG_QCOM_RMTFS_MEM=y
CONFIG_QCOM_RPMH=y
CONFIG_QCOM_RPMHPD=y
CONFIG_QCOM_RPMPD=y
CONFIG_QCOM_SMEM=y
CONFIG_QCOM_SMD_RPM=y
CONFIG_QCOM_SMEM_STATE=y
CONFIG_QCOM_SMP2P=y
CONFIG_QCOM_SMSM=y
CONFIG_QCOM_SOCINFO=y
CONFIG_QCOM_SPM=y
CONFIG_QCOM_STATS=y
CONFIG_QCOM_WCNSS_CTRL=y
CONFIG_QCOM_APR=y
CONFIG_QCOM_ICC_BWMON=y
# end of Qualcomm SoC drivers
CONFIG_SOC_RENESAS=y
CONFIG_ARCH_RCAR_GEN1=y
CONFIG_ARCH_RCAR_GEN2=y
CONFIG_ARCH_RMOBILE=y
CONFIG_ARCH_RZN1=y
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R8A7794=y
CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
CONFIG_ARCH_R8A7778=y
CONFIG_ARCH_R8A7793=y
CONFIG_ARCH_R8A7791=y
CONFIG_ARCH_R8A7792=y
CONFIG_ARCH_R8A7740=y
CONFIG_ARCH_R8A73A4=y
CONFIG_ARCH_R7S72100=y
CONFIG_ARCH_R7S9210=y
CONFIG_ARCH_R8A77470=y
CONFIG_ARCH_R8A7745=y
CONFIG_ARCH_R8A7742=y
CONFIG_ARCH_R8A7743=y
CONFIG_ARCH_R8A7744=y
CONFIG_ARCH_R9A06G032=y
CONFIG_ARCH_SH73A0=y
CONFIG_RST_RCAR=y
CONFIG_SYSC_RCAR=y
CONFIG_SYSC_RCAR_GEN4=y
CONFIG_SYSC_R8A77995=y
CONFIG_SYSC_R8A7794=y
CONFIG_SYSC_R8A77990=y
CONFIG_SYSC_R8A7779=y
CONFIG_SYSC_R8A7790=y
CONFIG_SYSC_R8A7795=y
CONFIG_SYSC_R8A7791=y
CONFIG_SYSC_R8A77965=y
CONFIG_SYSC_R8A77960=y
CONFIG_SYSC_R8A77961=y
CONFIG_SYSC_R8A779F0=y
CONFIG_SYSC_R8A7792=y
CONFIG_SYSC_R8A77980=y
CONFIG_SYSC_R8A77970=y
CONFIG_SYSC_R8A779A0=y
CONFIG_SYSC_R8A779G0=y
CONFIG_SYSC_RMOBILE=y
CONFIG_SYSC_R8A77470=y
CONFIG_SYSC_R8A7745=y
CONFIG_SYSC_R8A7742=y
CONFIG_SYSC_R8A7743=y
CONFIG_SYSC_R8A774C0=y
CONFIG_SYSC_R8A774E1=y
CONFIG_SYSC_R8A774A1=y
CONFIG_SYSC_R8A774B1=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ROCKCHIP_DTPM=m
CONFIG_SOC_SAMSUNG=y
CONFIG_EXYNOS_ASV_ARM=y
CONFIG_EXYNOS_CHIPID=y
CONFIG_EXYNOS_USI=y
CONFIG_EXYNOS_PMU=y
CONFIG_EXYNOS_PMU_ARM_DRIVERS=y
CONFIG_EXYNOS_PM_DOMAINS=y
CONFIG_SAMSUNG_PM_CHECK=y
CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE=64
CONFIG_EXYNOS_REGULATOR_COUPLER=y
CONFIG_SUNXI_MBUS=y
CONFIG_SUNXI_SRAM=y
CONFIG_ARCH_TEGRA_2x_SOC=y
CONFIG_ARCH_TEGRA_3x_SOC=y
CONFIG_ARCH_TEGRA_114_SOC=y
CONFIG_ARCH_TEGRA_124_SOC=y
CONFIG_SOC_TEGRA_FUSE=y
CONFIG_SOC_TEGRA_FLOWCTRL=y
CONFIG_SOC_TEGRA_PMC=y
CONFIG_SOC_TEGRA_POWERGATE_BPMP=y
CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER=y
CONFIG_SOC_TI=y
CONFIG_KEYSTONE_NAVIGATOR_QMSS=y
CONFIG_KEYSTONE_NAVIGATOR_DMA=y
CONFIG_AMX3_PM=y
CONFIG_WKUP_M3_IPC=y
CONFIG_TI_SCI_PM_DOMAINS=y
CONFIG_TI_PRUSS=y
CONFIG_UX500_SOC_ID=y
CONFIG_SOC_INTEGRATOR_CM=y
CONFIG_SOC_REALVIEW=y
#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers
CONFIG_PM_DEVFREQ=y
#
# DEVFREQ Governors
#
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_POWERSAVE=y
CONFIG_DEVFREQ_GOV_USERSPACE=y
CONFIG_DEVFREQ_GOV_PASSIVE=y
#
# DEVFREQ Drivers
#
CONFIG_ARM_EXYNOS_BUS_DEVFREQ=y
CONFIG_ARM_IMX_BUS_DEVFREQ=y
CONFIG_ARM_IMX8M_DDRC_DEVFREQ=y
CONFIG_ARM_TEGRA_DEVFREQ=y
CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=y
CONFIG_ARM_RK3399_DMC_DEVFREQ=y
CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=y
CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
CONFIG_EXTCON=y
#
# Extcon Device Drivers
#
CONFIG_EXTCON_ADC_JACK=y
CONFIG_EXTCON_FSA9480=y
CONFIG_EXTCON_GPIO=y
CONFIG_EXTCON_MAX14577=y
CONFIG_EXTCON_MAX3355=y
CONFIG_EXTCON_MAX77693=y
CONFIG_EXTCON_MAX77843=y
CONFIG_EXTCON_MAX8997=y
CONFIG_EXTCON_PALMAS=y
CONFIG_EXTCON_PTN5150=y
CONFIG_EXTCON_QCOM_SPMI_MISC=y
CONFIG_EXTCON_RT8973A=y
CONFIG_EXTCON_SM5502=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_EXTCON_USBC_CROS_EC=y
CONFIG_EXTCON_USBC_TUSB320=y
CONFIG_MEMORY=y
CONFIG_DDR=y
CONFIG_ARM_PL172_MPMC=y
CONFIG_ATMEL_SDRAMC=y
CONFIG_ATMEL_EBI=y
CONFIG_BRCMSTB_DPFE=y
CONFIG_BRCMSTB_MEMC=y
CONFIG_BT1_L2_CTL=y
CONFIG_TI_AEMIF=y
CONFIG_TI_EMIF=y
CONFIG_OMAP_GPMC=y
CONFIG_OMAP_GPMC_DEBUG=y
CONFIG_TI_EMIF_SRAM=y
CONFIG_FPGA_DFL_EMIF=y
CONFIG_MVEBU_DEVBUS=y
CONFIG_FSL_CORENET_CF=y
CONFIG_FSL_IFC=y
CONFIG_JZ4780_NEMC=y
CONFIG_MTK_SMI=y
CONFIG_DA8XX_DDRCTL=y
CONFIG_PL353_SMC=y
CONFIG_RENESAS_RPCIF=y
CONFIG_STM32_FMC2_EBI=y
CONFIG_SAMSUNG_MC=y
CONFIG_EXYNOS5422_DMC=y
CONFIG_EXYNOS_SROM=y
CONFIG_TEGRA_MC=y
CONFIG_TEGRA20_EMC=y
CONFIG_TEGRA30_EMC=y
CONFIG_TEGRA124_EMC=y
CONFIG_TEGRA210_EMC_TABLE=y
CONFIG_TEGRA210_EMC=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=y
CONFIG_IIO_BUFFER_DMA=y
CONFIG_IIO_BUFFER_DMAENGINE=y
CONFIG_IIO_BUFFER_HW_CONSUMER=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_TRIGGERED_BUFFER=y
CONFIG_IIO_CONFIGFS=y
CONFIG_IIO_TRIGGER=y
CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
CONFIG_IIO_SW_DEVICE=y
CONFIG_IIO_SW_TRIGGER=y
CONFIG_IIO_TRIGGERED_EVENT=y
#
# Accelerometers
#
CONFIG_ADIS16201=y
CONFIG_ADIS16209=y
CONFIG_ADXL313=y
CONFIG_ADXL313_I2C=y
CONFIG_ADXL313_SPI=y
CONFIG_ADXL355=y
CONFIG_ADXL355_I2C=y
CONFIG_ADXL355_SPI=y
CONFIG_ADXL367=y
CONFIG_ADXL367_SPI=y
CONFIG_ADXL367_I2C=y
CONFIG_ADXL372=y
CONFIG_ADXL372_SPI=y
CONFIG_ADXL372_I2C=y
CONFIG_BMA220=y
CONFIG_BMA400=y
CONFIG_BMA400_I2C=y
CONFIG_BMA400_SPI=y
CONFIG_BMC150_ACCEL=y
CONFIG_BMC150_ACCEL_I2C=y
CONFIG_BMC150_ACCEL_SPI=y
CONFIG_BMI088_ACCEL=y
CONFIG_BMI088_ACCEL_SPI=y
CONFIG_DA280=y
CONFIG_DA311=y
CONFIG_DMARD06=y
CONFIG_DMARD09=y
CONFIG_DMARD10=y
CONFIG_FXLS8962AF=y
CONFIG_FXLS8962AF_I2C=y
CONFIG_FXLS8962AF_SPI=y
CONFIG_HID_SENSOR_ACCEL_3D=y
CONFIG_IIO_CROS_EC_ACCEL_LEGACY=y
CONFIG_IIO_KX022A=y
CONFIG_IIO_KX022A_SPI=y
CONFIG_IIO_KX022A_I2C=y
CONFIG_KXSD9=y
CONFIG_KXSD9_SPI=y
CONFIG_KXSD9_I2C=y
CONFIG_KXCJK1013=y
CONFIG_MC3230=y
CONFIG_MMA7455=y
CONFIG_MMA7455_I2C=y
CONFIG_MMA7455_SPI=y
CONFIG_MMA7660=y
CONFIG_MMA8452=y
CONFIG_MMA9551_CORE=y
CONFIG_MMA9551=y
CONFIG_MMA9553=y
CONFIG_MSA311=y
CONFIG_MXC4005=y
CONFIG_MXC6255=y
CONFIG_SCA3000=y
CONFIG_SCA3300=y
CONFIG_STK8312=y
CONFIG_STK8BA50=y
# end of Accelerometers
#
# Analog to digital converters
#
CONFIG_AB8500_GPADC=y
CONFIG_AD_SIGMA_DELTA=y
CONFIG_AD4130=y
CONFIG_AD7091R5=y
CONFIG_AD7124=y
CONFIG_AD7192=y
CONFIG_AD7266=y
CONFIG_AD7280=y
CONFIG_AD7291=y
CONFIG_AD7292=y
CONFIG_AD7298=y
CONFIG_AD7476=y
CONFIG_AD7606=y
CONFIG_AD7606_IFACE_PARALLEL=y
CONFIG_AD7606_IFACE_SPI=y
CONFIG_AD7766=y
CONFIG_AD7768_1=y
CONFIG_AD7780=y
CONFIG_AD7791=y
CONFIG_AD7793=y
CONFIG_AD7887=y
CONFIG_AD7923=y
CONFIG_AD7949=y
CONFIG_AD799X=y
CONFIG_AD9467=y
CONFIG_ADI_AXI_ADC=y
CONFIG_ASPEED_ADC=y
CONFIG_AT91_ADC=y
CONFIG_AT91_SAMA5D2_ADC=y
CONFIG_AXP20X_ADC=y
CONFIG_AXP288_ADC=y
CONFIG_BCM_IPROC_ADC=y
CONFIG_BERLIN2_ADC=y
CONFIG_CC10001_ADC=y
CONFIG_CPCAP_ADC=y
CONFIG_DA9150_GPADC=y
CONFIG_DLN2_ADC=y
CONFIG_ENVELOPE_DETECTOR=y
CONFIG_EXYNOS_ADC=y
CONFIG_MXS_LRADC_ADC=y
CONFIG_FSL_MX25_ADC=y
CONFIG_HI8435=y
CONFIG_HX711=y
CONFIG_INGENIC_ADC=y
CONFIG_IMX7D_ADC=y
CONFIG_IMX8QXP_ADC=y
CONFIG_LP8788_ADC=y
CONFIG_LPC18XX_ADC=y
CONFIG_LPC32XX_ADC=y
CONFIG_LTC2471=y
CONFIG_LTC2485=y
CONFIG_LTC2496=y
CONFIG_LTC2497=y
CONFIG_MAX1027=y
CONFIG_MAX11100=y
CONFIG_MAX1118=y
CONFIG_MAX11205=y
CONFIG_MAX11410=y
CONFIG_MAX1241=y
CONFIG_MAX1363=y
CONFIG_MAX9611=y
CONFIG_MCP320X=y
CONFIG_MCP3422=y
CONFIG_MCP3911=y
CONFIG_MEDIATEK_MT6360_ADC=y
CONFIG_MEDIATEK_MT6370_ADC=y
CONFIG_MEDIATEK_MT6577_AUXADC=y
CONFIG_MEN_Z188_ADC=y
CONFIG_MESON_SARADC=y
CONFIG_MP2629_ADC=y
CONFIG_NAU7802=y
CONFIG_NPCM_ADC=y
CONFIG_PALMAS_GPADC=y
CONFIG_QCOM_VADC_COMMON=y
CONFIG_QCOM_PM8XXX_XOADC=y
CONFIG_QCOM_SPMI_RRADC=y
CONFIG_QCOM_SPMI_IADC=y
CONFIG_QCOM_SPMI_VADC=y
CONFIG_QCOM_SPMI_ADC5=y
CONFIG_RCAR_GYRO_ADC=y
CONFIG_RN5T618_ADC=y
CONFIG_ROCKCHIP_SARADC=y
CONFIG_RICHTEK_RTQ6056=y
CONFIG_RZG2L_ADC=y
CONFIG_SC27XX_ADC=y
CONFIG_SPEAR_ADC=y
CONFIG_SD_ADC_MODULATOR=y
CONFIG_STM32_ADC_CORE=y
CONFIG_STM32_ADC=y
CONFIG_STM32_DFSDM_CORE=y
CONFIG_STM32_DFSDM_ADC=y
CONFIG_STMPE_ADC=y
CONFIG_SUN4I_GPADC=y
CONFIG_TI_ADC081C=y
CONFIG_TI_ADC0832=y
CONFIG_TI_ADC084S021=y
CONFIG_TI_ADC12138=y
CONFIG_TI_ADC108S102=y
CONFIG_TI_ADC128S052=y
CONFIG_TI_ADC161S626=y
CONFIG_TI_ADS1015=y
CONFIG_TI_ADS7950=y
CONFIG_TI_ADS8344=y
CONFIG_TI_ADS8688=y
CONFIG_TI_ADS124S08=y
CONFIG_TI_ADS131E08=y
CONFIG_TI_AM335X_ADC=y
CONFIG_TI_LMP92064=y
CONFIG_TI_TLC4541=y
CONFIG_TI_TSC2046=y
CONFIG_TWL4030_MADC=y
CONFIG_TWL6030_GPADC=y
CONFIG_VF610_ADC=y
CONFIG_VIPERBOARD_ADC=y
CONFIG_XILINX_XADC=y
CONFIG_XILINX_AMS=y
# end of Analog to digital converters
#
# Analog to digital and digital to analog converters
#
CONFIG_AD74115=y
CONFIG_AD74413R=y
# end of Analog to digital and digital to analog converters
#
# Analog Front Ends
#
CONFIG_IIO_RESCALE=y
# end of Analog Front Ends
#
# Amplifiers
#
CONFIG_AD8366=y
CONFIG_ADA4250=y
CONFIG_HMC425=y
# end of Amplifiers
#
# Capacitance to digital converters
#
CONFIG_AD7150=y
CONFIG_AD7746=y
# end of Capacitance to digital converters
#
# Chemical Sensors
#
CONFIG_ATLAS_PH_SENSOR=y
CONFIG_ATLAS_EZO_SENSOR=y
CONFIG_BME680=y
CONFIG_BME680_I2C=y
CONFIG_BME680_SPI=y
CONFIG_CCS811=y
CONFIG_IAQCORE=y
CONFIG_PMS7003=y
CONFIG_SCD30_CORE=y
CONFIG_SCD30_I2C=y
CONFIG_SCD30_SERIAL=y
CONFIG_SCD4X=y
CONFIG_SENSIRION_SGP30=y
CONFIG_SENSIRION_SGP40=y
CONFIG_SPS30=y
CONFIG_SPS30_I2C=y
CONFIG_SPS30_SERIAL=y
CONFIG_SENSEAIR_SUNRISE_CO2=y
CONFIG_VZ89X=y
# end of Chemical Sensors
CONFIG_IIO_CROS_EC_SENSORS_CORE=y
CONFIG_IIO_CROS_EC_SENSORS=y
CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=y
#
# Hid Sensor IIO Common
#
CONFIG_HID_SENSOR_IIO_COMMON=y
CONFIG_HID_SENSOR_IIO_TRIGGER=y
# end of Hid Sensor IIO Common
CONFIG_IIO_MS_SENSORS_I2C=y
#
# IIO SCMI Sensors
#
CONFIG_IIO_SCMI=y
# end of IIO SCMI Sensors
#
# SSP Sensor Common
#
CONFIG_IIO_SSP_SENSORS_COMMONS=y
CONFIG_IIO_SSP_SENSORHUB=y
# end of SSP Sensor Common
CONFIG_IIO_ST_SENSORS_I2C=y
CONFIG_IIO_ST_SENSORS_SPI=y
CONFIG_IIO_ST_SENSORS_CORE=y
#
# Digital to analog converters
#
CONFIG_AD3552R=y
CONFIG_AD5064=y
CONFIG_AD5360=y
CONFIG_AD5380=y
CONFIG_AD5421=y
CONFIG_AD5446=y
CONFIG_AD5449=y
CONFIG_AD5592R_BASE=y
CONFIG_AD5592R=y
CONFIG_AD5593R=y
CONFIG_AD5504=y
CONFIG_AD5624R_SPI=y
CONFIG_LTC2688=y
CONFIG_AD5686=y
CONFIG_AD5686_SPI=y
CONFIG_AD5696_I2C=y
CONFIG_AD5755=y
CONFIG_AD5758=y
CONFIG_AD5761=y
CONFIG_AD5764=y
CONFIG_AD5766=y
CONFIG_AD5770R=y
CONFIG_AD5791=y
CONFIG_AD7293=y
CONFIG_AD7303=y
CONFIG_AD8801=y
CONFIG_DPOT_DAC=y
CONFIG_DS4424=y
CONFIG_LPC18XX_DAC=y
CONFIG_LTC1660=y
CONFIG_LTC2632=y
CONFIG_M62332=y
CONFIG_MAX517=y
CONFIG_MAX5821=y
CONFIG_MCP4725=y
CONFIG_MCP4922=y
CONFIG_STM32_DAC=y
CONFIG_STM32_DAC_CORE=y
CONFIG_TI_DAC082S085=y
CONFIG_TI_DAC5571=y
CONFIG_TI_DAC7311=y
CONFIG_TI_DAC7612=y
CONFIG_VF610_DAC=y
# end of Digital to analog converters
#
# IIO dummy driver
#
CONFIG_IIO_DUMMY_EVGEN=y
CONFIG_IIO_SIMPLE_DUMMY=y
CONFIG_IIO_SIMPLE_DUMMY_EVENTS=y
CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y
# end of IIO dummy driver
#
# Filters
#
# end of Filters
#
# Frequency Synthesizers DDS/PLL
#
#
# Clock Generator/Distribution
#
CONFIG_AD9523=y
# end of Clock Generator/Distribution
#
# Phase-Locked Loop (PLL) frequency synthesizers
#
CONFIG_ADF4350=y
CONFIG_ADF4371=y
CONFIG_ADF4377=y
CONFIG_ADMV1013=y
CONFIG_ADMV4420=y
CONFIG_ADRF6780=y
# end of Phase-Locked Loop (PLL) frequency synthesizers
# end of Frequency Synthesizers DDS/PLL
#
# Digital gyroscope sensors
#
CONFIG_ADIS16080=y
CONFIG_ADIS16130=y
CONFIG_ADIS16136=y
CONFIG_ADIS16260=y
CONFIG_ADXRS290=y
CONFIG_ADXRS450=y
CONFIG_BMG160=y
CONFIG_BMG160_I2C=y
CONFIG_BMG160_SPI=y
CONFIG_FXAS21002C=y
CONFIG_FXAS21002C_I2C=y
CONFIG_FXAS21002C_SPI=y
CONFIG_HID_SENSOR_GYRO_3D=y
CONFIG_MPU3050=y
CONFIG_MPU3050_I2C=y
CONFIG_IIO_ST_GYRO_3AXIS=y
CONFIG_IIO_ST_GYRO_I2C_3AXIS=y
CONFIG_IIO_ST_GYRO_SPI_3AXIS=y
CONFIG_ITG3200=y
# end of Digital gyroscope sensors
#
# Health Sensors
#
#
# Heart Rate Monitors
#
CONFIG_AFE4403=y
CONFIG_AFE4404=y
CONFIG_MAX30100=y
CONFIG_MAX30102=y
# end of Heart Rate Monitors
# end of Health Sensors
#
# Humidity sensors
#
CONFIG_AM2315=y
CONFIG_DHT11=y
CONFIG_HDC100X=y
CONFIG_HDC2010=y
CONFIG_HID_SENSOR_HUMIDITY=y
CONFIG_HTS221=y
CONFIG_HTS221_I2C=y
CONFIG_HTS221_SPI=y
CONFIG_HTU21=y
CONFIG_SI7005=y
CONFIG_SI7020=y
# end of Humidity sensors
#
# Inertial measurement units
#
CONFIG_ADIS16400=y
CONFIG_ADIS16460=y
CONFIG_ADIS16475=y
CONFIG_ADIS16480=y
CONFIG_BMI160=y
CONFIG_BMI160_I2C=y
CONFIG_BMI160_SPI=y
CONFIG_BOSCH_BNO055=y
CONFIG_BOSCH_BNO055_SERIAL=y
CONFIG_BOSCH_BNO055_I2C=y
CONFIG_FXOS8700=y
CONFIG_FXOS8700_I2C=y
CONFIG_FXOS8700_SPI=y
CONFIG_KMX61=y
CONFIG_INV_ICM42600=y
CONFIG_INV_ICM42600_I2C=y
CONFIG_INV_ICM42600_SPI=y
CONFIG_INV_MPU6050_IIO=y
CONFIG_INV_MPU6050_I2C=y
CONFIG_INV_MPU6050_SPI=y
CONFIG_IIO_ST_LSM6DSX=y
CONFIG_IIO_ST_LSM6DSX_I2C=y
CONFIG_IIO_ST_LSM6DSX_SPI=y
CONFIG_IIO_ST_LSM6DSX_I3C=y
# end of Inertial measurement units
CONFIG_IIO_ADIS_LIB=y
CONFIG_IIO_ADIS_LIB_BUFFER=y
#
# Light sensors
#
CONFIG_ADJD_S311=y
CONFIG_ADUX1020=y
CONFIG_AL3010=y
CONFIG_AL3320A=y
CONFIG_APDS9300=y
CONFIG_APDS9960=y
CONFIG_AS73211=y
CONFIG_BH1750=y
CONFIG_BH1780=y
CONFIG_CM32181=y
CONFIG_CM3232=y
CONFIG_CM3323=y
CONFIG_CM3605=y
CONFIG_CM36651=y
CONFIG_IIO_CROS_EC_LIGHT_PROX=y
CONFIG_GP2AP002=y
CONFIG_GP2AP020A00F=y
CONFIG_IQS621_ALS=y
CONFIG_SENSORS_ISL29018=y
CONFIG_SENSORS_ISL29028=y
CONFIG_ISL29125=y
CONFIG_HID_SENSOR_ALS=y
CONFIG_HID_SENSOR_PROX=y
CONFIG_JSA1212=y
CONFIG_RPR0521=y
CONFIG_SENSORS_LM3533=y
CONFIG_LTR501=y
CONFIG_LTRF216A=y
CONFIG_LV0104CS=y
CONFIG_MAX44000=y
CONFIG_MAX44009=y
CONFIG_NOA1305=y
CONFIG_OPT3001=y
CONFIG_PA12203001=y
CONFIG_SI1133=y
CONFIG_SI1145=y
CONFIG_STK3310=y
CONFIG_ST_UVIS25=y
CONFIG_ST_UVIS25_I2C=y
CONFIG_ST_UVIS25_SPI=y
CONFIG_TCS3414=y
CONFIG_TCS3472=y
CONFIG_SENSORS_TSL2563=y
CONFIG_TSL2583=y
CONFIG_TSL2591=y
CONFIG_TSL2772=y
CONFIG_TSL4531=y
CONFIG_US5182D=y
CONFIG_VCNL4000=y
CONFIG_VCNL4035=y
CONFIG_VEML6030=y
CONFIG_VEML6070=y
CONFIG_VL6180=y
CONFIG_ZOPT2201=y
# end of Light sensors
#
# Magnetometer sensors
#
CONFIG_AK8974=y
CONFIG_AK8975=y
CONFIG_AK09911=y
CONFIG_BMC150_MAGN=y
CONFIG_BMC150_MAGN_I2C=y
CONFIG_BMC150_MAGN_SPI=y
CONFIG_MAG3110=y
CONFIG_HID_SENSOR_MAGNETOMETER_3D=y
CONFIG_MMC35240=y
CONFIG_IIO_ST_MAGN_3AXIS=y
CONFIG_IIO_ST_MAGN_I2C_3AXIS=y
CONFIG_IIO_ST_MAGN_SPI_3AXIS=y
CONFIG_SENSORS_HMC5843=y
CONFIG_SENSORS_HMC5843_I2C=y
CONFIG_SENSORS_HMC5843_SPI=y
CONFIG_SENSORS_RM3100=y
CONFIG_SENSORS_RM3100_I2C=y
CONFIG_SENSORS_RM3100_SPI=y
CONFIG_TI_TMAG5273=y
CONFIG_YAMAHA_YAS530=y
# end of Magnetometer sensors
#
# Multiplexers
#
CONFIG_IIO_MUX=y
# end of Multiplexers
#
# Inclinometer sensors
#
CONFIG_HID_SENSOR_INCLINOMETER_3D=y
CONFIG_HID_SENSOR_DEVICE_ROTATION=y
# end of Inclinometer sensors
CONFIG_IIO_RESCALE_KUNIT_TEST=y
CONFIG_IIO_FORMAT_KUNIT_TEST=y
#
# Triggers - standalone
#
CONFIG_IIO_HRTIMER_TRIGGER=y
CONFIG_IIO_INTERRUPT_TRIGGER=y
CONFIG_IIO_STM32_LPTIMER_TRIGGER=y
CONFIG_IIO_STM32_TIMER_TRIGGER=y
CONFIG_IIO_TIGHTLOOP_TRIGGER=y
CONFIG_IIO_SYSFS_TRIGGER=y
# end of Triggers - standalone
#
# Linear and angular position sensors
#
CONFIG_IQS624_POS=y
CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=y
# end of Linear and angular position sensors
#
# Digital potentiometers
#
CONFIG_AD5110=y
CONFIG_AD5272=y
CONFIG_DS1803=y
CONFIG_MAX5432=y
CONFIG_MAX5481=y
CONFIG_MAX5487=y
CONFIG_MCP4018=y
CONFIG_MCP4131=y
CONFIG_MCP4531=y
CONFIG_MCP41010=y
CONFIG_TPL0102=y
# end of Digital potentiometers
#
# Digital potentiostats
#
CONFIG_LMP91000=y
# end of Digital potentiostats
#
# Pressure sensors
#
CONFIG_ABP060MG=y
CONFIG_BMP280=y
CONFIG_BMP280_I2C=y
CONFIG_BMP280_SPI=y
CONFIG_IIO_CROS_EC_BARO=y
CONFIG_DLHL60D=y
CONFIG_DPS310=y
CONFIG_HID_SENSOR_PRESS=y
CONFIG_HP03=y
CONFIG_ICP10100=y
CONFIG_MPL115=y
CONFIG_MPL115_I2C=y
CONFIG_MPL115_SPI=y
CONFIG_MPL3115=y
CONFIG_MS5611=y
CONFIG_MS5611_I2C=y
CONFIG_MS5611_SPI=y
CONFIG_MS5637=y
CONFIG_IIO_ST_PRESS=y
CONFIG_IIO_ST_PRESS_I2C=y
CONFIG_IIO_ST_PRESS_SPI=y
CONFIG_T5403=y
CONFIG_HP206C=y
CONFIG_ZPA2326=y
CONFIG_ZPA2326_I2C=y
CONFIG_ZPA2326_SPI=y
# end of Pressure sensors
#
# Lightning sensors
#
CONFIG_AS3935=y
# end of Lightning sensors
#
# Proximity and distance sensors
#
CONFIG_CROS_EC_MKBP_PROXIMITY=y
CONFIG_ISL29501=y
CONFIG_LIDAR_LITE_V2=y
CONFIG_MB1232=y
CONFIG_PING=y
CONFIG_RFD77402=y
CONFIG_SRF04=y
CONFIG_SX_COMMON=y
CONFIG_SX9310=y
CONFIG_SX9324=y
CONFIG_SX9360=y
CONFIG_SX9500=y
CONFIG_SRF08=y
CONFIG_VCNL3020=y
CONFIG_VL53L0X_I2C=y
# end of Proximity and distance sensors
#
# Resolver to digital converters
#
CONFIG_AD2S90=y
CONFIG_AD2S1200=y
# end of Resolver to digital converters
#
# Temperature sensors
#
CONFIG_IQS620AT_TEMP=y
CONFIG_LTC2983=y
CONFIG_MAXIM_THERMOCOUPLE=y
CONFIG_HID_SENSOR_TEMP=y
CONFIG_MLX90614=y
CONFIG_MLX90632=y
CONFIG_TMP006=y
CONFIG_TMP007=y
CONFIG_TMP117=y
CONFIG_TSYS01=y
CONFIG_TSYS02D=y
CONFIG_MAX30208=y
CONFIG_MAX31856=y
CONFIG_MAX31865=y
# end of Temperature sensors
CONFIG_NTB=y
CONFIG_NTB_MSI=y
CONFIG_NTB_IDT=y
CONFIG_NTB_EPF=m
CONFIG_NTB_SWITCHTEC=y
CONFIG_NTB_PINGPONG=y
CONFIG_NTB_TOOL=y
CONFIG_NTB_PERF=y
CONFIG_NTB_MSI_TEST=y
CONFIG_NTB_TRANSPORT=y
CONFIG_PWM=y
CONFIG_PWM_SYSFS=y
CONFIG_PWM_DEBUG=y
CONFIG_PWM_AB8500=y
CONFIG_PWM_ATMEL=y
CONFIG_PWM_ATMEL_HLCDC_PWM=y
CONFIG_PWM_ATMEL_TCB=y
CONFIG_PWM_BCM_IPROC=y
CONFIG_PWM_BCM_KONA=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_BERLIN=y
CONFIG_PWM_BRCMSTB=y
CONFIG_PWM_CLK=y
CONFIG_PWM_CLPS711X=y
CONFIG_PWM_CROS_EC=y
CONFIG_PWM_DWC=y
CONFIG_PWM_EP93XX=y
CONFIG_PWM_FSL_FTM=y
CONFIG_PWM_HIBVT=y
CONFIG_PWM_IMG=y
CONFIG_PWM_IMX1=y
CONFIG_PWM_IMX27=y
CONFIG_PWM_IMX_TPM=y
CONFIG_PWM_INTEL_LGM=y
CONFIG_PWM_IQS620A=y
CONFIG_PWM_JZ4740=y
CONFIG_PWM_KEEMBAY=y
CONFIG_PWM_LP3943=y
CONFIG_PWM_LPC18XX_SCT=y
CONFIG_PWM_LPC32XX=y
CONFIG_PWM_LPSS=y
CONFIG_PWM_LPSS_PCI=y
CONFIG_PWM_LPSS_PLATFORM=y
CONFIG_PWM_MESON=y
CONFIG_PWM_MTK_DISP=y
CONFIG_PWM_MEDIATEK=y
CONFIG_PWM_MXS=y
CONFIG_PWM_NTXEC=y
CONFIG_PWM_OMAP_DMTIMER=y
CONFIG_PWM_PCA9685=y
CONFIG_PWM_PXA=y
CONFIG_PWM_RASPBERRYPI_POE=y
CONFIG_PWM_RCAR=y
CONFIG_PWM_RENESAS_TPU=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_PWM_SAMSUNG=y
CONFIG_PWM_SIFIVE=y
CONFIG_PWM_SL28CPLD=y
CONFIG_PWM_SPEAR=y
CONFIG_PWM_SPRD=y
CONFIG_PWM_STI=y
CONFIG_PWM_STM32=y
CONFIG_PWM_STM32_LP=y
CONFIG_PWM_STMPE=y
CONFIG_PWM_SUN4I=y
CONFIG_PWM_SUNPLUS=y
CONFIG_PWM_TEGRA=y
CONFIG_PWM_TIECAP=y
CONFIG_PWM_TIEHRPWM=y
CONFIG_PWM_TWL=y
CONFIG_PWM_TWL_LED=y
CONFIG_PWM_VISCONTI=y
CONFIG_PWM_VT8500=y
CONFIG_PWM_XILINX=y
#
# IRQ chip support
#
CONFIG_IRQCHIP=y
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_MAX_NR=2
CONFIG_ARM_GIC_V2M=y
CONFIG_GIC_NON_BANKED=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_GIC_V3_ITS_PCI=y
CONFIG_ARM_GIC_V3_ITS_FSL_MC=y
CONFIG_ARM_VIC=y
CONFIG_ARM_VIC_NR=4
CONFIG_ARMADA_370_XP_IRQ=y
CONFIG_ALPINE_MSI=y
CONFIG_AL_FIC=y
CONFIG_ATMEL_AIC5_IRQ=y
CONFIG_BCM7038_L1_IRQ=y
CONFIG_BCM7120_L2_IRQ=y
CONFIG_BRCMSTB_L2_IRQ=y
CONFIG_DW_APB_ICTL=y
CONFIG_MADERA_IRQ=y
CONFIG_OMAP_IRQCHIP=y
CONFIG_ORION_IRQCHIP=y
CONFIG_JCORE_AIC=y
CONFIG_RDA_INTC=y
CONFIG_RENESAS_INTC_IRQPIN=y
CONFIG_RENESAS_IRQC=y
CONFIG_RENESAS_RZA1_IRQC=y
CONFIG_RENESAS_RZG2L_IRQC=y
CONFIG_SL28CPLD_INTC=y
CONFIG_ST_IRQCHIP=y
CONFIG_SUN4I_INTC=y
CONFIG_SUN6I_R_INTC=y
CONFIG_SUNXI_NMI_INTC=y
CONFIG_TS4800_IRQ=y
CONFIG_VERSATILE_FPGA_IRQ=y
CONFIG_VERSATILE_FPGA_IRQ_NR=4
CONFIG_XILINX_INTC=y
CONFIG_IRQ_CROSSBAR=y
CONFIG_KEYSTONE_IRQ=y
CONFIG_INGENIC_TCU_IRQ=y
CONFIG_IMX_GPCV2=y
CONFIG_LS_EXTIRQ=y
CONFIG_LS_SCFG_MSI=y
CONFIG_PARTITION_PERCPU=y
CONFIG_STM32_EXTI=y
CONFIG_IRQ_UNIPHIER_AIDET=y
CONFIG_MESON_IRQ_GPIO=y
CONFIG_QCOM_PDC=y
CONFIG_QCOM_MPM=y
CONFIG_IMX_IRQSTEER=y
CONFIG_IMX_INTMUX=y
CONFIG_IMX_MU_MSI=y
CONFIG_TI_PRUSS_INTC=y
CONFIG_EXYNOS_IRQ_COMBINER=y
CONFIG_MST_IRQ=y
CONFIG_MCHP_EIC=y
CONFIG_SUNPLUS_SP7021_INTC=y
# end of IRQ chip support
CONFIG_IPACK_BUS=y
CONFIG_BOARD_TPCI200=y
CONFIG_SERIAL_IPOCTAL=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_A10SR=y
CONFIG_RESET_ATH79=y
CONFIG_RESET_AXS10X=y
CONFIG_RESET_BCM6345=y
CONFIG_RESET_BERLIN=y
CONFIG_RESET_BRCMSTB=y
CONFIG_RESET_BRCMSTB_RESCAL=y
CONFIG_RESET_HSDK=y
CONFIG_RESET_IMX7=y
CONFIG_RESET_INTEL_GW=y
CONFIG_RESET_K210=y
CONFIG_RESET_LANTIQ=y
CONFIG_RESET_LPC18XX=y
CONFIG_RESET_MCHP_SPARX5=y
CONFIG_RESET_MESON=y
CONFIG_RESET_MESON_AUDIO_ARB=y
CONFIG_RESET_NPCM=y
CONFIG_RESET_OXNAS=y
CONFIG_RESET_PISTACHIO=y
CONFIG_RESET_POLARFIRE_SOC=y
CONFIG_RESET_QCOM_AOSS=y
CONFIG_RESET_QCOM_PDC=y
CONFIG_RESET_RASPBERRYPI=y
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
CONFIG_RESET_SCMI=y
CONFIG_RESET_SIMPLE=y
CONFIG_RESET_SOCFPGA=y
CONFIG_RESET_STARFIVE_JH7100=y
CONFIG_RESET_SUNPLUS=y
CONFIG_RESET_SUNXI=y
CONFIG_RESET_TI_SCI=y
CONFIG_RESET_TI_SYSCON=y
CONFIG_RESET_TI_TPS380X=y
CONFIG_RESET_TN48M_CPLD=y
CONFIG_RESET_UNIPHIER=y
CONFIG_RESET_UNIPHIER_GLUE=y
CONFIG_RESET_ZYNQ=y
CONFIG_STI_RESET_SYSCFG=y
CONFIG_STIH407_RESET=y
CONFIG_COMMON_RESET_HI3660=y
CONFIG_COMMON_RESET_HI6220=y
CONFIG_RESET_TEGRA_BPMP=y
#
# PHY Subsystem
#
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PHY_MIPI_DPHY=y
CONFIG_PHY_LPC18XX_USB_OTG=y
CONFIG_PHY_PISTACHIO_USB=y
CONFIG_PHY_XGENE=y
CONFIG_USB_LGM_PHY=y
CONFIG_PHY_CAN_TRANSCEIVER=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN6I_MIPI_DPHY=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SUN50I_USB3=y
CONFIG_PHY_MESON8_HDMI_TX=y
CONFIG_PHY_MESON8B_USB2=y
CONFIG_PHY_MESON_GXL_USB2=y
CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG=y
CONFIG_PHY_MESON_G12A_USB2=y
CONFIG_PHY_MESON_G12A_USB3_PCIE=y
CONFIG_PHY_MESON_AXG_PCIE=y
CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y
CONFIG_PHY_MESON_AXG_MIPI_DPHY=y
#
# PHY drivers for Broadcom platforms
#
CONFIG_PHY_BCM63XX_USBH=y
CONFIG_PHY_CYGNUS_PCIE=y
CONFIG_PHY_BCM_SR_USB=y
CONFIG_BCM_KONA_USB2_PHY=y
CONFIG_PHY_BCM_NS_USB2=y
CONFIG_PHY_BCM_NS_USB3=y
CONFIG_PHY_NS2_PCIE=y
CONFIG_PHY_NS2_USB_DRD=y
CONFIG_PHY_BRCM_SATA=y
CONFIG_PHY_BRCM_USB=y
CONFIG_PHY_BCM_SR_PCIE=y
# end of PHY drivers for Broadcom platforms
CONFIG_PHY_CADENCE_TORRENT=y
CONFIG_PHY_CADENCE_DPHY=y
CONFIG_PHY_CADENCE_DPHY_RX=y
CONFIG_PHY_CADENCE_SIERRA=y
CONFIG_PHY_CADENCE_SALVO=y
CONFIG_PHY_FSL_IMX8MQ_USB=y
CONFIG_PHY_MIXEL_LVDS_PHY=y
CONFIG_PHY_MIXEL_MIPI_DPHY=y
CONFIG_PHY_FSL_IMX8M_PCIE=y
CONFIG_PHY_FSL_LYNX_28G=y
CONFIG_PHY_HI6220_USB=y
CONFIG_PHY_HI3660_USB=y
CONFIG_PHY_HI3670_USB=y
CONFIG_PHY_HI3670_PCIE=y
CONFIG_PHY_HISTB_COMBPHY=y
CONFIG_PHY_HISI_INNO_USB2=y
CONFIG_PHY_HIX5HD2_SATA=y
CONFIG_PHY_INGENIC_USB=y
CONFIG_PHY_LANTIQ_VRX200_PCIE=y
CONFIG_PHY_LANTIQ_RCU_USB2=y
CONFIG_ARMADA375_USBCLUSTER_PHY=y
CONFIG_PHY_BERLIN_SATA=y
CONFIG_PHY_BERLIN_USB=y
CONFIG_PHY_MVEBU_A3700_COMPHY=y
CONFIG_PHY_MVEBU_A3700_UTMI=y
CONFIG_PHY_MVEBU_A38X_COMPHY=y
CONFIG_PHY_MVEBU_CP110_COMPHY=y
CONFIG_PHY_MVEBU_CP110_UTMI=y
CONFIG_PHY_MVEBU_SATA=y
CONFIG_PHY_PXA_28NM_HSIC=y
CONFIG_PHY_PXA_28NM_USB2=y
CONFIG_PHY_PXA_USB=y
CONFIG_PHY_MMP3_USB=y
CONFIG_PHY_MMP3_HSIC=y
CONFIG_PHY_MTK_PCIE=y
CONFIG_PHY_MTK_TPHY=y
CONFIG_PHY_MTK_UFS=y
CONFIG_PHY_MTK_XSPHY=y
CONFIG_PHY_MTK_HDMI=y
CONFIG_PHY_MTK_MIPI_DSI=y
CONFIG_PHY_MTK_DP=y
CONFIG_PHY_SPARX5_SERDES=y
CONFIG_PHY_LAN966X_SERDES=y
CONFIG_PHY_CPCAP_USB=y
CONFIG_PHY_MAPPHONE_MDM6600=y
CONFIG_PHY_OCELOT_SERDES=y
CONFIG_PHY_ATH79_USB=y
CONFIG_PHY_QCOM_APQ8064_SATA=y
CONFIG_PHY_QCOM_EDP=y
CONFIG_PHY_QCOM_IPQ4019_USB=y
CONFIG_PHY_QCOM_IPQ806X_SATA=y
CONFIG_PHY_QCOM_PCIE2=y
CONFIG_PHY_QCOM_QMP=y
CONFIG_PHY_QCOM_QUSB2=y
CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
CONFIG_PHY_QCOM_USB_HSIC=y
CONFIG_PHY_QCOM_USB_HS_28NM=y
CONFIG_PHY_QCOM_USB_SS=y
CONFIG_PHY_QCOM_IPQ806X_USB=y
CONFIG_PHY_MT7621_PCI=y
CONFIG_PHY_RALINK_USB=y
CONFIG_PHY_R8A779F0_ETHERNET_SERDES=y
CONFIG_PHY_RCAR_GEN2=y
CONFIG_PHY_RCAR_GEN3_PCIE=y
CONFIG_PHY_RCAR_GEN3_USB2=y
CONFIG_PHY_RCAR_GEN3_USB3=y
CONFIG_PHY_ROCKCHIP_DP=y
CONFIG_PHY_ROCKCHIP_DPHY_RX0=y
CONFIG_PHY_ROCKCHIP_EMMC=y
CONFIG_PHY_ROCKCHIP_INNO_HDMI=y
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=y
CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y
CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y
CONFIG_PHY_ROCKCHIP_PCIE=y
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PHY_ROCKCHIP_USB=y
CONFIG_PHY_EXYNOS_DP_VIDEO=y
CONFIG_PHY_EXYNOS_MIPI_VIDEO=y
CONFIG_PHY_EXYNOS_PCIE=y
CONFIG_PHY_SAMSUNG_UFS=y
CONFIG_PHY_SAMSUNG_USB2=y
CONFIG_PHY_EXYNOS4210_USB2=y
CONFIG_PHY_EXYNOS4X12_USB2=y
CONFIG_PHY_EXYNOS5250_USB2=y
CONFIG_PHY_S5PV210_USB2=y
CONFIG_PHY_EXYNOS5_USBDRD=y
CONFIG_PHY_EXYNOS5250_SATA=y
CONFIG_PHY_UNIPHIER_USB2=y
CONFIG_PHY_UNIPHIER_USB3=y
CONFIG_PHY_UNIPHIER_PCIE=y
CONFIG_PHY_UNIPHIER_AHCI=y
CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_ST_SPEAR1310_MIPHY=y
CONFIG_PHY_ST_SPEAR1340_MIPHY=y
CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_STM32_USBPHYC=y
CONFIG_PHY_SUNPLUS_USB=y
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_PHY_TEGRA194_P2U=y
CONFIG_PHY_DA8XX_USB=y
CONFIG_PHY_DM816X_USB=y
CONFIG_PHY_AM654_SERDES=y
CONFIG_PHY_J721E_WIZ=y
CONFIG_OMAP_CONTROL_PHY=y
CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
CONFIG_PHY_TUSB1210=y
CONFIG_TWL4030_USB=y
CONFIG_PHY_TI_GMII_SEL=y
CONFIG_PHY_INTEL_KEEMBAY_EMMC=y
CONFIG_PHY_INTEL_KEEMBAY_USB=y
CONFIG_PHY_INTEL_LGM_COMBO=y
CONFIG_PHY_INTEL_LGM_EMMC=y
CONFIG_PHY_INTEL_THUNDERBAY_EMMC=y
CONFIG_PHY_XILINX_ZYNQMP=y
# end of PHY Subsystem
CONFIG_POWERCAP=y
CONFIG_IDLE_INJECT=y
CONFIG_ARM_SCMI_POWERCAP=y
CONFIG_DTPM=y
CONFIG_DTPM_CPU=y
CONFIG_DTPM_DEVFREQ=y
CONFIG_MCB=y
CONFIG_MCB_PCI=y
CONFIG_MCB_LPC=y
#
# Performance monitor support
#
CONFIG_ARM_CCI_PMU=y
CONFIG_ARM_CCI400_PMU=y
CONFIG_ARM_CCI5xx_PMU=y
CONFIG_ARM_CCN=y
CONFIG_ARM_CMN=y
CONFIG_ARM_PMU=y
CONFIG_FSL_IMX8_DDR_PMU=y
CONFIG_ARM_DMC620_PMU=y
CONFIG_ALIBABA_UNCORE_DRW_PMU=y
CONFIG_HNS3_PMU=y
CONFIG_MESON_DDR_PMU=y
# end of Performance monitor support
CONFIG_RAS=y
CONFIG_USB4=y
CONFIG_USB4_DEBUGFS_WRITE=y
CONFIG_USB4_DEBUGFS_MARGINING=y
CONFIG_USB4_KUNIT_TEST=y
CONFIG_USB4_DMA_TEST=y
#
# Android
#
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
CONFIG_ANDROID_BINDER_IPC_SELFTEST=y
# end of Android
CONFIG_DAX=y
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
#
# Layout Types
#
CONFIG_NVMEM_LAYOUT_SL28_VPD=y
CONFIG_NVMEM_LAYOUT_ONIE_TLV=y
# end of Layout Types
CONFIG_NVMEM_APPLE_EFUSES=y
CONFIG_NVMEM_BCM_OCOTP=y
CONFIG_NVMEM_BRCM_NVRAM=y
CONFIG_NVMEM_IMX_IIM=y
CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_IMX_OCOTP_SCU=y
CONFIG_NVMEM_JZ4780_EFUSE=y
CONFIG_NVMEM_LAN9662_OTPC=y
CONFIG_NVMEM_LAYERSCAPE_SFP=y
CONFIG_NVMEM_LPC18XX_EEPROM=y
CONFIG_NVMEM_LPC18XX_OTP=y
CONFIG_NVMEM_MESON_MX_EFUSE=y
CONFIG_NVMEM_MICROCHIP_OTPC=y
CONFIG_NVMEM_MTK_EFUSE=y
CONFIG_NVMEM_MXS_OCOTP=y
CONFIG_NVMEM_NINTENDO_OTP=y
CONFIG_NVMEM_QCOM_QFPROM=y
CONFIG_NVMEM_RAVE_SP_EEPROM=y
CONFIG_NVMEM_RMEM=y
CONFIG_NVMEM_ROCKCHIP_EFUSE=y
CONFIG_NVMEM_ROCKCHIP_OTP=y
CONFIG_NVMEM_SC27XX_EFUSE=y
CONFIG_NVMEM_SNVS_LPGPR=y
CONFIG_NVMEM_SPMI_SDAM=y
CONFIG_NVMEM_SPRD_EFUSE=y
CONFIG_NVMEM_STM32_ROMEM=y
CONFIG_NVMEM_SUNPLUS_OCOTP=y
CONFIG_NVMEM_SUNXI_SID=y
CONFIG_NVMEM_U_BOOT_ENV=y
CONFIG_NVMEM_UNIPHIER_EFUSE=y
CONFIG_NVMEM_VF610_OCOTP=y
#
# HW tracing support
#
CONFIG_STM=y
CONFIG_STM_PROTO_BASIC=y
CONFIG_STM_PROTO_SYS_T=y
CONFIG_STM_DUMMY=y
CONFIG_STM_SOURCE_CONSOLE=y
CONFIG_STM_SOURCE_HEARTBEAT=y
CONFIG_STM_SOURCE_FTRACE=y
CONFIG_INTEL_TH=y
CONFIG_INTEL_TH_PCI=y
CONFIG_INTEL_TH_GTH=y
CONFIG_INTEL_TH_STH=y
CONFIG_INTEL_TH_MSU=y
CONFIG_INTEL_TH_PTI=y
CONFIG_INTEL_TH_DEBUG=y
# end of HW tracing support
CONFIG_FPGA=y
CONFIG_FPGA_MGR_SOCFPGA=y
CONFIG_FPGA_MGR_SOCFPGA_A10=y
CONFIG_ALTERA_PR_IP_CORE=y
CONFIG_ALTERA_PR_IP_CORE_PLAT=y
CONFIG_FPGA_MGR_ALTERA_PS_SPI=y
CONFIG_FPGA_MGR_ALTERA_CVP=y
CONFIG_FPGA_MGR_ZYNQ_FPGA=y
CONFIG_FPGA_MGR_XILINX_SPI=y
CONFIG_FPGA_MGR_ICE40_SPI=y
CONFIG_FPGA_MGR_MACHXO2_SPI=y
CONFIG_FPGA_BRIDGE=y
CONFIG_SOCFPGA_FPGA_BRIDGE=y
CONFIG_ALTERA_FREEZE_BRIDGE=y
CONFIG_XILINX_PR_DECOUPLER=y
CONFIG_FPGA_REGION=y
CONFIG_OF_FPGA_REGION=y
CONFIG_FPGA_DFL=y
CONFIG_FPGA_DFL_FME=y
CONFIG_FPGA_DFL_FME_MGR=y
CONFIG_FPGA_DFL_FME_BRIDGE=y
CONFIG_FPGA_DFL_FME_REGION=y
CONFIG_FPGA_DFL_AFU=y
CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000=y
CONFIG_FPGA_DFL_PCI=y
CONFIG_FPGA_MGR_ZYNQMP_FPGA=y
CONFIG_FPGA_MGR_VERSAL_FPGA=y
CONFIG_FPGA_M10_BMC_SEC_UPDATE=y
CONFIG_FPGA_MGR_MICROCHIP_SPI=y
CONFIG_FPGA_MGR_LATTICE_SYSCONFIG=y
CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI=y
CONFIG_FSI=y
CONFIG_FSI_NEW_DEV_NODE=y
CONFIG_FSI_MASTER_GPIO=y
CONFIG_FSI_MASTER_HUB=y
CONFIG_FSI_MASTER_AST_CF=y
CONFIG_FSI_MASTER_ASPEED=y
CONFIG_FSI_SCOM=y
CONFIG_FSI_SBEFIFO=y
CONFIG_FSI_OCC=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_MULTIPLEXER=y
#
# Multiplexer drivers
#
CONFIG_MUX_ADG792A=y
CONFIG_MUX_ADGS1408=y
CONFIG_MUX_GPIO=y
CONFIG_MUX_MMIO=y
# end of Multiplexer drivers
CONFIG_PM_OPP=y
CONFIG_SIOX=y
CONFIG_SIOX_BUS_GPIO=y
CONFIG_SLIMBUS=y
CONFIG_SLIM_QCOM_CTRL=y
CONFIG_SLIM_QCOM_NGD_CTRL=y
CONFIG_INTERCONNECT=y
CONFIG_INTERCONNECT_IMX=y
CONFIG_INTERCONNECT_IMX8MM=y
CONFIG_INTERCONNECT_IMX8MN=y
CONFIG_INTERCONNECT_IMX8MQ=y
CONFIG_INTERCONNECT_IMX8MP=y
CONFIG_INTERCONNECT_QCOM=y
CONFIG_INTERCONNECT_QCOM_BCM_VOTER=y
CONFIG_INTERCONNECT_QCOM_MSM8916=y
CONFIG_INTERCONNECT_QCOM_MSM8939=y
CONFIG_INTERCONNECT_QCOM_MSM8974=y
CONFIG_INTERCONNECT_QCOM_MSM8996=y
CONFIG_INTERCONNECT_QCOM_OSM_L3=y
CONFIG_INTERCONNECT_QCOM_QCM2290=y
CONFIG_INTERCONNECT_QCOM_QCS404=y
CONFIG_INTERCONNECT_QCOM_QDU1000=y
CONFIG_INTERCONNECT_QCOM_RPMH_POSSIBLE=y
CONFIG_INTERCONNECT_QCOM_RPMH=y
CONFIG_INTERCONNECT_QCOM_SC7180=y
CONFIG_INTERCONNECT_QCOM_SC7280=y
CONFIG_INTERCONNECT_QCOM_SC8180X=y
CONFIG_INTERCONNECT_QCOM_SC8280XP=y
CONFIG_INTERCONNECT_QCOM_SDM660=y
CONFIG_INTERCONNECT_QCOM_SDM845=y
CONFIG_INTERCONNECT_QCOM_SDX55=y
CONFIG_INTERCONNECT_QCOM_SDX65=y
CONFIG_INTERCONNECT_QCOM_SM6350=y
CONFIG_INTERCONNECT_QCOM_SM8150=y
CONFIG_INTERCONNECT_QCOM_SM8250=y
CONFIG_INTERCONNECT_QCOM_SM8350=y
CONFIG_INTERCONNECT_QCOM_SM8450=y
CONFIG_INTERCONNECT_QCOM_SM8550=y
CONFIG_INTERCONNECT_QCOM_SMD_RPM=y
CONFIG_INTERCONNECT_SAMSUNG=y
CONFIG_INTERCONNECT_EXYNOS=y
CONFIG_COUNTER=y
CONFIG_104_QUAD_8=y
CONFIG_INTERRUPT_CNT=y
CONFIG_STM32_TIMER_CNT=y
CONFIG_STM32_LPTIMER_CNT=y
CONFIG_TI_EQEP=y
CONFIG_FTM_QUADDEC=y
CONFIG_MICROCHIP_TCB_CAPTURE=y
CONFIG_INTEL_QEP=y
CONFIG_TI_ECAP_CAPTURE=y
CONFIG_MOST=y
CONFIG_MOST_USB_HDM=y
CONFIG_MOST_CDEV=y
CONFIG_MOST_SND=y
CONFIG_PECI=y
CONFIG_PECI_CPU=y
CONFIG_PECI_ASPEED=y
CONFIG_HTE=y
# end of Device Drivers
#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_VALIDATE_FS_PARSER=y
CONFIG_FS_IOMAP=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_DEBUG=y
CONFIG_EXT4_KUNIT_TESTS=y
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
CONFIG_JFS_FS=y
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_JFS_DEBUG=y
CONFIG_JFS_STATISTICS=y
CONFIG_XFS_FS=y
CONFIG_XFS_SUPPORT_V4=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_ONLINE_SCRUB=y
CONFIG_XFS_ONLINE_REPAIR=y
CONFIG_XFS_DEBUG=y
CONFIG_XFS_ASSERT_FATAL=y
CONFIG_GFS2_FS=y
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=y
CONFIG_OCFS2_FS_O2CB=y
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=y
CONFIG_OCFS2_FS_STATS=y
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BTRFS_FS_CHECK_INTEGRITY=y
CONFIG_BTRFS_FS_RUN_SANITY_TESTS=y
CONFIG_BTRFS_DEBUG=y
CONFIG_BTRFS_ASSERT=y
CONFIG_BTRFS_FS_REF_VERIFY=y
CONFIG_NILFS2_FS=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_F2FS_CHECK_FS=y
CONFIG_F2FS_FAULT_INJECTION=y
CONFIG_F2FS_FS_COMPRESSION=y
CONFIG_F2FS_FS_LZO=y
CONFIG_F2FS_FS_LZORLE=y
CONFIG_F2FS_FS_LZ4=y
CONFIG_F2FS_FS_LZ4HC=y
CONFIG_F2FS_FS_ZSTD=y
CONFIG_F2FS_IOSTAT=y
CONFIG_F2FS_UNFAIR_RWSEM=y
CONFIG_ZONEFS_FS=y
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=y
CONFIG_QFMT_V1=y
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
CONFIG_AUTOFS4_FS=y
CONFIG_AUTOFS_FS=y
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
CONFIG_VIRTIO_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
CONFIG_OVERLAY_FS_INDEX=y
CONFIG_OVERLAY_FS_METACOPY=y
#
# Caches
#
CONFIG_NETFS_SUPPORT=y
CONFIG_NETFS_STATS=y
CONFIG_FSCACHE=y
CONFIG_FSCACHE_STATS=y
CONFIG_FSCACHE_DEBUG=y
CONFIG_CACHEFILES=y
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_ERROR_INJECTION=y
CONFIG_CACHEFILES_ONDEMAND=y
# end of Caches
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=y
# end of CD-ROM/DVD Filesystems
#
# DOS/FAT/EXFAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_FAT_KUNIT_TEST=y
CONFIG_EXFAT_FS=y
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y
CONFIG_NTFS3_FS=y
CONFIG_NTFS3_LZX_XPRESS=y
CONFIG_NTFS3_FS_POSIX_ACL=y
# end of DOS/FAT/EXFAT/NT Filesystems
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_VMCORE=y
CONFIG_PROC_VMCORE_DEVICE_DUMP=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PROC_CHILDREN=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
CONFIG_MEMFD_CREATE=y
CONFIG_CONFIGFS_FS=y
CONFIG_EFIVAR_FS=y
# end of Pseudo filesystems
CONFIG_MISC_FILESYSTEMS=y
CONFIG_ORANGEFS_FS=y
CONFIG_ADFS_FS=y
CONFIG_ADFS_FS_RW=y
CONFIG_AFFS_FS=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_HFS_FS=y
CONFIG_HFSPLUS_FS=y
CONFIG_BEFS_FS=y
CONFIG_BEFS_DEBUG=y
CONFIG_BFS_FS=y
CONFIG_EFS_FS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_JFFS2_FS_WBUF_VERIFY=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_FS_POSIX_ACL=y
CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
CONFIG_UBIFS_ATIME_SUPPORT=y
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_SECURITY=y
CONFIG_UBIFS_FS_AUTHENTICATION=y
CONFIG_CRAMFS=y
CONFIG_CRAMFS_BLOCKDEV=y
CONFIG_CRAMFS_MTD=y
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_FILE_CACHE=y
# CONFIG_SQUASHFS_FILE_DIRECT is not set
CONFIG_SQUASHFS_DECOMP_SINGLE=y
CONFIG_SQUASHFS_DECOMP_MULTI=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y
CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS=y
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
CONFIG_VXFS_FS=y
CONFIG_MINIX_FS=y
CONFIG_OMFS_FS=y
CONFIG_HPFS_FS=y
CONFIG_QNX4FS_FS=y
CONFIG_QNX6FS_FS=y
CONFIG_QNX6FS_DEBUG=y
CONFIG_ROMFS_FS=y
CONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not set
CONFIG_ROMFS_ON_BLOCK=y
CONFIG_PSTORE=y
CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
CONFIG_PSTORE_DEFLATE_COMPRESS=y
CONFIG_PSTORE_LZO_COMPRESS=y
CONFIG_PSTORE_LZ4_COMPRESS=y
CONFIG_PSTORE_LZ4HC_COMPRESS=y
CONFIG_PSTORE_842_COMPRESS=y
CONFIG_PSTORE_ZSTD_COMPRESS=y
CONFIG_PSTORE_COMPRESS=y
CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y
# CONFIG_PSTORE_LZO_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_LZ4_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_842_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_ZSTD_COMPRESS_DEFAULT is not set
CONFIG_PSTORE_COMPRESS_DEFAULT="deflate"
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_FTRACE=y
CONFIG_PSTORE_RAM=y
CONFIG_PSTORE_ZONE=y
CONFIG_PSTORE_BLK=y
CONFIG_PSTORE_BLK_BLKDEV=""
CONFIG_PSTORE_BLK_KMSG_SIZE=64
CONFIG_PSTORE_BLK_MAX_REASON=2
CONFIG_PSTORE_BLK_PMSG_SIZE=64
CONFIG_PSTORE_BLK_CONSOLE_SIZE=64
CONFIG_PSTORE_BLK_FTRACE_SIZE=64
CONFIG_SYSV_FS=y
CONFIG_UFS_FS=y
CONFIG_UFS_FS_WRITE=y
CONFIG_UFS_DEBUG=y
CONFIG_EROFS_FS=y
CONFIG_EROFS_FS_DEBUG=y
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZMA=y
CONFIG_EROFS_FS_ONDEMAND=y
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_SWAP=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_PNFS_FILE_LAYOUT=y
CONFIG_PNFS_BLOCK=y
CONFIG_PNFS_FLEXFILE_LAYOUT=y
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
CONFIG_NFS_V4_1_MIGRATION=y
CONFIG_NFS_V4_SECURITY_LABEL=y
CONFIG_ROOT_NFS=y
CONFIG_NFS_FSCACHE=y
CONFIG_NFS_USE_LEGACY_DNS=y
CONFIG_NFS_DEBUG=y
CONFIG_NFS_DISABLE_UDP_SUPPORT=y
CONFIG_NFS_V4_2_READ_PLUS=y
CONFIG_NFSD=y
CONFIG_NFSD_V2=y
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_PNFS=y
CONFIG_NFSD_BLOCKLAYOUT=y
CONFIG_NFSD_SCSILAYOUT=y
CONFIG_NFSD_FLEXFILELAYOUT=y
CONFIG_NFSD_V4_2_INTER_SSC=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
CONFIG_GRACE_PERIOD=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_NFS_V4_2_SSC_HELPER=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_SUNRPC_BACKCHANNEL=y
CONFIG_SUNRPC_SWAP=y
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
CONFIG_SUNRPC_DEBUG=y
CONFIG_SUNRPC_XPRT_RDMA=y
CONFIG_CEPH_FS=y
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CEPH_FS_SECURITY_LABEL=y
CONFIG_CIFS=y
CONFIG_CIFS_STATS2=y
CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DEBUG=y
CONFIG_CIFS_DEBUG2=y
CONFIG_CIFS_DEBUG_DUMP_KEYS=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SWN_UPCALL=y
CONFIG_CIFS_SMB_DIRECT=y
CONFIG_CIFS_FSCACHE=y
CONFIG_CIFS_ROOT=y
CONFIG_SMB_SERVER=y
CONFIG_SMB_SERVER_SMBDIRECT=y
CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y
CONFIG_SMB_SERVER_KERBEROS5=y
CONFIG_SMBFS_COMMON=y
CONFIG_CODA_FS=y
CONFIG_AFS_FS=y
CONFIG_AFS_DEBUG=y
CONFIG_AFS_FSCACHE=y
CONFIG_AFS_DEBUG_CURSOR=y
CONFIG_9P_FS=y
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_950=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_CODEPAGE_949=y
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=y
CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_MAC_ROMAN=y
CONFIG_NLS_MAC_CELTIC=y
CONFIG_NLS_MAC_CENTEURO=y
CONFIG_NLS_MAC_CROATIAN=y
CONFIG_NLS_MAC_CYRILLIC=y
CONFIG_NLS_MAC_GAELIC=y
CONFIG_NLS_MAC_GREEK=y
CONFIG_NLS_MAC_ICELAND=y
CONFIG_NLS_MAC_INUIT=y
CONFIG_NLS_MAC_ROMANIAN=y
CONFIG_NLS_MAC_TURKISH=y
CONFIG_NLS_UTF8=y
CONFIG_DLM=y
CONFIG_DLM_DEPRECATED_API=y
CONFIG_DLM_DEBUG=y
CONFIG_UNICODE=y
CONFIG_UNICODE_NORMALIZATION_SELFTEST=y
CONFIG_IO_WQ=y
# end of File systems
#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_REQUEST_CACHE=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_BIG_KEYS=y
CONFIG_TRUSTED_KEYS=y
CONFIG_TRUSTED_KEYS_TPM=y
CONFIG_TRUSTED_KEYS_TEE=y
CONFIG_TRUSTED_KEYS_CAAM=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_USER_DECRYPTED_DATA=y
CONFIG_KEY_DH_OPERATIONS=y
CONFIG_KEY_NOTIFICATIONS=y
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_SECURITY_WRITABLE_HOOKS=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_INFINIBAND=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
CONFIG_LSM_MMAP_MIN_ADDR=32768
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_STATIC_USERMODEHELPER_PATH="/sbin/usermode-helper"
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SMACK_BRINGUP=y
CONFIG_SECURITY_SMACK_NETFILTER=y
CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048
CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024
CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER=y
CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_DEBUG=y
CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS=y
CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES=y
CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y
CONFIG_SECURITY_APPARMOR_HASH=y
CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y
CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y
CONFIG_SECURITY_APPARMOR_KUNIT_TEST=y
CONFIG_SECURITY_LOADPIN=y
CONFIG_SECURITY_LOADPIN_ENFORCE=y
CONFIG_SECURITY_LOADPIN_VERITY=y
CONFIG_SECURITY_YAMA=y
CONFIG_SECURITY_SAFESETID=y
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
CONFIG_SECURITY_LANDLOCK=y
CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y
CONFIG_LOAD_UEFI_KEYS=y
CONFIG_INTEGRITY_AUDIT=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_LSM_RULES=y
CONFIG_IMA_NG_TEMPLATE=y
# CONFIG_IMA_SIG_TEMPLATE is not set
CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
CONFIG_IMA_DEFAULT_HASH_SHA1=y
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
# CONFIG_IMA_DEFAULT_HASH_WP512 is not set
# CONFIG_IMA_DEFAULT_HASH_SM3 is not set
CONFIG_IMA_DEFAULT_HASH="sha1"
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_READ_POLICY=y
CONFIG_IMA_APPRAISE=y
CONFIG_IMA_ARCH_POLICY=y
CONFIG_IMA_APPRAISE_BUILD_POLICY=y
CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS=y
CONFIG_IMA_APPRAISE_BOOTPARAM=y
CONFIG_IMA_APPRAISE_MODSIG=y
CONFIG_IMA_TRUSTED_KEYRING=y
CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY=y
CONFIG_IMA_BLACKLIST_KEYRING=y
CONFIG_IMA_LOAD_X509=y
CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
CONFIG_IMA_APPRAISE_SIGNED_INIT=y
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
CONFIG_IMA_DISABLE_HTABLE=y
CONFIG_EVM=y
CONFIG_EVM_ATTR_FSUUID=y
CONFIG_EVM_EXTRA_SMACK_XATTRS=y
CONFIG_EVM_ADD_XATTRS=y
CONFIG_EVM_LOAD_X509=y
CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der"
CONFIG_DEFAULT_SECURITY_SELINUX=y
# CONFIG_DEFAULT_SECURITY_SMACK is not set
# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
# CONFIG_DEFAULT_SECURITY_APPARMOR is not set
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
#
# Kernel hardening options
#
#
# Memory initialization
#
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
# CONFIG_INIT_STACK_NONE is not set
CONFIG_INIT_STACK_ALL_PATTERN=y
# CONFIG_INIT_STACK_ALL_ZERO is not set
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
CONFIG_ZERO_CALL_USED_REGS=y
# end of Memory initialization
# CONFIG_RANDSTRUCT_NONE is not set
CONFIG_RANDSTRUCT_FULL=y
# CONFIG_RANDSTRUCT_PERFORMANCE is not set
CONFIG_RANDSTRUCT=y
CONFIG_GCC_PLUGIN_RANDSTRUCT=y
# end of Kernel hardening options
# end of Security options
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_SKCIPHER=y
CONFIG_CRYPTO_SKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
CONFIG_CRYPTO_KPP=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_PCRYPT=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_TEST=y
CONFIG_CRYPTO_SIMD=y
CONFIG_CRYPTO_ENGINE=y
# end of Crypto core or helper
#
# Public-key cryptography
#
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_DH=y
CONFIG_CRYPTO_DH_RFC7919_GROUPS=y
CONFIG_CRYPTO_ECC=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_ECDSA=y
CONFIG_CRYPTO_ECRDSA=y
CONFIG_CRYPTO_SM2=y
CONFIG_CRYPTO_CURVE25519=y
# end of Public-key cryptography
#
# Block ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_TI=y
CONFIG_CRYPTO_ANUBIS=y
CONFIG_CRYPTO_ARIA=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_BLOWFISH_COMMON=y
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAST_COMMON=y
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=y
CONFIG_CRYPTO_KHAZAD=y
CONFIG_CRYPTO_SEED=y
CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_SM4=y
CONFIG_CRYPTO_SM4_GENERIC=y
CONFIG_CRYPTO_TEA=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
# end of Block ciphers
#
# Length-preserving ciphers and modes
#
CONFIG_CRYPTO_ADIANTUM=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_CHACHA20=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CFB=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HCTR2=y
CONFIG_CRYPTO_KEYWRAP=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_OFB=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XCTR=y
CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_NHPOLY1305=y
# end of Length-preserving ciphers and modes
#
# AEAD (authenticated encryption with associated data) ciphers
#
CONFIG_CRYPTO_AEGIS128=y
CONFIG_CRYPTO_AEGIS128_SIMD=y
CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_ESSIV=y
# end of AEAD (authenticated encryption with associated data) ciphers
#
# Hashes, digests, and MACs
#
CONFIG_CRYPTO_BLAKE2B=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_POLYVAL=y
CONFIG_CRYPTO_POLY1305=y
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SM3=y
CONFIG_CRYPTO_SM3_GENERIC=y
CONFIG_CRYPTO_STREEBOG=y
CONFIG_CRYPTO_VMAC=y
CONFIG_CRYPTO_WP512=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_XXHASH=y
# end of Hashes, digests, and MACs
#
# CRCs (cyclic redundancy checks)
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRCT10DIF=y
CONFIG_CRYPTO_CRC64_ROCKSOFT=y
# end of CRCs (cyclic redundancy checks)
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_842=y
CONFIG_CRYPTO_LZ4=y
CONFIG_CRYPTO_LZ4HC=y
CONFIG_CRYPTO_ZSTD=y
# end of Compression
#
# Random number generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_DRBG_CTR=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_KDF800108_CTR=y
# end of Random number generation
#
# Userspace interface
#
CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_USER_API_RNG=y
CONFIG_CRYPTO_USER_API_RNG_CAVP=y
CONFIG_CRYPTO_USER_API_AEAD=y
CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
CONFIG_CRYPTO_STATS=y
# end of Userspace interface
CONFIG_CRYPTO_HASH_INFO=y
#
# Accelerated Cryptographic Algorithms for CPU (arm)
#
CONFIG_CRYPTO_CURVE25519_NEON=y
CONFIG_CRYPTO_GHASH_ARM_CE=y
CONFIG_CRYPTO_NHPOLY1305_NEON=y
CONFIG_CRYPTO_POLY1305_ARM=y
CONFIG_CRYPTO_BLAKE2S_ARM=y
CONFIG_CRYPTO_BLAKE2B_NEON=y
CONFIG_CRYPTO_SHA1_ARM=y
CONFIG_CRYPTO_SHA1_ARM_NEON=y
CONFIG_CRYPTO_SHA1_ARM_CE=y
CONFIG_CRYPTO_SHA2_ARM_CE=y
CONFIG_CRYPTO_SHA256_ARM=y
CONFIG_CRYPTO_SHA512_ARM=y
CONFIG_CRYPTO_AES_ARM=y
CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_CRYPTO_AES_ARM_CE=y
CONFIG_CRYPTO_CHACHA20_NEON=y
CONFIG_CRYPTO_CRC32_ARM_CE=y
CONFIG_CRYPTO_CRCT10DIF_ARM_CE=y
# end of Accelerated Cryptographic Algorithms for CPU (arm)
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_ALLWINNER=y
CONFIG_CRYPTO_DEV_SUN4I_SS=y
CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y
CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_CE=y
CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_HASH=y
CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS=y
CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_HASH=y
CONFIG_CRYPTO_DEV_SL3516=y
CONFIG_CRYPTO_DEV_SL3516_DEBUG=y
CONFIG_CRYPTO_DEV_HIFN_795X=y
CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG=y
CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN=y
CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y
CONFIG_CRYPTO_DEV_OMAP=y
CONFIG_CRYPTO_DEV_OMAP_SHAM=y
CONFIG_CRYPTO_DEV_OMAP_AES=y
CONFIG_CRYPTO_DEV_OMAP_DES=y
CONFIG_CRYPTO_DEV_SAHARA=y
CONFIG_CRYPTO_DEV_EXYNOS_RNG=y
CONFIG_CRYPTO_DEV_S5P=y
CONFIG_CRYPTO_DEV_UX500=y
CONFIG_CRYPTO_DEV_UX500_HASH=y
CONFIG_CRYPTO_DEV_UX500_DEBUG=y
CONFIG_CRYPTO_DEV_ATMEL_AUTHENC=y
CONFIG_CRYPTO_DEV_ATMEL_AES=y
CONFIG_CRYPTO_DEV_ATMEL_TDES=y
CONFIG_CRYPTO_DEV_ATMEL_SHA=y
CONFIG_CRYPTO_DEV_ATMEL_I2C=y
CONFIG_CRYPTO_DEV_ATMEL_ECC=y
CONFIG_CRYPTO_DEV_ATMEL_SHA204A=y
CONFIG_CRYPTO_DEV_MXS_DCP=y
CONFIG_CRYPTO_DEV_QAT=y
CONFIG_CRYPTO_DEV_QAT_DH895xCC=y
CONFIG_CRYPTO_DEV_QAT_C3XXX=y
CONFIG_CRYPTO_DEV_QAT_C62X=y
CONFIG_CRYPTO_DEV_QAT_4XXX=y
CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=y
CONFIG_CRYPTO_DEV_QAT_C3XXXVF=y
CONFIG_CRYPTO_DEV_QAT_C62XVF=y
CONFIG_CRYPTO_DEV_MARVELL=y
CONFIG_CRYPTO_DEV_MARVELL_CESA=y
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
CONFIG_CRYPTO_DEV_QCE_SHA=y
CONFIG_CRYPTO_DEV_QCE_AEAD=y
CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
CONFIG_CRYPTO_DEV_QCOM_RNG=y
CONFIG_CRYPTO_DEV_IMGTEC_HASH=y
CONFIG_CRYPTO_DEV_ROCKCHIP=y
CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG=y
CONFIG_CRYPTO_DEV_ZYNQMP_AES=y
CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=y
CONFIG_CRYPTO_DEV_CHELSIO=y
CONFIG_CRYPTO_DEV_VIRTIO=y
CONFIG_CRYPTO_DEV_BCM_SPU=y
CONFIG_CRYPTO_DEV_STM32_CRC=y
CONFIG_CRYPTO_DEV_STM32_HASH=y
CONFIG_CRYPTO_DEV_STM32_CRYP=y
CONFIG_CRYPTO_DEV_SAFEXCEL=y
CONFIG_CRYPTO_DEV_ARTPEC6=y
CONFIG_CRYPTO_DEV_CCREE=y
CONFIG_CRYPTO_DEV_HISI_SEC=y
CONFIG_CRYPTO_DEV_AMLOGIC_GXL=y
CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y
CONFIG_CRYPTO_DEV_SA2UL=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU_HMAC_SHA224=y
CONFIG_CRYPTO_DEV_ASPEED=y
CONFIG_CRYPTO_DEV_ASPEED_DEBUG=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO=y
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS8_PRIVATE_KEY_PARSER=y
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_PKCS7_TEST_KEY=y
CONFIG_SIGNED_PE_FILE_VERIFICATION=y
CONFIG_FIPS_SIGNATURE_SELFTEST=y
#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_EXTRA_CERTIFICATE=y
CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096
CONFIG_SECONDARY_TRUSTED_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
CONFIG_SYSTEM_REVOCATION_LIST=y
CONFIG_SYSTEM_REVOCATION_KEYS=""
CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE=y
# end of Certificates for signature checking
CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_RAID6_PQ=y
CONFIG_RAID6_PQ_BENCHMARK=y
CONFIG_LINEAR_RANGES=y
CONFIG_PACKING=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_CORDIC=y
CONFIG_PRIME_NUMBERS=y
CONFIG_RATIONAL=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_STMP_DEVICE=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
#
# Crypto library routines
#
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_ARC4=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y
CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
CONFIG_CRYPTO_LIB_CHACHA=y
CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=y
CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
CONFIG_CRYPTO_LIB_CURVE25519=y
CONFIG_CRYPTO_LIB_DES=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y
CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305=y
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
# end of Crypto library routines
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC64_ROCKSOFT=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC32_SELFTEST=y
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
CONFIG_CRC64=y
CONFIG_CRC4=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_CRC8=y
CONFIG_XXHASH=y
CONFIG_AUDIT_GENERIC=y
CONFIG_RANDOM32_SELFTEST=y
CONFIG_842_COMPRESS=y
CONFIG_842_DECOMPRESS=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4_COMPRESS=y
CONFIG_LZ4HC_COMPRESS=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_MICROLZMA=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_TEST=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_ZSTD=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_REED_SOLOMON_ENC16=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_BCH=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=y
CONFIG_TEXTSEARCH_BM=y
CONFIG_TEXTSEARCH_FSM=y
CONFIG_BTREE=y
CONFIG_INTERVAL_TREE=y
CONFIG_INTERVAL_TREE_SPAN_ITER=y
CONFIG_XARRAY_MULTI=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_DMA_DECLARE_COHERENT=y
CONFIG_ARCH_HAS_SETUP_DMA_OPS=y
CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y
CONFIG_DMA_NONCOHERENT_MMAP=y
CONFIG_DMA_CMA=y
CONFIG_DMA_PERNUMA_CMA=y
#
# Default contiguous memory area size:
#
CONFIG_CMA_SIZE_MBYTES=16
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_ALIGNMENT=8
CONFIG_DMA_API_DEBUG=y
CONFIG_DMA_API_DEBUG_SG=y
CONFIG_DMA_MAP_BENCHMARK=y
CONFIG_SGL_ALLOC=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_GLOB=y
CONFIG_GLOB_SELFTEST=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_LRU_CACHE=y
CONFIG_CLZ_TAB=y
CONFIG_IRQ_POLL=y
CONFIG_MPILIB=y
CONFIG_SIGNATURE=y
CONFIG_DIMLIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
CONFIG_UCS2_STRING=y
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_VDSO_32=y
CONFIG_FONT_SUPPORT=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_FONT_6x11=y
CONFIG_FONT_7x14=y
CONFIG_FONT_PEARL_8x8=y
CONFIG_FONT_ACORN_8x8=y
CONFIG_FONT_MINI_4x6=y
CONFIG_FONT_6x10=y
CONFIG_FONT_10x18=y
CONFIG_FONT_SUN8x16=y
CONFIG_FONT_SUN12x22=y
CONFIG_FONT_TER16x32=y
CONFIG_FONT_6x8=y
CONFIG_SG_SPLIT=y
CONFIG_SG_POOL=y
CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_REF_TRACKER=y
CONFIG_SBITMAP=y
CONFIG_PARMAN=y
CONFIG_OBJAGG=y
# end of Library routines
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_PLDMFW=y
CONFIG_ASN1_ENCODER=y
CONFIG_POLYNOMIAL=y
#
# Kernel hacking
#
#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
CONFIG_STACKTRACE_BUILD_ID=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DYNAMIC_DEBUG_CORE=y
CONFIG_SYMBOLIC_ERRNAME=y
CONFIG_DEBUG_BUGVERBOSE=y
# end of printk and dmesg options
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y
#
# Compile-time checks and compiler options
#
CONFIG_AS_HAS_NON_CONST_LEB128=y
CONFIG_DEBUG_INFO_NONE=y
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
CONFIG_FRAME_WARN=2048
CONFIG_STRIP_ASM_SYMS=y
CONFIG_READABLE_ASM=y
CONFIG_HEADERS_INSTALL=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_VMLINUX_MAP=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# end of Compile-time checks and compiler options
#
# Generic Kernel Debugging Instruments
#
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_FS_ALLOW_ALL=y
# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_HONOUR_BLOCKLIST=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_TESTS=y
CONFIG_KGDB_TESTS_ON_BOOT=y
CONFIG_KGDB_TESTS_BOOT_STRING="V1F100"
CONFIG_KGDB_KDB=y
CONFIG_KDB_DEFAULT_ENABLE=0x1
CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
CONFIG_UBSAN=y
CONFIG_CC_HAS_UBSAN_BOUNDS=y
CONFIG_UBSAN_BOUNDS=y
CONFIG_UBSAN_ONLY_BOUNDS=y
CONFIG_UBSAN_SHIFT=y
CONFIG_UBSAN_DIV_ZERO=y
CONFIG_UBSAN_UNREACHABLE=y
CONFIG_UBSAN_BOOL=y
CONFIG_UBSAN_ENUM=y
CONFIG_UBSAN_SANITIZE_ALL=y
CONFIG_TEST_UBSAN=m
CONFIG_HAVE_KCSAN_COMPILER=y
# end of Generic Kernel Debugging Instruments
#
# Networking Debugging
#
CONFIG_NET_DEV_REFCNT_TRACKER=y
CONFIG_NET_NS_REFCNT_TRACKER=y
CONFIG_DEBUG_NET=y
# end of Networking Debugging
#
# Memory Debugging
#
CONFIG_PAGE_EXTENSION=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_POISONING=y
CONFIG_DEBUG_PAGE_REF=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DEBUG_WX=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_WORK=y
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SHRINKER_DEBUG=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
CONFIG_DEBUG_KMEMLEAK_TEST=m
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_VM_IRQSOFF=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_MAPLE_TREE=y
CONFIG_DEBUG_VM_RB=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_DEBUG_KMAP_LOCAL=y
CONFIG_DEBUG_HIGHMEM=y
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
CONFIG_HAVE_ARCH_KFENCE=y
CONFIG_KFENCE=y
CONFIG_KFENCE_SAMPLE_INTERVAL=100
CONFIG_KFENCE_NUM_OBJECTS=255
CONFIG_KFENCE_DEFERRABLE=y
CONFIG_KFENCE_STATIC_KEYS=y
CONFIG_KFENCE_STRESS_TEST_FAULTS=0
CONFIG_KFENCE_KUNIT_TEST=y
# end of Memory Debugging
CONFIG_DEBUG_SHIRQ=y
#
# Debug Oops, Lockups and Hangs
#
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_ON_OOPS_VALUE=1
CONFIG_PANIC_TIMEOUT=0
CONFIG_LOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_WQ_WATCHDOG=y
CONFIG_TEST_LOCKUP=m
# end of Debug Oops, Lockups and Hangs
#
# Scheduler Debugging
#
CONFIG_SCHED_DEBUG=y
CONFIG_SCHED_INFO=y
CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging
CONFIG_DEBUG_TIMEKEEPING=y
#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_PROVE_LOCKING=y
CONFIG_PROVE_RAW_LOCK_NESTING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_LOCKDEP=y
CONFIG_LOCKDEP_BITS=15
CONFIG_LOCKDEP_CHAINS_BITS=16
CONFIG_LOCKDEP_STACK_TRACE_BITS=19
CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_LOCK_TORTURE_TEST=y
CONFIG_WW_MUTEX_SELFTEST=y
CONFIG_SCF_TORTURE_TEST=y
# end of Lock Debugging (spinlocks, mutexes, etc...)
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_IRQFLAGS=y
CONFIG_STACKTRACE=y
CONFIG_WARN_ALL_UNSEEDED_RANDOM=y
CONFIG_DEBUG_KOBJECT=y
CONFIG_DEBUG_KOBJECT_RELEASE=y
#
# Debug kernel data structures
#
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_DEBUG_MAPLE_TREE=y
# end of Debug kernel data structures
CONFIG_DEBUG_CREDENTIALS=y
#
# RCU Debugging
#
CONFIG_PROVE_RCU=y
CONFIG_PROVE_RCU_LIST=y
CONFIG_TORTURE_TEST=y
CONFIG_RCU_SCALE_TEST=y
CONFIG_RCU_TORTURE_TEST=y
CONFIG_RCU_REF_SCALE_TEST=y
CONFIG_RCU_CPU_STALL_TIMEOUT=21
CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
CONFIG_RCU_CPU_STALL_CPUTIME=y
CONFIG_RCU_TRACE=y
CONFIG_RCU_EQS_DEBUG=y
CONFIG_RCU_STRICT_GRACE_PERIOD=y
# end of RCU Debugging
CONFIG_DEBUG_WQ_FORCE_RR_CPU=y
CONFIG_CPU_HOTPLUG_STATE_CONTROL=y
CONFIG_LATENCYTOP=y
CONFIG_DEBUG_CGROUP_REF=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_PREEMPTIRQ_TRACEPOINTS=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_BOOTTIME_TRACING=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_STACK_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_HWLAT_TRACER=y
CONFIG_OSNOISE_TRACER=y
CONFIG_TIMERLAT_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KPROBE_EVENTS=y
CONFIG_KPROBE_EVENTS_ON_NOTRACE=y
CONFIG_UPROBE_EVENTS=y
CONFIG_BPF_EVENTS=y
CONFIG_DYNAMIC_EVENTS=y
CONFIG_PROBE_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_FTRACE_MCOUNT_RECORD=y
CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT=y
CONFIG_TRACING_MAP=y
CONFIG_SYNTH_EVENTS=y
CONFIG_USER_EVENTS=y
CONFIG_HIST_TRIGGERS=y
CONFIG_TRACE_EVENT_INJECT=y
CONFIG_TRACEPOINT_BENCHMARK=y
CONFIG_RING_BUFFER_BENCHMARK=y
CONFIG_TRACE_EVAL_MAP_FILE=y
CONFIG_FTRACE_RECORD_RECURSION=y
CONFIG_FTRACE_RECORD_RECURSION_SIZE=128
CONFIG_RING_BUFFER_RECORD_RECURSION=y
CONFIG_GCOV_PROFILE_FTRACE=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_TEST_SYSCALLS=y
CONFIG_FTRACE_SORT_STARTUP_TEST=y
CONFIG_RING_BUFFER_STARTUP_TEST=y
CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS=y
CONFIG_PREEMPTIRQ_DELAY_TEST=m
CONFIG_SYNTH_EVENT_GEN_TEST=y
CONFIG_KPROBE_EVENT_GEN_TEST=y
CONFIG_HIST_TRIGGERS_DEBUG=y
CONFIG_DA_MON_EVENTS=y
CONFIG_DA_MON_EVENTS_ID=y
CONFIG_RV=y
CONFIG_RV_MON_WWNR=y
CONFIG_RV_REACTORS=y
CONFIG_RV_REACT_PRINTK=y
CONFIG_RV_REACT_PANIC=y
# CONFIG_SAMPLES is not set
CONFIG_STRICT_DEVMEM=y
CONFIG_IO_STRICT_DEVMEM=y
#
# arm Debugging
#
CONFIG_ARM_PTDUMP_CORE=y
CONFIG_ARM_PTDUMP_DEBUGFS=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
CONFIG_UNWINDER_ARM=y
CONFIG_ARM_UNWIND=y
CONFIG_BACKTRACE_VERBOSE=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_ALPINE_UART0=y
# CONFIG_DEBUG_AT91_SAM9263_DBGU is not set
# CONFIG_DEBUG_AT91_SAMA5D2_UART1 is not set
# CONFIG_DEBUG_AT91_SAMA5D4_USART3 is not set
# CONFIG_DEBUG_AT91_SAMA7G5_FLEXCOM3 is not set
# CONFIG_DEBUG_AT91_LAN966_FLEXCOM is not set
# CONFIG_DEBUG_BCM2835 is not set
# CONFIG_DEBUG_BCM2836 is not set
# CONFIG_DEBUG_BCM_5301X is not set
# CONFIG_DEBUG_BCM_HR2 is not set
# CONFIG_DEBUG_BCM_IPROC_UART3 is not set
# CONFIG_DEBUG_BCM_KONA_UART is not set
# CONFIG_DEBUG_BCM63XX_UART is not set
# CONFIG_DEBUG_BERLIN_UART is not set
# CONFIG_DEBUG_BRCMSTB_UART is not set
# CONFIG_DEBUG_DIGICOLOR_UA0 is not set
# CONFIG_DEBUG_HI3620_UART is not set
# CONFIG_DEBUG_HIGHBANK_UART is not set
# CONFIG_DEBUG_HIP01_UART is not set
# CONFIG_DEBUG_HIP04_UART is not set
# CONFIG_DEBUG_HIX5HD2_UART is not set
# CONFIG_DEBUG_IMX31_UART is not set
# CONFIG_DEBUG_IMX35_UART is not set
# CONFIG_DEBUG_IMX50_UART is not set
# CONFIG_DEBUG_IMX51_UART is not set
# CONFIG_DEBUG_IMX53_UART is not set
# CONFIG_DEBUG_IMX6Q_UART is not set
# CONFIG_DEBUG_IMX6SL_UART is not set
# CONFIG_DEBUG_IMX6SX_UART is not set
# CONFIG_DEBUG_IMX6UL_UART is not set
# CONFIG_DEBUG_IMX7D_UART is not set
# CONFIG_DEBUG_INTEGRATOR is not set
# CONFIG_DEBUG_KEYSTONE_UART0 is not set
# CONFIG_DEBUG_KEYSTONE_UART1 is not set
# CONFIG_DEBUG_MESON_UARTAO is not set
# CONFIG_DEBUG_MMP_UART2 is not set
# CONFIG_DEBUG_MMP_UART3 is not set
# CONFIG_DEBUG_MVEBU_UART0 is not set
# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set
# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
# CONFIG_DEBUG_MSTARV7_PMUART is not set
# CONFIG_DEBUG_MT6589_UART0 is not set
# CONFIG_DEBUG_MT8127_UART0 is not set
# CONFIG_DEBUG_MT8135_UART3 is not set
# CONFIG_DEBUG_OMAP2UART1 is not set
# CONFIG_DEBUG_OMAP2UART2 is not set
# CONFIG_DEBUG_OMAP2UART3 is not set
# CONFIG_DEBUG_OMAP3UART3 is not set
# CONFIG_DEBUG_OMAP4UART3 is not set
# CONFIG_DEBUG_OMAP3UART4 is not set
# CONFIG_DEBUG_OMAP4UART4 is not set
# CONFIG_DEBUG_TI81XXUART1 is not set
# CONFIG_DEBUG_TI81XXUART2 is not set
# CONFIG_DEBUG_TI81XXUART3 is not set
# CONFIG_DEBUG_AM33XXUART1 is not set
# CONFIG_DEBUG_ZOOM_UART is not set
# CONFIG_DEBUG_QCOM_UARTDM is not set
# CONFIG_DEBUG_REALVIEW_STD_PORT is not set
# CONFIG_DEBUG_REALVIEW_PB1176_PORT is not set
# CONFIG_DEBUG_RV1108_UART0 is not set
# CONFIG_DEBUG_RV1108_UART1 is not set
# CONFIG_DEBUG_RV1108_UART2 is not set
# CONFIG_DEBUG_RK29_UART0 is not set
# CONFIG_DEBUG_RK29_UART1 is not set
# CONFIG_DEBUG_RK29_UART2 is not set
# CONFIG_DEBUG_RK3X_UART0 is not set
# CONFIG_DEBUG_RK3X_UART1 is not set
# CONFIG_DEBUG_RK3X_UART2 is not set
# CONFIG_DEBUG_RK3X_UART3 is not set
# CONFIG_DEBUG_RK32_UART2 is not set
# CONFIG_DEBUG_R7S72100_SCIF2 is not set
# CONFIG_DEBUG_R7S9210_SCIF2 is not set
# CONFIG_DEBUG_R7S9210_SCIF4 is not set
# CONFIG_DEBUG_RCAR_GEN1_SCIF0 is not set
# CONFIG_DEBUG_RCAR_GEN1_SCIF2 is not set
# CONFIG_DEBUG_RCAR_GEN2_SCIF0 is not set
# CONFIG_DEBUG_RCAR_GEN2_SCIF1 is not set
# CONFIG_DEBUG_RCAR_GEN2_SCIF2 is not set
# CONFIG_DEBUG_RCAR_GEN2_SCIF4 is not set
# CONFIG_DEBUG_RCAR_GEN2_SCIFA2 is not set
# CONFIG_DEBUG_RMOBILE_SCIFA0 is not set
# CONFIG_DEBUG_RMOBILE_SCIFA1 is not set
# CONFIG_DEBUG_RMOBILE_SCIFA4 is not set
# CONFIG_DEBUG_S3C_UART0 is not set
# CONFIG_DEBUG_S3C_UART1 is not set
# CONFIG_DEBUG_S3C_UART2 is not set
# CONFIG_DEBUG_S3C_UART3 is not set
# CONFIG_DEBUG_SOCFPGA_UART0 is not set
# CONFIG_DEBUG_SOCFPGA_ARRIA10_UART1 is not set
# CONFIG_DEBUG_SOCFPGA_CYCLONE5_UART1 is not set
# CONFIG_DEBUG_SUN9I_UART0 is not set
# CONFIG_DEBUG_SUNXI_UART0 is not set
# CONFIG_DEBUG_SUNXI_UART1 is not set
# CONFIG_DEBUG_SUNXI_R_UART is not set
# CONFIG_DEBUG_SPEAR13XX is not set
# CONFIG_DEBUG_STIH41X_ASC2 is not set
# CONFIG_DEBUG_STIH41X_SBC_ASC1 is not set
# CONFIG_DEBUG_STIH418_SBC_ASC0 is not set
# CONFIG_STM32MP1_DEBUG_UART is not set
# CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA is not set
# CONFIG_TEGRA_DEBUG_UARTA is not set
# CONFIG_TEGRA_DEBUG_UARTB is not set
# CONFIG_TEGRA_DEBUG_UARTC is not set
# CONFIG_TEGRA_DEBUG_UARTD is not set
# CONFIG_TEGRA_DEBUG_UARTE is not set
# CONFIG_DEBUG_UX500_UART is not set
# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
# CONFIG_DEBUG_VF_UART is not set
# CONFIG_DEBUG_VT8500_UART0 is not set
# CONFIG_DEBUG_ZYNQ_UART0 is not set
# CONFIG_DEBUG_ZYNQ_UART1 is not set
# CONFIG_DEBUG_ICEDCC is not set
# CONFIG_DEBUG_SEMIHOSTING is not set
# CONFIG_DEBUG_LL_UART_8250 is not set
# CONFIG_DEBUG_LL_UART_PL01X is not set
CONFIG_DEBUG_VF_UART_PORT=1
CONFIG_DEBUG_UART_FLOW_CONTROL=y
CONFIG_DEBUG_LL_INCLUDE="debug/palmchip.S"
CONFIG_DEBUG_UART_8250=y
CONFIG_DEBUG_UART_PHYS=0xfd883000
CONFIG_DEBUG_UART_VIRT=0xfd883000
CONFIG_DEBUG_UART_8250_SHIFT=2
CONFIG_DEBUG_UART_8250_WORD=y
CONFIG_DEBUG_UART_8250_PALMCHIP=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
CONFIG_ARM_KPROBES_TEST=y
CONFIG_PID_IN_CONTEXTIDR=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_LINKS_AND_SINKS=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_CATU=y
CONFIG_CORESIGHT_SINK_TPIU=y
CONFIG_CORESIGHT_SINK_ETBV10=y
CONFIG_CORESIGHT_SOURCE_ETM3X=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_CPU_DEBUG=y
CONFIG_CORESIGHT_CPU_DEBUG_DEFAULT_ON=y
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
# end of arm Debugging
#
# Kernel Testing and Coverage
#
CONFIG_KUNIT=y
CONFIG_KUNIT_DEBUGFS=y
CONFIG_KUNIT_TEST=y
CONFIG_KUNIT_EXAMPLE_TEST=y
CONFIG_KUNIT_ALL_TESTS=y
CONFIG_KUNIT_DEFAULT_ENABLED=y
CONFIG_NOTIFIER_ERROR_INJECTION=y
CONFIG_PM_NOTIFIER_ERROR_INJECT=y
CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT=y
CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=y
CONFIG_FUNCTION_ERROR_INJECTION=y
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_USERCOPY=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAIL_FUNCTION=y
CONFIG_FAIL_MMC_REQUEST=y
CONFIG_FAIL_SUNRPC=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_ARCH_HAS_KCOV=y
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
CONFIG_KCOV=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_IRQ_AREA_SIZE=0x40000
CONFIG_RUNTIME_TESTING_MENU=y
CONFIG_TEST_DHRY=y
CONFIG_LKDTM=y
CONFIG_CPUMASK_KUNIT_TEST=y
CONFIG_TEST_LIST_SORT=y
CONFIG_TEST_MIN_HEAP=y
CONFIG_TEST_SORT=y
CONFIG_TEST_DIV64=y
CONFIG_KPROBES_SANITY_TEST=y
CONFIG_BACKTRACE_SELF_TEST=y
CONFIG_TEST_REF_TRACKER=y
CONFIG_RBTREE_TEST=y
CONFIG_REED_SOLOMON_TEST=y
CONFIG_INTERVAL_TREE_TEST=y
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y
CONFIG_ASYNC_RAID6_TEST=y
CONFIG_TEST_HEXDUMP=y
CONFIG_STRING_SELFTEST=y
CONFIG_TEST_STRING_HELPERS=y
CONFIG_TEST_KSTRTOX=y
CONFIG_TEST_PRINTF=y
CONFIG_TEST_SCANF=y
CONFIG_TEST_BITMAP=y
CONFIG_TEST_UUID=y
CONFIG_TEST_XARRAY=y
CONFIG_TEST_MAPLE_TREE=y
CONFIG_TEST_RHASHTABLE=y
CONFIG_TEST_IDA=y
CONFIG_TEST_PARMAN=y
CONFIG_TEST_LKM=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
CONFIG_TEST_USER_COPY=m
CONFIG_TEST_BPF=m
CONFIG_TEST_BLACKHOLE_DEV=m
CONFIG_FIND_BIT_BENCHMARK=y
CONFIG_TEST_FIRMWARE=y
CONFIG_TEST_SYSCTL=y
CONFIG_BITFIELD_KUNIT=y
CONFIG_HASH_KUNIT_TEST=y
CONFIG_RESOURCE_KUNIT_TEST=y
CONFIG_SYSCTL_KUNIT_TEST=y
CONFIG_LIST_KUNIT_TEST=y
CONFIG_LINEAR_RANGES_TEST=y
CONFIG_CMDLINE_KUNIT_TEST=y
CONFIG_BITS_TEST=y
CONFIG_RATIONAL_KUNIT_TEST=y
CONFIG_MEMCPY_KUNIT_TEST=y
CONFIG_IS_SIGNED_TYPE_KUNIT_TEST=y
CONFIG_OVERFLOW_KUNIT_TEST=y
CONFIG_STACKINIT_KUNIT_TEST=y
CONFIG_FORTIFY_KUNIT_TEST=y
CONFIG_HW_BREAKPOINT_KUNIT_TEST=y
CONFIG_STRSCPY_KUNIT_TEST=y
CONFIG_SIPHASH_KUNIT_TEST=y
CONFIG_TEST_UDELAY=y
CONFIG_TEST_STATIC_KEYS=m
CONFIG_TEST_DYNAMIC_DEBUG=y
CONFIG_TEST_KMOD=m
CONFIG_TEST_DEBUG_VIRTUAL=y
CONFIG_TEST_MEMCAT_P=y
CONFIG_TEST_OBJAGG=y
CONFIG_TEST_MEMINIT=y
CONFIG_TEST_FREE_PAGES=y
CONFIG_ARCH_USE_MEMTEST=y
CONFIG_MEMTEST=y
# end of Kernel Testing and Coverage
#
# Rust hacking
#
# end of Rust hacking
CONFIG_WARN_MISSING_DOCUMENTS=y
CONFIG_WARN_ABI_ERRORS=y
# end of Kernel hacking
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array
2023-01-10 17:56 ` [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array Konrad Dybcio
@ 2023-01-13 1:26 ` Rob Herring
0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2023-01-13 1:26 UTC (permalink / raw)
To: Konrad Dybcio
Cc: linux-arm-msm, Krzysztof Kozlowski, linux-pm, marijn.suijten,
devicetree, andersson, agross, krzysztof.kozlowski,
angelogioacchino.delregno, Rob Herring, linux-kernel,
Viresh Kumar, Nishanth Menon, Niklas Cassel, Stephen Boyd
On Tue, 10 Jan 2023 18:56:02 +0100, Konrad Dybcio wrote:
> In some instances (particularly with CPRh) we might want to specifiy
> more than one qcom,opp-fuse-level, as the same OPP subnodes may be
> used by different "CPR threads". We need to make sure that
> n = num_threads entries is legal and so far nobody seems to use more
> than two, so let's allow that.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
> Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2023-01-13 1:26 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20230110175605.1240188-1-konrad.dybcio@linaro.org>
2023-01-10 17:56 ` [PATCH v8 1/5] dt-bindings: soc: qcom: cpr3: Add bindings for CPR3 driver Konrad Dybcio
2023-01-10 18:54 ` Konrad Dybcio
2023-01-11 2:18 ` Dmitry Baryshkov
2023-01-11 13:30 ` Konrad Dybcio
2023-01-11 15:58 ` Dmitry Baryshkov
2023-01-11 1:34 ` Rob Herring
2023-01-10 17:56 ` [PATCH v8 2/5] dt-bindings: opp: v2-qcom-level: Let qcom,opp-fuse-level be a 2-long array Konrad Dybcio
2023-01-13 1:26 ` Rob Herring
2023-01-10 17:56 ` [PATCH v8 3/5] soc: qcom: cpr: Move common functions to new file Konrad Dybcio
2023-01-10 17:56 ` [PATCH v8 4/5] soc: qcom: Add support for Core Power Reduction v3, v4 and Hardened Konrad Dybcio
2023-01-10 18:27 ` Robert Marko
2023-01-10 18:29 ` Konrad Dybcio
2023-01-10 18:42 ` Robert Marko
2023-01-10 18:43 ` Konrad Dybcio
2023-01-11 20:43 ` kernel test robot
2023-01-10 17:56 ` [PATCH v8 5/5] arm64: dts: qcom: msm8998: Configure CPRh Konrad Dybcio
2023-01-10 18:45 ` Konrad Dybcio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®