* [PATCH v9 2/7] dt-bindings: spmi: Deprecate qcom,bus-id
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa, Krzysztof Kozlowski
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
As it is optional and no platform is actually using the secondary bus,
deprecate the qcom,bus-id property. For newer platforms that implement
SPMI PMIC ARB v7 in HW, the X1E80100 approach should be used.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
index f983b4af6db9..51daf1b847a9 100644
--- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
@@ -92,6 +92,7 @@ properties:
description: >
SPMI bus instance. only applicable to PMIC arbiter version 7 and beyond.
Supported values, 0 = primary bus, 1 = secondary bus
+ deprecated: true
required:
- compatible
--
2.34.1
^ permalink raw reply related
* [PATCH v9 3/7] spmi: pmic-arb: Fix some compile warnings about members not being described
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
Fix the following compile warnings:
warning: Function parameter or struct member 'core' not described in 'spmi_pmic_arb'
warning: Function parameter or struct member 'core_size' not described in 'spmi_pmic_arb'
warning: Function parameter or struct member 'mapping_table_valid' not described in 'spmi_pmic_arb'
warning: Function parameter or struct member 'pmic_arb' not described in 'pmic_arb_read_data'
warning: Function parameter or struct member 'pmic_arb' not described in 'pmic_arb_write_data'
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/spmi/spmi-pmic-arb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..704fd4506971 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -132,6 +132,8 @@ struct apid_data {
* @wr_base: on v1 "core", on v2 "chnls" register base off DT.
* @intr: address of the SPMI interrupt control registers.
* @cnfg: address of the PMIC Arbiter configuration registers.
+ * @core: core register base for v2 and above only (see above)
+ * @core_size: core register base size
* @lock: lock to synchronize accesses.
* @channel: execution environment channel to use for accesses.
* @irq: PMIC ARB interrupt.
@@ -144,6 +146,7 @@ struct apid_data {
* @apid_count: on v5 and v7: number of APIDs associated with the
* particular SPMI bus instance
* @mapping_table: in-memory copy of PPID -> APID mapping table.
+ * @mapping_table_valid:bitmap containing valid-only periphs
* @domain: irq domain object for PMIC IRQ domain
* @spmic: SPMI controller object
* @ver_ops: version dependent operations.
@@ -232,6 +235,7 @@ static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb *pmic_arb,
/**
* pmic_arb_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
+ * @pmic_arb: the SPMI PMIC arbiter
* @bc: byte count -1. range: 0..3
* @reg: register's address
* @buf: output parameter, length must be bc + 1
@@ -246,6 +250,7 @@ pmic_arb_read_data(struct spmi_pmic_arb *pmic_arb, u8 *buf, u32 reg, u8 bc)
/**
* pmic_arb_write_data: write 1..4 bytes from buf to pmic-arb's register
+ * @pmic_arb: the SPMI PMIC arbiter
* @bc: byte-count -1. range: 0..3.
* @reg: register's address.
* @buf: buffer to write. length must be bc + 1.
--
2.34.1
^ permalink raw reply related
* [PATCH v9 4/7] spmi: pmic-arb: Make the APID init a version operation
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
Rather than using conditionals in probe function, add the APID init
as a version specific operation. Due to v7, which supports multiple
buses, pass on the bus index to be used for sorting out the apid base
and count.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/spmi/spmi-pmic-arb.c | 144 +++++++++++++++++++++----------------------
1 file changed, 69 insertions(+), 75 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 704fd4506971..dc969f8bed18 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -186,6 +186,7 @@ struct spmi_pmic_arb {
* struct pmic_arb_ver_ops - version dependent functionality.
*
* @ver_str: version string.
+ * @init_apid: finds the apid base and count
* @ppid_to_apid: finds the apid for a given ppid.
* @non_data_cmd: on v1 issues an spmi non-data command.
* on v2 no HW support, returns -EOPNOTSUPP.
@@ -205,6 +206,7 @@ struct spmi_pmic_arb {
*/
struct pmic_arb_ver_ops {
const char *ver_str;
+ int (*init_apid)(struct spmi_pmic_arb *pmic_arb);
int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
@@ -947,6 +949,32 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
return 0;
}
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+{
+ /*
+ * Initialize max_apid/min_apid to the opposite bounds, during
+ * the irq domain translation, we are sure to update these
+ */
+ pmic_arb->max_apid = 0;
+ pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+
+ return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb)
+{
+ u32 *mapping_table;
+
+ mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+ sizeof(*mapping_table), GFP_KERNEL);
+ if (!mapping_table)
+ return -ENOMEM;
+
+ pmic_arb->mapping_table = mapping_table;
+
+ return pmic_arb_init_apid_min_max(pmic_arb);
+}
+
static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
{
u32 *mapping_table = pmic_arb->mapping_table;
@@ -1149,6 +1177,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
return 0x1000 * pmic_arb->ee + 0x8000 * apid;
}
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb)
+{
+ int ret;
+
+ pmic_arb->base_apid = 0;
+ pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK;
+
+ if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+ dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+ pmic_arb->base_apid + pmic_arb->apid_count);
+ return -EINVAL;
+ }
+
+ ret = pmic_arb_init_apid_min_max(pmic_arb);
+ if (ret)
+ return ret;
+
+ ret = pmic_arb_read_apid_map_v5(pmic_arb);
+ if (ret) {
+ dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* v5 offset per ee and per apid for observer channels and per apid for
* read/write channels.
@@ -1363,6 +1419,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
.ver_str = "v1",
+ .init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v1,
.non_data_cmd = pmic_arb_non_data_cmd_v1,
.offset = pmic_arb_offset_v1,
@@ -1377,6 +1434,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
.ver_str = "v2",
+ .init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v2,
@@ -1391,6 +1449,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
.ver_str = "v3",
+ .init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v2,
@@ -1405,6 +1464,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
static const struct pmic_arb_ver_ops pmic_arb_v5 = {
.ver_str = "v5",
+ .init_apid = pmic_arb_init_apid_v5,
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v5,
@@ -1419,6 +1479,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
.ver_str = "v7",
+ .init_apid = pmic_arb_init_apid_v5,
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v7,
@@ -1444,7 +1505,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
struct spmi_controller *ctrl;
struct resource *res;
void __iomem *core;
- u32 *mapping_table;
u32 channel, ee, hw_ver;
int err;
@@ -1472,12 +1532,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
pmic_arb->core_size = resource_size(res);
- pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
- sizeof(*pmic_arb->ppid_to_apid),
- GFP_KERNEL);
- if (!pmic_arb->ppid_to_apid)
- return -ENOMEM;
-
hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1511,58 +1565,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
return PTR_ERR(pmic_arb->wr_base);
}
- pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+ dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+ pmic_arb->ver_ops->ver_str, hw_ver);
- if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+ if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+ pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+ else
pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
- /* Optional property for v7: */
- of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
- &pmic_arb->bus_instance);
- if (pmic_arb->bus_instance > 1) {
- dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
- pmic_arb->bus_instance);
- return -EINVAL;
- }
- if (pmic_arb->bus_instance == 0) {
- pmic_arb->base_apid = 0;
- pmic_arb->apid_count =
- readl_relaxed(core + PMIC_ARB_FEATURES) &
- PMIC_ARB_FEATURES_PERIPH_MASK;
- } else {
- pmic_arb->base_apid =
- readl_relaxed(core + PMIC_ARB_FEATURES) &
- PMIC_ARB_FEATURES_PERIPH_MASK;
- pmic_arb->apid_count =
- readl_relaxed(core + PMIC_ARB_FEATURES1) &
- PMIC_ARB_FEATURES_PERIPH_MASK;
- }
-
- if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
- dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
- pmic_arb->base_apid + pmic_arb->apid_count);
- return -EINVAL;
- }
- } else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
- pmic_arb->base_apid = 0;
- pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
- PMIC_ARB_FEATURES_PERIPH_MASK;
-
- if (pmic_arb->apid_count > pmic_arb->max_periphs) {
- dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
- pmic_arb->apid_count);
- return -EINVAL;
- }
- }
-
- pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
- sizeof(*pmic_arb->apid_data),
- GFP_KERNEL);
- if (!pmic_arb->apid_data)
- return -ENOMEM;
-
- dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
- pmic_arb->ver_ops->ver_str, hw_ver);
+ err = pmic_arb->ver_ops->init_apid(pmic_arb);
+ if (err)
+ return err;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
@@ -1604,16 +1617,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
}
pmic_arb->ee = ee;
- mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
- sizeof(*mapping_table), GFP_KERNEL);
- if (!mapping_table)
- return -ENOMEM;
-
- pmic_arb->mapping_table = mapping_table;
- /* Initialize max_apid/min_apid to the opposite bounds, during
- * the irq domain translation, we are sure to update these */
- pmic_arb->max_apid = 0;
- pmic_arb->min_apid = pmic_arb->max_periphs - 1;
platform_set_drvdata(pdev, ctrl);
raw_spin_lock_init(&pmic_arb->lock);
@@ -1622,15 +1625,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
ctrl->read_cmd = pmic_arb_read_cmd;
ctrl->write_cmd = pmic_arb_write_cmd;
- if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
- err = pmic_arb_read_apid_map_v5(pmic_arb);
- if (err) {
- dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
- err);
- return err;
- }
- }
-
dev_dbg(&pdev->dev, "adding irq domain\n");
pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
&pmic_arb_irq_domain_ops, pmic_arb);
--
2.34.1
^ permalink raw reply related
* [PATCH v9 5/7] spmi: pmic-arb: Make core resources acquiring a version operation
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
Rather than setting up the core, obsrv and chnls in probe by using
version specific conditionals, add a dedicated "get_core_resources"
version specific op and move the acquiring in there. Since there are
no current users of the second bus yet, drop the comment about why
devm_platform_ioremap_resource can't be used in case of "core",
as it is not applicable anymore.
Don't switch to devm_platform_ioremap_resource though as we need
to keep track of core size.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/spmi/spmi-pmic-arb.c | 114 +++++++++++++++++++++++++++----------------
1 file changed, 71 insertions(+), 43 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index dc969f8bed18..ff777b4a6f33 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -186,6 +186,7 @@ struct spmi_pmic_arb {
* struct pmic_arb_ver_ops - version dependent functionality.
*
* @ver_str: version string.
+ * @get_core_resources: initializes the core, observer and channels
* @init_apid: finds the apid base and count
* @ppid_to_apid: finds the apid for a given ppid.
* @non_data_cmd: on v1 issues an spmi non-data command.
@@ -206,6 +207,7 @@ struct spmi_pmic_arb {
*/
struct pmic_arb_ver_ops {
const char *ver_str;
+ int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
int (*init_apid)(struct spmi_pmic_arb *pmic_arb);
int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -961,6 +963,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
return 0;
}
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+ void __iomem *core)
+{
+ struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+ pmic_arb->wr_base = core;
+ pmic_arb->rd_base = core;
+
+ pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+ return 0;
+}
+
static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb)
{
u32 *mapping_table;
@@ -1062,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
return apid;
}
+static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
+{
+ struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+ pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr");
+ if (IS_ERR(pmic_arb->rd_base))
+ return PTR_ERR(pmic_arb->rd_base);
+
+ pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls");
+ if (IS_ERR(pmic_arb->wr_base))
+ return PTR_ERR(pmic_arb->wr_base);
+
+ return 0;
+}
+
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+ void __iomem *core)
+{
+ struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+ pmic_arb->core = core;
+
+ pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+ return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
{
u16 apid_valid;
@@ -1239,6 +1281,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
return offset;
}
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+ void __iomem *core)
+{
+ struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+ pmic_arb->core = core;
+
+ pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+ return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
/*
* v7 offset per ee and per apid for observer channels and per apid for
* read/write channels.
@@ -1419,6 +1473,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
.ver_str = "v1",
+ .get_core_resources = pmic_arb_get_core_resources_v1,
.init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v1,
.non_data_cmd = pmic_arb_non_data_cmd_v1,
@@ -1434,6 +1489,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
.ver_str = "v2",
+ .get_core_resources = pmic_arb_get_core_resources_v2,
.init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
@@ -1449,6 +1505,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
.ver_str = "v3",
+ .get_core_resources = pmic_arb_get_core_resources_v2,
.init_apid = pmic_arb_init_apid_v1,
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
@@ -1464,6 +1521,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
static const struct pmic_arb_ver_ops pmic_arb_v5 = {
.ver_str = "v5",
+ .get_core_resources = pmic_arb_get_core_resources_v2,
.init_apid = pmic_arb_init_apid_v5,
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
@@ -1479,6 +1537,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
.ver_str = "v7",
+ .get_core_resources = pmic_arb_get_core_resources_v7,
.init_apid = pmic_arb_init_apid_v5,
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
@@ -1515,16 +1574,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
pmic_arb = spmi_controller_get_drvdata(ctrl);
pmic_arb->spmic = ctrl;
- /*
- * Please don't replace this with devm_platform_ioremap_resource() or
- * devm_ioremap_resource(). These both result in a call to
- * devm_request_mem_region() which prevents multiple mappings of this
- * register address range. SoCs with PMIC arbiter v7 may define two
- * arbiter devices, for the two physical SPMI interfaces, which share
- * some register address ranges (i.e. "core", "obsrvr", and "chnls").
- * Ensure that both devices probe successfully by calling devm_ioremap()
- * which does not result in a devm_request_mem_region() call.
- */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
if (IS_ERR(core))
@@ -1534,44 +1583,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
- if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+ if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
pmic_arb->ver_ops = &pmic_arb_v1;
- pmic_arb->wr_base = core;
- pmic_arb->rd_base = core;
- } else {
- pmic_arb->core = core;
-
- if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
- pmic_arb->ver_ops = &pmic_arb_v2;
- else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
- pmic_arb->ver_ops = &pmic_arb_v3;
- else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
- pmic_arb->ver_ops = &pmic_arb_v5;
- else
- pmic_arb->ver_ops = &pmic_arb_v7;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "obsrvr");
- pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
- resource_size(res));
- if (IS_ERR(pmic_arb->rd_base))
- return PTR_ERR(pmic_arb->rd_base);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "chnls");
- pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
- resource_size(res));
- if (IS_ERR(pmic_arb->wr_base))
- return PTR_ERR(pmic_arb->wr_base);
- }
+ else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+ pmic_arb->ver_ops = &pmic_arb_v2;
+ else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+ pmic_arb->ver_ops = &pmic_arb_v3;
+ else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+ pmic_arb->ver_ops = &pmic_arb_v5;
+ else
+ pmic_arb->ver_ops = &pmic_arb_v7;
dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
pmic_arb->ver_ops->ver_str, hw_ver);
- if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
- pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
- else
- pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+ err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+ if (err)
+ return err;
err = pmic_arb->ver_ops->init_apid(pmic_arb);
if (err)
--
2.34.1
^ permalink raw reply related
* [PATCH v9 6/7] spmi: pmic-arb: Register controller for bus instead of arbiter
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
Introduce the bus object in order to decouple the resources
that are bus specific from the arbiter. This way the SPMI controller
is registered with the generic framework at a bus level rather than
arbiter. This is needed in order to prepare for multi bus support.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/spmi/spmi-pmic-arb.c | 659 ++++++++++++++++++++++++-------------------
1 file changed, 374 insertions(+), 285 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index ff777b4a6f33..65d8f45da24b 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spmi.h>
@@ -125,61 +126,72 @@ struct apid_data {
u8 irq_ee;
};
+struct spmi_pmic_arb;
+
/**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
*
- * @rd_base: on v1 "core", on v2 "observer" register base off DT.
- * @wr_base: on v1 "core", on v2 "chnls" register base off DT.
+ * @pmic_arb: the SPMI PMIC Arbiter the bus belongs to.
+ * @domain: irq domain object for PMIC IRQ domain
* @intr: address of the SPMI interrupt control registers.
* @cnfg: address of the PMIC Arbiter configuration registers.
- * @core: core register base for v2 and above only (see above)
- * @core_size: core register base size
+ * @spmic: spmi controller registered for this bus
* @lock: lock to synchronize accesses.
- * @channel: execution environment channel to use for accesses.
- * @irq: PMIC ARB interrupt.
- * @ee: the current Execution Environment
- * @bus_instance: on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid: minimum APID (used for bounding IRQ search)
- * @max_apid: maximum APID
* @base_apid: on v7: minimum APID associated with the particular SPMI
* bus instance
* @apid_count: on v5 and v7: number of APIDs associated with the
* particular SPMI bus instance
* @mapping_table: in-memory copy of PPID -> APID mapping table.
* @mapping_table_valid:bitmap containing valid-only periphs
- * @domain: irq domain object for PMIC IRQ domain
- * @spmic: SPMI controller object
- * @ver_ops: version dependent operations.
* @ppid_to_apid: in-memory copy of PPID -> APID mapping table.
* @last_apid: Highest value APID in use
* @apid_data: Table of data for all APIDs
- * @max_periphs: Number of elements in apid_data[]
+ * @min_apid: minimum APID (used for bounding IRQ search)
+ * @max_apid: maximum APID
+ * @irq: PMIC ARB interrupt.
*/
-struct spmi_pmic_arb {
- void __iomem *rd_base;
- void __iomem *wr_base;
+struct spmi_pmic_arb_bus {
+ struct spmi_pmic_arb *pmic_arb;
+ struct irq_domain *domain;
void __iomem *intr;
void __iomem *cnfg;
- void __iomem *core;
- resource_size_t core_size;
+ struct spmi_controller *spmic;
raw_spinlock_t lock;
- u8 channel;
- int irq;
- u8 ee;
- u32 bus_instance;
- u16 min_apid;
- u16 max_apid;
u16 base_apid;
int apid_count;
u32 *mapping_table;
DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
- struct irq_domain *domain;
- struct spmi_controller *spmic;
- const struct pmic_arb_ver_ops *ver_ops;
u16 *ppid_to_apid;
u16 last_apid;
struct apid_data *apid_data;
+ u16 min_apid;
+ u16 max_apid;
+ int irq;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base: on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base: on v1 "core", on v2 "chnls" register base off DT.
+ * @core: core register base for v2 and above only (see above)
+ * @core_size: core register base size
+ * @channel: execution environment channel to use for accesses.
+ * @ee: the current Execution Environment
+ * @ver_ops: version dependent operations.
+ * @max_periphs: Number of elements in apid_data[]
+ * @bus: per arbiter bus instance
+ */
+struct spmi_pmic_arb {
+ void __iomem *rd_base;
+ void __iomem *wr_base;
+ void __iomem *core;
+ resource_size_t core_size;
+ u8 channel;
+ u8 ee;
+ const struct pmic_arb_ver_ops *ver_ops;
int max_periphs;
+ struct spmi_pmic_arb_bus *bus;
};
/**
@@ -208,21 +220,21 @@ struct spmi_pmic_arb {
struct pmic_arb_ver_ops {
const char *ver_str;
int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
- int (*init_apid)(struct spmi_pmic_arb *pmic_arb);
- int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+ int (*init_apid)(struct spmi_pmic_arb_bus *bus);
+ int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
- int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
- enum pmic_arb_channel ch_type);
+ int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type);
u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
/* Interrupts controller functionality (offset of PIC registers) */
- void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+ void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
u16 n);
- void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
- void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
- void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+ void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+ void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+ void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
u32 (*apid_map_offset)(u16 n);
- void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+ void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
};
static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -272,13 +284,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
void __iomem *base, u8 sid, u16 addr,
enum pmic_arb_channel ch_type)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u32 status = 0;
u32 timeout = PMIC_ARB_TIMEOUT_US;
u32 offset;
int rc;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+ rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
if (rc < 0)
return rc;
@@ -321,24 +334,25 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
static int
pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
unsigned long flags;
u32 cmd;
int rc;
u32 offset;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+ rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
if (rc < 0)
return rc;
offset = rc;
cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
- raw_spin_lock_irqsave(&pmic_arb->lock, flags);
+ raw_spin_lock_irqsave(&bus->lock, flags);
pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0,
PMIC_ARB_CHANNEL_RW);
- raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ raw_spin_unlock_irqrestore(&bus->lock, flags);
return rc;
}
@@ -363,20 +377,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
}
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
u16 addr, size_t len, u32 *cmd, u32 *offset)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u8 bc = len - 1;
int rc;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+ rc = pmic_arb->ver_ops->offset(bus, sid, addr,
PMIC_ARB_CHANNEL_OBS);
if (rc < 0)
return rc;
*offset = rc;
if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
- dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+ dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
PMIC_ARB_MAX_TRANS_BYTES, len);
return -EINVAL;
}
@@ -400,7 +415,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
u32 offset, u8 sid, u16 addr, u8 *buf,
size_t len)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u8 bc = len - 1;
int rc;
@@ -422,38 +438,39 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
u16 addr, u8 *buf, size_t len)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
unsigned long flags;
u32 cmd, offset;
int rc;
- rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+ rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
&offset);
if (rc)
return rc;
- raw_spin_lock_irqsave(&pmic_arb->lock, flags);
+ raw_spin_lock_irqsave(&bus->lock, flags);
rc = pmic_arb_read_cmd_unlocked(ctrl, cmd, offset, sid, addr, buf, len);
- raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ raw_spin_unlock_irqrestore(&bus->lock, flags);
return rc;
}
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
u8 sid, u16 addr, size_t len, u32 *cmd,
u32 *offset)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u8 bc = len - 1;
int rc;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+ rc = pmic_arb->ver_ops->offset(bus, sid, addr,
PMIC_ARB_CHANNEL_RW);
if (rc < 0)
return rc;
*offset = rc;
if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
- dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+ dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
PMIC_ARB_MAX_TRANS_BYTES, len);
return -EINVAL;
}
@@ -479,7 +496,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
u32 offset, u8 sid, u16 addr,
const u8 *buf, size_t len)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u8 bc = len - 1;
/* Write data to FIFOs */
@@ -498,20 +516,20 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
u16 addr, const u8 *buf, size_t len)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
unsigned long flags;
u32 cmd, offset;
int rc;
- rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+ rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
&offset);
if (rc)
return rc;
- raw_spin_lock_irqsave(&pmic_arb->lock, flags);
+ raw_spin_lock_irqsave(&bus->lock, flags);
rc = pmic_arb_write_cmd_unlocked(ctrl, cmd, offset, sid, addr, buf,
len);
- raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ raw_spin_unlock_irqrestore(&bus->lock, flags);
return rc;
}
@@ -519,23 +537,23 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
const u8 *buf, const u8 *mask, size_t len)
{
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+ struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
u32 read_cmd, read_offset, write_cmd, write_offset;
u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
unsigned long flags;
int rc, i;
- rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+ rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
&read_cmd, &read_offset);
if (rc)
return rc;
- rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+ rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
len, &write_cmd, &write_offset);
if (rc)
return rc;
- raw_spin_lock_irqsave(&pmic_arb->lock, flags);
+ raw_spin_lock_irqsave(&bus->lock, flags);
rc = pmic_arb_read_cmd_unlocked(ctrl, read_cmd, read_offset, sid, addr,
temp, len);
if (rc)
@@ -547,7 +565,7 @@ static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
rc = pmic_arb_write_cmd_unlocked(ctrl, write_cmd, write_offset, sid,
addr, temp, len);
done:
- raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ raw_spin_unlock_irqrestore(&bus->lock, flags);
return rc;
}
@@ -573,25 +591,25 @@ struct spmi_pmic_arb_qpnpint_type {
static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
size_t len)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
u8 sid = hwirq_to_sid(d->hwirq);
u8 per = hwirq_to_per(d->hwirq);
- if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+ if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
(per << 8) + reg, buf, len))
- dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+ dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
d->irq);
}
static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
u8 sid = hwirq_to_sid(d->hwirq);
u8 per = hwirq_to_per(d->hwirq);
- if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+ if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
(per << 8) + reg, buf, len))
- dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+ dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
d->irq);
}
@@ -599,47 +617,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
const void *buf, const void *mask,
size_t len)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
u8 sid = hwirq_to_sid(d->hwirq);
u8 per = hwirq_to_per(d->hwirq);
int rc;
- rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+ rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
mask, len);
if (rc)
- dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+ dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
d->irq, rc);
return rc;
}
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
{
- u16 ppid = pmic_arb->apid_data[apid].ppid;
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+ u16 ppid = bus->apid_data[apid].ppid;
u8 sid = ppid >> 8;
u8 per = ppid & 0xFF;
u8 irq_mask = BIT(id);
- dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
- __func__, apid, sid, per, id);
- writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+ dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+ __func__, apid, sid, per, id);
+ writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
}
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
unsigned int irq;
u32 status, id;
int handled = 0;
- u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
- u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+ u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+ u8 per = bus->apid_data[apid].ppid & 0xFF;
- status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+ status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
while (status) {
id = ffs(status) - 1;
status &= ~BIT(id);
- irq = irq_find_mapping(pmic_arb->domain,
- spec_to_hwirq(sid, per, id, apid));
+ irq = irq_find_mapping(bus->domain,
+ spec_to_hwirq(sid, per, id, apid));
if (irq == 0) {
- cleanup_irq(pmic_arb, apid, id);
+ cleanup_irq(bus, apid, id);
continue;
}
generic_handle_irq(irq);
@@ -651,16 +671,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
static void pmic_arb_chained_irq(struct irq_desc *desc)
{
- struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+ struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
struct irq_chip *chip = irq_desc_get_chip(desc);
- int first = pmic_arb->min_apid;
- int last = pmic_arb->max_apid;
+ int first = bus->min_apid;
+ int last = bus->max_apid;
/*
* acc_offset will be non-zero for the secondary SPMI bus instance on
* v7 controllers.
*/
- int acc_offset = pmic_arb->base_apid >> 5;
+ int acc_offset = bus->base_apid >> 5;
u8 ee = pmic_arb->ee;
u32 status, enable, handled = 0;
int i, id, apid;
@@ -671,7 +692,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
chained_irq_enter(chip, desc);
for (i = first >> 5; i <= last >> 5; ++i) {
- status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+ status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
if (status)
acc_valid = true;
@@ -685,9 +706,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
continue;
}
enable = readl_relaxed(
- ver_ops->acc_enable(pmic_arb, apid));
+ ver_ops->acc_enable(bus, apid));
if (enable & SPMI_PIC_ACC_ENABLE_BIT)
- if (periph_interrupt(pmic_arb, apid) != 0)
+ if (periph_interrupt(bus, apid) != 0)
handled++;
}
}
@@ -696,19 +717,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
if (!acc_valid) {
for (i = first; i <= last; i++) {
/* skip if APPS is not irq owner */
- if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+ if (bus->apid_data[i].irq_ee != pmic_arb->ee)
continue;
irq_status = readl_relaxed(
- ver_ops->irq_status(pmic_arb, i));
+ ver_ops->irq_status(bus, i));
if (irq_status) {
enable = readl_relaxed(
- ver_ops->acc_enable(pmic_arb, i));
+ ver_ops->acc_enable(bus, i));
if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
- dev_dbg(&pmic_arb->spmic->dev,
+ dev_dbg(&bus->spmic->dev,
"Dispatching IRQ for apid=%d status=%x\n",
i, irq_status);
- if (periph_interrupt(pmic_arb, i) != 0)
+ if (periph_interrupt(bus, i) != 0)
handled++;
}
}
@@ -723,12 +744,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
static void qpnpint_irq_ack(struct irq_data *d)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u8 irq = hwirq_to_irq(d->hwirq);
u16 apid = hwirq_to_apid(d->hwirq);
u8 data;
- writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+ writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
data = BIT(irq);
qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -744,14 +766,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
static void qpnpint_irq_unmask(struct irq_data *d)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
u8 irq = hwirq_to_irq(d->hwirq);
u16 apid = hwirq_to_apid(d->hwirq);
u8 buf[2];
writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
- ver_ops->acc_enable(pmic_arb, apid));
+ ver_ops->acc_enable(bus, apid));
qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
if (!(buf[0] & BIT(irq))) {
@@ -808,9 +831,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
- return irq_set_irq_wake(pmic_arb->irq, on);
+ return irq_set_irq_wake(bus->irq, on);
}
static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -832,17 +855,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
static int qpnpint_irq_domain_activate(struct irq_domain *domain,
struct irq_data *d, bool reserve)
{
- struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u16 periph = hwirq_to_per(d->hwirq);
u16 apid = hwirq_to_apid(d->hwirq);
u16 sid = hwirq_to_sid(d->hwirq);
u16 irq = hwirq_to_irq(d->hwirq);
u8 buf;
- if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
- dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+ if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+ dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
sid, periph, irq, pmic_arb->ee,
- pmic_arb->apid_data[apid].irq_ee);
+ bus->apid_data[apid].irq_ee);
return -ENODEV;
}
@@ -869,15 +893,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
unsigned long *out_hwirq,
unsigned int *out_type)
{
- struct spmi_pmic_arb *pmic_arb = d->host_data;
+ struct spmi_pmic_arb_bus *bus = d->host_data;
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u32 *intspec = fwspec->param;
u16 apid, ppid;
int rc;
- dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+ dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
intspec[0], intspec[1], intspec[2]);
- if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+ if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
return -EINVAL;
if (fwspec->param_count != 4)
return -EINVAL;
@@ -885,37 +910,37 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
return -EINVAL;
ppid = intspec[0] << 8 | intspec[1];
- rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+ rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
if (rc < 0) {
- dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
- intspec[0], intspec[1], intspec[2], rc);
+ dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+ intspec[0], intspec[1], intspec[2], rc);
return rc;
}
apid = rc;
/* Keep track of {max,min}_apid for bounding search during interrupt */
- if (apid > pmic_arb->max_apid)
- pmic_arb->max_apid = apid;
- if (apid < pmic_arb->min_apid)
- pmic_arb->min_apid = apid;
+ if (apid > bus->max_apid)
+ bus->max_apid = apid;
+ if (apid < bus->min_apid)
+ bus->min_apid = apid;
*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
*out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
- dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+ dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
return 0;
}
static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq, unsigned int type)
{
irq_flow_handler_t handler;
- dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+ dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
virq, hwirq, type);
if (type & IRQ_TYPE_EDGE_BOTH)
@@ -926,7 +951,7 @@ static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
irq_set_lockdep_class(virq, &qpnpint_irq_lock_class,
&qpnpint_irq_request_class);
- irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, pmic_arb,
+ irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, bus,
handler, NULL, NULL);
}
@@ -934,7 +959,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
unsigned int virq, unsigned int nr_irqs,
void *data)
{
- struct spmi_pmic_arb *pmic_arb = domain->host_data;
+ struct spmi_pmic_arb_bus *bus = domain->host_data;
struct irq_fwspec *fwspec = data;
irq_hw_number_t hwirq;
unsigned int type;
@@ -945,20 +970,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
return ret;
for (i = 0; i < nr_irqs; i++)
- qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+ qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
type);
return 0;
}
-static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
/*
* Initialize max_apid/min_apid to the opposite bounds, during
* the irq domain translation, we are sure to update these
*/
- pmic_arb->max_apid = 0;
- pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+ bus->max_apid = 0;
+ bus->min_apid = pmic_arb->max_periphs - 1;
return 0;
}
@@ -976,37 +1003,38 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
return 0;
}
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u32 *mapping_table;
- mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+ mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
sizeof(*mapping_table), GFP_KERNEL);
if (!mapping_table)
return -ENOMEM;
- pmic_arb->mapping_table = mapping_table;
+ bus->mapping_table = mapping_table;
- return pmic_arb_init_apid_min_max(pmic_arb);
+ return pmic_arb_init_apid_min_max(bus);
}
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
{
- u32 *mapping_table = pmic_arb->mapping_table;
+ u32 *mapping_table = bus->mapping_table;
int index = 0, i;
u16 apid_valid;
u16 apid;
u32 data;
- apid_valid = pmic_arb->ppid_to_apid[ppid];
+ apid_valid = bus->ppid_to_apid[ppid];
if (apid_valid & PMIC_ARB_APID_VALID) {
apid = apid_valid & ~PMIC_ARB_APID_VALID;
return apid;
}
for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
- if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
- mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+ if (!test_and_set_bit(index, bus->mapping_table_valid))
+ mapping_table[index] = readl_relaxed(bus->cnfg +
SPMI_MAPPING_TABLE_REG(index));
data = mapping_table[index];
@@ -1016,9 +1044,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
} else {
apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
- pmic_arb->ppid_to_apid[ppid]
+ bus->ppid_to_apid[ppid]
= apid | PMIC_ARB_APID_VALID;
- pmic_arb->apid_data[apid].ppid = ppid;
+ bus->apid_data[apid].ppid = ppid;
return apid;
}
} else {
@@ -1026,9 +1054,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
} else {
apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
- pmic_arb->ppid_to_apid[ppid]
+ bus->ppid_to_apid[ppid]
= apid | PMIC_ARB_APID_VALID;
- pmic_arb->apid_data[apid].ppid = ppid;
+ bus->apid_data[apid].ppid = ppid;
return apid;
}
}
@@ -1038,24 +1066,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
}
/* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
- enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return 0x800 + 0x80 * pmic_arb->channel;
}
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
{
- struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+ struct apid_data *apidd = &bus->apid_data[bus->last_apid];
u32 regval, offset;
u16 id, apid;
- for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+ for (apid = bus->last_apid; ; apid++, apidd++) {
offset = pmic_arb->ver_ops->apid_map_offset(apid);
if (offset >= pmic_arb->core_size)
break;
- regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+ regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
apid));
apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
apidd->write_ee = apidd->irq_ee;
@@ -1065,14 +1095,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
continue;
id = (regval >> 8) & PMIC_ARB_PPID_MASK;
- pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+ bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
apidd->ppid = id;
if (id == ppid) {
apid |= PMIC_ARB_APID_VALID;
break;
}
}
- pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+ bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
return apid;
}
@@ -1104,21 +1134,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
return pmic_arb_get_obsrvr_chnls_v2(pdev);
}
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
{
u16 apid_valid;
- apid_valid = pmic_arb->ppid_to_apid[ppid];
+ apid_valid = bus->ppid_to_apid[ppid];
if (!(apid_valid & PMIC_ARB_APID_VALID))
- apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+ apid_valid = pmic_arb_find_apid(bus, ppid);
if (!(apid_valid & PMIC_ARB_APID_VALID))
return -ENODEV;
return apid_valid & ~PMIC_ARB_APID_VALID;
}
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
struct apid_data *apidd;
struct apid_data *prev_apidd;
u16 i, apid, ppid, apid_max;
@@ -1140,9 +1171,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
* where N = number of APIDs supported by the primary bus and
* M = number of APIDs supported by the secondary bus
*/
- apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
- apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
- for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+ apidd = &bus->apid_data[bus->base_apid];
+ apid_max = bus->base_apid + bus->apid_count;
+ for (i = bus->base_apid; i < apid_max; i++, apidd++) {
offset = pmic_arb->ver_ops->apid_map_offset(i);
if (offset >= pmic_arb->core_size)
break;
@@ -1153,19 +1184,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
- regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
- i));
+ regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
- valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
- apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
- prev_apidd = &pmic_arb->apid_data[apid];
+ valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+ apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+ prev_apidd = &bus->apid_data[apid];
if (!valid || apidd->write_ee == pmic_arb->ee) {
/* First PPID mapping or one for this EE */
- pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+ bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
} else if (valid && is_irq_ee &&
prev_apidd->write_ee == pmic_arb->ee) {
/*
@@ -1176,42 +1206,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
}
apidd->ppid = ppid;
- pmic_arb->last_apid = i;
+ bus->last_apid = i;
}
/* Dump the mapping table for debug purposes. */
- dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+ dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
- apid = pmic_arb->ppid_to_apid[ppid];
+ apid = bus->ppid_to_apid[ppid];
if (apid & PMIC_ARB_APID_VALID) {
apid &= ~PMIC_ARB_APID_VALID;
- apidd = &pmic_arb->apid_data[apid];
- dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
- ppid, apid, apidd->write_ee, apidd->irq_ee);
+ apidd = &bus->apid_data[apid];
+ dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+ ppid, apid, apidd->write_ee, apidd->irq_ee);
}
}
return 0;
}
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
{
- if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+ if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
return -ENODEV;
- return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+ return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
}
/* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
- enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u16 apid;
u16 ppid;
int rc;
ppid = sid << 8 | ((addr >> 8) & 0xFF);
- rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+ rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
if (rc < 0)
return rc;
@@ -1219,27 +1250,28 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
return 0x1000 * pmic_arb->ee + 0x8000 * apid;
}
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
int ret;
- pmic_arb->base_apid = 0;
- pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
- PMIC_ARB_FEATURES_PERIPH_MASK;
+ bus->base_apid = 0;
+ bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK;
- if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
- dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
- pmic_arb->base_apid + pmic_arb->apid_count);
+ if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+ dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+ bus->base_apid + bus->apid_count);
return -EINVAL;
}
- ret = pmic_arb_init_apid_min_max(pmic_arb);
+ ret = pmic_arb_init_apid_min_max(bus);
if (ret)
return ret;
- ret = pmic_arb_read_apid_map_v5(pmic_arb);
+ ret = pmic_arb_read_apid_map_v5(bus);
if (ret) {
- dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+ dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
ret);
return ret;
}
@@ -1251,15 +1283,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb)
* v5 offset per ee and per apid for observer channels and per apid for
* read/write channels.
*/
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
- enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u16 apid;
int rc;
u32 offset = 0;
u16 ppid = (sid << 8) | (addr >> 8);
- rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+ rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
if (rc < 0)
return rc;
@@ -1269,8 +1302,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
break;
case PMIC_ARB_CHANNEL_RW:
- if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
- dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+ if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+ dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
sid, addr);
return -EPERM;
}
@@ -1297,15 +1330,16 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
* v7 offset per ee and per apid for observer channels and per apid for
* read/write channels.
*/
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
- enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u16 apid;
int rc;
u32 offset = 0;
u16 ppid = (sid << 8) | (addr >> 8);
- rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+ rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
if (rc < 0)
return rc;
@@ -1315,8 +1349,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
break;
case PMIC_ARB_CHANNEL_RW:
- if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
- dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+ if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+ dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
sid, addr);
return -EPERM;
}
@@ -1338,104 +1372,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
}
static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
{
- return pmic_arb->intr + 0x20 * m + 0x4 * n;
+ return bus->intr + 0x20 * m + 0x4 * n;
}
static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
{
- return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+ return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
}
static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
{
- return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+ return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
}
static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
{
- return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+ return bus->intr + 0x10000 * m + 0x4 * n;
}
static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
{
- return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+ return bus->intr + 0x1000 * m + 0x4 * n;
}
static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0x200 + 0x4 * n;
+ return bus->intr + 0x200 + 0x4 * n;
}
static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0x1000 * n;
+ return bus->intr + 0x1000 * n;
}
static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x100 + 0x10000 * n;
}
static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x100 + 0x1000 * n;
}
static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0x600 + 0x4 * n;
+ return bus->intr + 0x600 + 0x4 * n;
}
static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0x4 + 0x1000 * n;
+ return bus->intr + 0x4 + 0x1000 * n;
}
static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x104 + 0x10000 * n;
}
static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x104 + 0x1000 * n;
}
static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0xA00 + 0x4 * n;
+ return bus->intr + 0xA00 + 0x4 * n;
}
static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->intr + 0x8 + 0x1000 * n;
+ return bus->intr + 0x8 + 0x1000 * n;
}
static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x108 + 0x10000 * n;
}
static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
return pmic_arb->wr_base + 0x108 + 0x1000 * n;
}
@@ -1455,9 +1495,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
}
static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->cnfg + 0x700 + 0x4 * n;
+ return bus->cnfg + 0x700 + 0x4 * n;
}
/*
@@ -1466,9 +1506,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
* 0.
*/
static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
{
- return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+ return bus->cnfg + 0x4 * (n - bus->base_apid);
}
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
@@ -1558,29 +1598,121 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
.translate = qpnpint_irq_domain_translate,
};
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+ struct device_node *node,
+ struct spmi_pmic_arb *pmic_arb)
+{
+ struct spmi_pmic_arb_bus *bus;
+ struct device *dev = &pdev->dev;
+ struct spmi_controller *ctrl;
+ void __iomem *intr;
+ void __iomem *cnfg;
+ int index, ret;
+ u32 irq;
+
+ ctrl = devm_spmi_controller_alloc(dev, sizeof(*bus));
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
+
+ ctrl->cmd = pmic_arb_cmd;
+ ctrl->read_cmd = pmic_arb_read_cmd;
+ ctrl->write_cmd = pmic_arb_write_cmd;
+
+ bus = spmi_controller_get_drvdata(ctrl);
+
+ pmic_arb->bus = bus;
+
+ raw_spin_lock_init(&bus->lock);
+
+ bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+ sizeof(*bus->ppid_to_apid),
+ GFP_KERNEL);
+ if (!bus->ppid_to_apid)
+ return -ENOMEM;
+
+ bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+ sizeof(*bus->apid_data),
+ GFP_KERNEL);
+ if (!bus->apid_data)
+ return -ENOMEM;
+
+ index = of_property_match_string(node, "reg-names", "cnfg");
+ if (index < 0) {
+ dev_err(dev, "cnfg reg region missing");
+ return -EINVAL;
+ }
+
+ cnfg = devm_of_iomap(dev, node, index, NULL);
+ if (IS_ERR(cnfg))
+ return PTR_ERR(cnfg);
+
+ index = of_property_match_string(node, "reg-names", "intr");
+ if (index < 0) {
+ dev_err(dev, "intr reg region missing");
+ return -EINVAL;
+ }
+
+ intr = devm_of_iomap(dev, node, index, NULL);
+ if (IS_ERR(intr))
+ return PTR_ERR(intr);
+
+ irq = of_irq_get_byname(node, "periph_irq");
+ if (irq < 0)
+ return irq;
+
+ bus->pmic_arb = pmic_arb;
+ bus->intr = intr;
+ bus->cnfg = cnfg;
+ bus->irq = irq;
+ bus->spmic = ctrl;
+
+ ret = pmic_arb->ver_ops->init_apid(bus);
+ if (ret)
+ return ret;
+
+ dev_dbg(&pdev->dev, "adding irq domain\n");
+
+ bus->domain = irq_domain_add_tree(dev->of_node,
+ &pmic_arb_irq_domain_ops, bus);
+ if (!bus->domain) {
+ dev_err(&pdev->dev, "unable to create irq_domain\n");
+ return -ENOMEM;
+ }
+
+ irq_set_chained_handler_and_data(bus->irq,
+ pmic_arb_chained_irq, bus);
+
+ ctrl->dev.of_node = node;
+
+ ret = devm_spmi_controller_add(dev, ctrl);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int spmi_pmic_arb_probe(struct platform_device *pdev)
{
struct spmi_pmic_arb *pmic_arb;
- struct spmi_controller *ctrl;
+ struct device *dev = &pdev->dev;
struct resource *res;
void __iomem *core;
u32 channel, ee, hw_ver;
int err;
- ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
- if (IS_ERR(ctrl))
- return PTR_ERR(ctrl);
-
- pmic_arb = spmi_controller_get_drvdata(ctrl);
- pmic_arb->spmic = ctrl;
+ pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+ if (!pmic_arb)
+ return -ENOMEM;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
- core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+ core = devm_ioremap(dev, res->start, resource_size(res));
if (IS_ERR(core))
return PTR_ERR(core);
pmic_arb->core_size = resource_size(res);
+ platform_set_drvdata(pdev, pmic_arb);
+
hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
@@ -1594,30 +1726,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
else
pmic_arb->ver_ops = &pmic_arb_v7;
- dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
- pmic_arb->ver_ops->ver_str, hw_ver);
-
err = pmic_arb->ver_ops->get_core_resources(pdev, core);
if (err)
return err;
- err = pmic_arb->ver_ops->init_apid(pmic_arb);
- if (err)
- return err;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
- pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
- if (IS_ERR(pmic_arb->intr))
- return PTR_ERR(pmic_arb->intr);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
- pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
- if (IS_ERR(pmic_arb->cnfg))
- return PTR_ERR(pmic_arb->cnfg);
-
- pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
- if (pmic_arb->irq < 0)
- return pmic_arb->irq;
+ dev_info(dev, "PMIC arbiter version %s (0x%x)\n",
+ pmic_arb->ver_ops->ver_str, hw_ver);
err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
if (err) {
@@ -1646,42 +1760,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
pmic_arb->ee = ee;
- platform_set_drvdata(pdev, ctrl);
- raw_spin_lock_init(&pmic_arb->lock);
-
- ctrl->cmd = pmic_arb_cmd;
- ctrl->read_cmd = pmic_arb_read_cmd;
- ctrl->write_cmd = pmic_arb_write_cmd;
-
- dev_dbg(&pdev->dev, "adding irq domain\n");
- pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
- &pmic_arb_irq_domain_ops, pmic_arb);
- if (!pmic_arb->domain) {
- dev_err(&pdev->dev, "unable to create irq_domain\n");
- return -ENOMEM;
- }
-
- irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
- pmic_arb);
- err = spmi_controller_add(ctrl);
- if (err)
- goto err_domain_remove;
-
- return 0;
-
-err_domain_remove:
- irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
- irq_domain_remove(pmic_arb->domain);
- return err;
+ return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb);
}
static void spmi_pmic_arb_remove(struct platform_device *pdev)
{
- struct spmi_controller *ctrl = platform_get_drvdata(pdev);
- struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
- spmi_controller_remove(ctrl);
- irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
- irq_domain_remove(pmic_arb->domain);
+ struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+ struct spmi_pmic_arb_bus *bus = pmic_arb->bus;
+
+ irq_set_chained_handler_and_data(bus->irq,
+ NULL, NULL);
+ irq_domain_remove(bus->domain);
}
static const struct of_device_id spmi_pmic_arb_match_table[] = {
--
2.34.1
^ permalink raw reply related
* [PATCH v9 7/7] spmi: pmic-arb: Add multi bus support
From: Abel Vesa @ 2024-04-07 16:23 UTC (permalink / raw)
To: Stephen Boyd, Matthias Brugger, Bjorn Andersson, Konrad Dybcio,
Dmitry Baryshkov, Neil Armstrong, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, David Collins, linux-kernel,
linux-arm-kernel, linux-arm-msm, linux-mediatek, devicetree,
Abel Vesa
In-Reply-To: <20240407-spmi-multi-master-support-v9-0-fa151c1391f3@linaro.org>
Starting with HW version 7, there are actually two separate buses
(with two separate sets of wires). So add support for the second bus.
The first platform that needs this support for the second bus is the
Qualcomm X1 Elite, so add the compatible for it as well.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/spmi/spmi-pmic-arb.c | 138 +++++++++++++++++++++++++++++++++++++------
1 file changed, 120 insertions(+), 18 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 65d8f45da24b..cfa8ec21cd56 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -95,6 +96,8 @@ enum pmic_arb_channel {
PMIC_ARB_CHANNEL_OBS,
};
+#define PMIC_ARB_MAX_BUSES 2
+
/* Maximum number of support PMIC peripherals */
#define PMIC_ARB_MAX_PERIPHS 512
#define PMIC_ARB_MAX_PERIPHS_V7 1024
@@ -149,6 +152,7 @@ struct spmi_pmic_arb;
* @min_apid: minimum APID (used for bounding IRQ search)
* @max_apid: maximum APID
* @irq: PMIC ARB interrupt.
+ * @id: unique ID of the bus
*/
struct spmi_pmic_arb_bus {
struct spmi_pmic_arb *pmic_arb;
@@ -167,6 +171,7 @@ struct spmi_pmic_arb_bus {
u16 min_apid;
u16 max_apid;
int irq;
+ u8 id;
};
/**
@@ -180,7 +185,8 @@ struct spmi_pmic_arb_bus {
* @ee: the current Execution Environment
* @ver_ops: version dependent operations.
* @max_periphs: Number of elements in apid_data[]
- * @bus: per arbiter bus instance
+ * @buses: per arbiter buses instances
+ * @buses_available: number of buses registered
*/
struct spmi_pmic_arb {
void __iomem *rd_base;
@@ -191,7 +197,8 @@ struct spmi_pmic_arb {
u8 ee;
const struct pmic_arb_ver_ops *ver_ops;
int max_periphs;
- struct spmi_pmic_arb_bus *bus;
+ struct spmi_pmic_arb_bus *buses[PMIC_ARB_MAX_BUSES];
+ int buses_available;
};
/**
@@ -220,7 +227,7 @@ struct spmi_pmic_arb {
struct pmic_arb_ver_ops {
const char *ver_str;
int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
- int (*init_apid)(struct spmi_pmic_arb_bus *bus);
+ int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
@@ -309,8 +316,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
}
if (status & PMIC_ARB_STATUS_FAILURE) {
- dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
- __func__, sid, addr, status);
+ dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+ __func__, sid, addr, status, offset);
WARN_ON(1);
return -EIO;
}
@@ -326,8 +333,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
udelay(1);
}
- dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
- __func__, sid, addr, status);
+ dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+ __func__, bus->id, sid, addr, status);
return -ETIMEDOUT;
}
@@ -1003,11 +1010,17 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
return 0;
}
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
{
struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
u32 *mapping_table;
+ if (index) {
+ dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+ index);
+ return -EINVAL;
+ }
+
mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
sizeof(*mapping_table), GFP_KERNEL);
if (!mapping_table)
@@ -1250,11 +1263,17 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
return 0x1000 * pmic_arb->ee + 0x8000 * apid;
}
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
{
struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
int ret;
+ if (index) {
+ dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+ index);
+ return -EINVAL;
+ }
+
bus->base_apid = 0;
bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
PMIC_ARB_FEATURES_PERIPH_MASK;
@@ -1326,6 +1345,50 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
return pmic_arb_get_obsrvr_chnls_v2(pdev);
}
+/*
+ * Only v7 supports 2 buses. Each bus will get a different apid count, read
+ * from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
+{
+ struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+ int ret;
+
+ if (index == 0) {
+ bus->base_apid = 0;
+ bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK;
+ } else if (index == 1) {
+ bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK;
+ bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+ PMIC_ARB_FEATURES_PERIPH_MASK;
+ } else {
+ dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+ bus->id);
+ return -EINVAL;
+ }
+
+ if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+ dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+ bus->base_apid + bus->apid_count);
+ return -EINVAL;
+ }
+
+ ret = pmic_arb_init_apid_min_max(bus);
+ if (ret)
+ return ret;
+
+ ret = pmic_arb_read_apid_map_v5(bus);
+ if (ret) {
+ dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* v7 offset per ee and per apid for observer channels and per apid for
* read/write channels.
@@ -1578,7 +1641,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
.ver_str = "v7",
.get_core_resources = pmic_arb_get_core_resources_v7,
- .init_apid = pmic_arb_init_apid_v5,
+ .init_apid = pmic_arb_init_apid_v7,
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v7,
@@ -1602,6 +1665,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
struct device_node *node,
struct spmi_pmic_arb *pmic_arb)
{
+ int bus_index = pmic_arb->buses_available;
struct spmi_pmic_arb_bus *bus;
struct device *dev = &pdev->dev;
struct spmi_controller *ctrl;
@@ -1620,7 +1684,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
bus = spmi_controller_get_drvdata(ctrl);
- pmic_arb->bus = bus;
+ pmic_arb->buses[bus_index] = bus;
raw_spin_lock_init(&bus->lock);
@@ -1665,12 +1729,13 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
bus->cnfg = cnfg;
bus->irq = irq;
bus->spmic = ctrl;
+ bus->id = bus_index;
- ret = pmic_arb->ver_ops->init_apid(bus);
+ ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
if (ret)
return ret;
- dev_dbg(&pdev->dev, "adding irq domain\n");
+ dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
bus->domain = irq_domain_add_tree(dev->of_node,
&pmic_arb_irq_domain_ops, bus);
@@ -1683,14 +1748,53 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
pmic_arb_chained_irq, bus);
ctrl->dev.of_node = node;
+ dev_set_name(&ctrl->dev, "spmi-%d", bus_index);
ret = devm_spmi_controller_add(dev, ctrl);
if (ret)
return ret;
+ pmic_arb->buses_available++;
+
return 0;
}
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+ struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct device_node *child;
+ int ret;
+
+ /* legacy mode doesn't provide child node for the bus */
+ if (of_device_is_compatible(node, "qcom,spmi-pmic-arb"))
+ return spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+
+ for_each_available_child_of_node(node, child) {
+ if (of_node_name_eq(child, "spmi")) {
+ ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+ int i;
+
+ for (i = 0; i < pmic_arb->buses_available; i++) {
+ struct spmi_pmic_arb_bus *bus = pmic_arb->buses[i];
+
+ irq_set_chained_handler_and_data(bus->irq,
+ NULL, NULL);
+ irq_domain_remove(bus->domain);
+ }
+}
+
static int spmi_pmic_arb_probe(struct platform_device *pdev)
{
struct spmi_pmic_arb *pmic_arb;
@@ -1760,21 +1864,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
pmic_arb->ee = ee;
- return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb);
+ return spmi_pmic_arb_register_buses(pmic_arb, pdev);
}
static void spmi_pmic_arb_remove(struct platform_device *pdev)
{
struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
- struct spmi_pmic_arb_bus *bus = pmic_arb->bus;
- irq_set_chained_handler_and_data(bus->irq,
- NULL, NULL);
- irq_domain_remove(bus->domain);
+ spmi_pmic_arb_deregister_buses(pmic_arb);
}
static const struct of_device_id spmi_pmic_arb_match_table[] = {
{ .compatible = "qcom,spmi-pmic-arb", },
+ { .compatible = "qcom,x1e80100-spmi-pmic-arb", },
{},
};
MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);
--
2.34.1
^ permalink raw reply related
* [PATCH RESEND v8 0/6] riscv: add initial support for Canaan Kendryte K230
From: Yangyu Chen @ 2024-04-07 16:26 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen
K230 is an ideal chip for RISC-V Vector 1.0 evaluation now. Add initial
support for it to allow more people to participate in building drivers
to mainline for it.
This kernel has been tested upon factory SDK [1] with
k230_evb_only_linux_defconfig and patched mainline opensbi [2] to skip
locked pmp and successfully booted to busybox on initrd with this log [3].
Changes in resend v8:
- Add missing cc to lkml and linux-dt list and correct Krzysztof's address
- No change in content
v8: https://lore.kernel.org/linux-riscv/tencent_9F423E3DC13F6D5FC7415C89988490F04607@qq.com/
Changes since v7:
- Add missing riscv,cbop-block-size and riscv,cboz-block-size in dts
v7: https://lore.kernel.org/linux-riscv/tencent_F6392EE11AC6A485C43406F1BD09C268DB0A@qq.com/
Changes since v6:
- Split SOC_CANAAN clean up to a separate patch [4]
- Add zicbop and zicboz in dts
- Rebase to riscv-dt-for-next branch
v6: https://lore.kernel.org/linux-riscv/tencent_F76EB8D731C521C18D5D7C4F8229DAA58E08@qq.com/
Changes since v5:
- Deprecate SOC_CANAAN and use SOC_CANAAN_K210 for K210 SoCs
- Modify existing K210 drivers depends on SOC_CANAAN_K210 symbol
- Reword dts commit message
- Modify dts to use Full 512MB memory
- Rebase to linux mainline master
v5: https://lore.kernel.org/linux-riscv/tencent_FC10B3C630BE27412FED2547245CBE18D807@qq.com/
Changes since v4:
- Reword commit message on dts that the B-ext version of c908 is 1.0 rather
than 1.0-rc1
v4: https://lore.kernel.org/linux-riscv/tencent_587730262984A011834F42D0563BC6B10405@qq.com/
Changes since v3:
- Refactor Kconfig.soc which uses ARCH_CANAAN for regular Canaan SoCs and
rename SOC_CANAAN to SOC_CANAAN_K210 for K210 in patch [5/7]
- Sort dt-binding stings on Cannan SoCs in alphanumerical order
v3: https://lore.kernel.org/linux-riscv/tencent_BB2364BBF1812F4E304F7BDDD11E57356605@qq.com/
Changes since v2:
- Add MIT License to dts file
- Sort dt-binding stings in alphanumerical order
- Sort filename in dts Makefile in alphanumerical order
- Rename canmv-k230.dts to k230-canmv.dts
v2: https://lore.kernel.org/linux-riscv/tencent_64A9B4B31C2D70D5633042461AC9F80C0509@qq.com/
Changes since v1:
- Patch dt-bindings in clint and plic
- Use enum in K230 compatible dt bindings
- Fix dts to pass `make dtbs_check`
- Add more details in commit message
v1: https://lore.kernel.org/linux-riscv/tencent_E15F8FE0B6769E6338AE690C7F4844A31706@qq.com/
[1] https://github.com/kendryte/k230_sdk
[2] https://github.com/cyyself/opensbi/tree/k230
[3] https://gist.github.com/cyyself/b9445f38cc3ba1094924bd41c9086176
[4] https://lore.kernel.org/linux-riscv/tencent_2E60E33C1F88A090B6B3A332AE528C6B8806@qq.com/
Yangyu Chen (6):
dt-bindings: riscv: Add T-HEAD C908 compatible
dt-bindings: add Canaan K230 boards compatible strings
dt-bindings: timer: Add Canaan K230 CLINT
dt-bindings: interrupt-controller: Add Canaan K230 PLIC
riscv: dts: add initial canmv-k230 and k230-evb dts
riscv: config: enable ARCH_CANAAN in defconfig
.../sifive,plic-1.0.0.yaml | 1 +
.../devicetree/bindings/riscv/canaan.yaml | 8 +-
.../devicetree/bindings/riscv/cpus.yaml | 1 +
.../bindings/timer/sifive,clint.yaml | 1 +
arch/riscv/boot/dts/canaan/Makefile | 2 +
arch/riscv/boot/dts/canaan/k230-canmv.dts | 24 +++
arch/riscv/boot/dts/canaan/k230-evb.dts | 24 +++
arch/riscv/boot/dts/canaan/k230.dtsi | 142 ++++++++++++++++++
arch/riscv/configs/defconfig | 1 +
9 files changed, 203 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/boot/dts/canaan/k230-canmv.dts
create mode 100644 arch/riscv/boot/dts/canaan/k230-evb.dts
create mode 100644 arch/riscv/boot/dts/canaan/k230.dtsi
base-commit: 0eea987088a22d73d81e968de7347cdc7e594f72
--
2.43.0
^ permalink raw reply
* [PATCH RESEND v8 1/6] dt-bindings: riscv: Add T-HEAD C908 compatible
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen, Conor Dooley
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
The thead,c908 is a RISC-V CPU core from T-HEAD Semiconductor which used
in Canaan Kendryte K230 SoC.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
---
Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index d87dd50f1a4b..d067f2a468ee 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -47,6 +47,7 @@ properties:
- sifive,u74
- sifive,u74-mc
- thead,c906
+ - thead,c908
- thead,c910
- thead,c920
- const: riscv
--
2.43.0
^ permalink raw reply related
* [PATCH RESEND v8 3/6] dt-bindings: timer: Add Canaan K230 CLINT
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen, Rob Herring
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
Add compatible string for Canaan K230 CLINT.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Guo Ren <guoren@kernel.org>
---
Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
index fced6f2d8ecb..06c67f20ad3c 100644
--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
@@ -38,6 +38,7 @@ properties:
- items:
- enum:
- allwinner,sun20i-d1-clint
+ - canaan,k230-clint
- sophgo,cv1800b-clint
- sophgo,cv1812h-clint
- thead,th1520-clint
--
2.43.0
^ permalink raw reply related
* [PATCH RESEND v8 5/6] riscv: dts: add initial canmv-k230 and k230-evb dts
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
Add initial dts for CanMV-K230 and K230-EVB powered by Canaan Kendryte
K230 SoC [1].
Some key consideration:
- Only place BigCore which is 1.6GHz RV64GCBV
The existence of cache coherence between the two cores remains unknown
since they have dedicated L2 caches. And the factory SDK uses it for
other OS by default. I don't know whether the two CPUs on K230 SoC
can be used in one system. So only place BigCore here.
Meanwhile, although docs from Canaan said 1.6GHz Core with Vector is
CPU1, the CSR.MHARTID of this core is 0.
- Support for "zba" "zbb" "zbc" "zbs" are tested by hand
The user manual of C908 from T-Head does not document it specifically.
It just said it supports B extension V1.0. [2]
I have tested it by using this [3] which attempts to execute "add.uw",
"andn", "clmulr", "bclr" and they doesn't traps on K230. But on JH7110,
"clmulr" and "bclr" will trap.
- Support for "zicbom" is tested by hand
Have tested with some out-of-tree drivers from [4] that need DMA and they
do not come to the dts currently.
- Support for "zicboz" is tested by hand
Have tested with my own bare mental M-Mode program [5] which tries to use
zicboz to clear a 64B aligned block and got output[6] shows it supports
zicboz.
- Cache parameters are inferred from T-Head docs [2] and Canaan docs [1]
L1i: 32KB, VIPT 4-Way set-associative, 64B Cacheline
L1d: 32KB, VIPT 4-Way set-associative, 64B Cacheline
L2: 256KB, PIPT 16-way set-associative, 64B Cacheline
The numbers of cache sets are calculated from these parameters.
- MMU only supports Sv39
The T-Head docs [2] say the C908 core can be configured to support Sv48 and
Sv39 or only Sv39. On K230, I tried to write "riscv,sv48" on mmu-type in
dts and boot the mainline kernel. However, it failed during the kernel
probe and fell back to Sv39. I also tested it on M-Mode software, writing
Sv48 to satp.mode will not trap but will leave the CSR unchanged. While
writing Sv39, it will take effect. It shows that this CPU does not support
Sv48.
- Svpbmt and T-Head MAEE both supported
T-Head C908 does support both Svpbmt and T-Head MAEE for page-based memory
attributes and is controlled by BIT(21) on CSR.MXSTATUS. The Svpbmt is used
here for mainline kernel support for K230. If the kernel wants to use
Svpbmt, the M-Mode software should unset BIT(21) of CSR.MXSTATUS before
entering the S-Mode kernel. Otherwise, the kernel will not boot, as 0 on
T-Head MAEE is NonCachable Memory. Once the kernel switches from bare metal
to Sv39, It will lose dirty cache line modifications that haven't been
written back to the memory.
[1] https://developer.canaan-creative.com/k230/dev/zh/00_hardware/K230_datasheet.html#chapter-1-introduction
[2] https://occ-intl-prod.oss-ap-southeast-1.aliyuncs.com/resource//1699268369347/XuanTie-C908-UserManual.pdf
[3] https://github.com/cyyself/rvb_test
[4] https://github.com/cyyself/linux/tree/k230-mainline
[5] https://github.com/cyyself/simple-sw-workbench/commit/32657d807d64217323a80cb04ce114671e51ed60
[6] https://gist.github.com/cyyself/aa98b07b8c77bb1d53b5a4c5e67a37cf
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
---
arch/riscv/boot/dts/canaan/Makefile | 2 +
arch/riscv/boot/dts/canaan/k230-canmv.dts | 24 ++++
arch/riscv/boot/dts/canaan/k230-evb.dts | 24 ++++
arch/riscv/boot/dts/canaan/k230.dtsi | 142 ++++++++++++++++++++++
4 files changed, 192 insertions(+)
create mode 100644 arch/riscv/boot/dts/canaan/k230-canmv.dts
create mode 100644 arch/riscv/boot/dts/canaan/k230-evb.dts
create mode 100644 arch/riscv/boot/dts/canaan/k230.dtsi
diff --git a/arch/riscv/boot/dts/canaan/Makefile b/arch/riscv/boot/dts/canaan/Makefile
index 987d1f0c41f0..7d54ea5c6f3d 100644
--- a/arch/riscv/boot/dts/canaan/Makefile
+++ b/arch/riscv/boot/dts/canaan/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_CANAAN) += canaan_kd233.dtb
dtb-$(CONFIG_ARCH_CANAAN) += k210_generic.dtb
+dtb-$(CONFIG_ARCH_CANAAN) += k230-canmv.dtb
+dtb-$(CONFIG_ARCH_CANAAN) += k230-evb.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_bit.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_dock.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_go.dtb
diff --git a/arch/riscv/boot/dts/canaan/k230-canmv.dts b/arch/riscv/boot/dts/canaan/k230-canmv.dts
new file mode 100644
index 000000000000..9565915cead6
--- /dev/null
+++ b/arch/riscv/boot/dts/canaan/k230-canmv.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
+ */
+
+#include "k230.dtsi"
+
+/ {
+ model = "Canaan CanMV-K230";
+ compatible = "canaan,canmv-k230", "canaan,kendryte-k230";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ ddr: memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x20000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/canaan/k230-evb.dts b/arch/riscv/boot/dts/canaan/k230-evb.dts
new file mode 100644
index 000000000000..f898b8e62368
--- /dev/null
+++ b/arch/riscv/boot/dts/canaan/k230-evb.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
+ */
+
+#include "k230.dtsi"
+
+/ {
+ model = "Kendryte K230 EVB";
+ compatible = "canaan,k230-usip-lp3-evb", "canaan,kendryte-k230";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ ddr: memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x20000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/canaan/k230.dtsi b/arch/riscv/boot/dts/canaan/k230.dtsi
new file mode 100644
index 000000000000..95c1a3d8fb11
--- /dev/null
+++ b/arch/riscv/boot/dts/canaan/k230.dtsi
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/dts-v1/;
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "canaan,kendryte-k230";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <27000000>;
+
+ cpu@0 {
+ compatible = "thead,c908", "riscv";
+ device_type = "cpu";
+ reg = <0>;
+ riscv,isa = "rv64imafdcv_zba_zbb_zbc_zbs_zicbom_zicbop_zicboz_svpbmt";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zba", "zbb",
+ "zbc", "zbs", "zicbom", "zicbop", "zicboz",
+ "zicntr", "zicsr", "zifencei", "zihpm", "svpbmt";
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <128>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <128>;
+ i-cache-size = <32768>;
+ next-level-cache = <&l2_cache>;
+ mmu-type = "riscv,sv39";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ l2_cache: l2-cache {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <262144>;
+ cache-sets = <256>;
+ cache-unified;
+ };
+ };
+
+ apb_clk: apb-clk-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ clock-output-names = "apb_clk";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-noncoherent;
+ ranges;
+
+ plic: interrupt-controller@f00000000 {
+ compatible = "canaan,k230-plic" ,"thead,c900-plic";
+ reg = <0xf 0x00000000 0x0 0x04000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <208>;
+ };
+
+ clint: timer@f04000000 {
+ compatible = "canaan,k230-clint", "thead,c900-clint";
+ reg = <0xf 0x04000000 0x0 0x00010000>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
+ };
+
+ uart0: serial@91400000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x91400000 0x0 0x1000>;
+ clocks = <&apb_clk>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart1: serial@91401000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x91401000 0x0 0x1000>;
+ clocks = <&apb_clk>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart2: serial@91402000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x91402000 0x0 0x1000>;
+ clocks = <&apb_clk>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart3: serial@91403000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x91403000 0x0 0x1000>;
+ clocks = <&apb_clk>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart4: serial@91404000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x91404000 0x0 0x1000>;
+ clocks = <&apb_clk>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related
* [PATCH RESEND v8 6/6] riscv: config: enable ARCH_CANAAN in defconfig
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen, Conor Dooley
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
Since K230 has been supported, allow ARCH_CANAAN to be selected to build dt
and drivers for it in defconfig.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index fc0ec2ee13bc..27bea8296b9d 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -33,6 +33,7 @@ CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_THEAD=y
CONFIG_SOC_VIRT=y
+CONFIG_ARCH_CANAAN=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
CONFIG_PM=y
--
2.43.0
^ permalink raw reply related
* [PATCH RESEND v8 2/6] dt-bindings: add Canaan K230 boards compatible strings
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen, Krzysztof Kozlowski
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
Since K230 was released, K210 is no longer the only SoC in the Kendryte
series, so remove the K210 string from the description. Also, add two
boards based on k230 to compatible strings to allow them to be used in the
dt.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
---
Documentation/devicetree/bindings/riscv/canaan.yaml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/riscv/canaan.yaml b/Documentation/devicetree/bindings/riscv/canaan.yaml
index 41fd11f70a49..f9854ff43ac6 100644
--- a/Documentation/devicetree/bindings/riscv/canaan.yaml
+++ b/Documentation/devicetree/bindings/riscv/canaan.yaml
@@ -10,7 +10,7 @@ maintainers:
- Damien Le Moal <dlemoal@kernel.org>
description:
- Canaan Kendryte K210 SoC-based boards
+ Canaan Kendryte SoC-based boards
properties:
$nodename:
@@ -42,6 +42,12 @@ properties:
- items:
- const: canaan,kendryte-k210
+ - items:
+ - enum:
+ - canaan,canmv-k230
+ - canaan,k230-usip-lp3-evb
+ - const: canaan,kendryte-k230
+
additionalProperties: true
...
--
2.43.0
^ permalink raw reply related
* [PATCH RESEND v8 4/6] dt-bindings: interrupt-controller: Add Canaan K230 PLIC
From: Yangyu Chen @ 2024-04-07 16:28 UTC (permalink / raw)
To: linux-riscv
Cc: Conor Dooley, Damien Le Moal, Rob Herring, Krzysztof Kozlowski,
Dan Carpenter, Paul Walmsley, Palmer Dabbelt, Albert Ou, Guo Ren,
devicetree, linux-kernel, Yangyu Chen, Rob Herring
In-Reply-To: <tencent_22BA0425B4DF1CA1713B62E4423C1BFBF809@qq.com>
Add compatible string for Canaan K230 PLIC.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Guo Ren <guoren@kernel.org>
---
.../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
index 709b2211276b..122f9b7b3f52 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
@@ -65,6 +65,7 @@ properties:
- items:
- enum:
- allwinner,sun20i-d1-plic
+ - canaan,k230-plic
- sophgo,cv1800b-plic
- sophgo,cv1812h-plic
- sophgo,sg2042-plic
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2] dt-bindings: dma: snps,dma-spear1340: Fix data{-,_}width schema
From: Vinod Koul @ 2024-04-07 16:38 UTC (permalink / raw)
To: Viresh Kumar, Andy Shevchenko, Krzysztof Kozlowski, Conor Dooley,
Rob Herring
Cc: Viresh Kumar, Serge Semin, dmaengine, devicetree, linux-kernel
In-Reply-To: <20240401204354.1691845-1-robh@kernel.org>
On Mon, 01 Apr 2024 15:43:53 -0500, Rob Herring wrote:
> 'data-width' and 'data_width' properties are defined as arrays, but the
> schema is defined as a matrix. That works currently since everything gets
> decoded in to matrices, but that is internal to dtschema and could change.
>
>
Applied, thanks!
[1/1] dt-bindings: dma: snps,dma-spear1340: Fix data{-,_}width schema
commit: 7eccb5a5b224be42431c8087c9c9e016636ff3b5
Best regards,
--
~Vinod
^ permalink raw reply
* Re: [PATCH v4 0/5] dmaengine: fsl-sdma: Some improvement for fsl-sdma
From: Vinod Koul @ 2024-04-07 16:39 UTC (permalink / raw)
To: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joy Zou, Frank Li
Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
Nicolin Chen, Shengjiu Wang, Daniel Baluta, Vipul Kumar,
Srikanth Krishnakar, Robin Gong, Iuliana Prodan, Clark Wang
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>
On Fri, 29 Mar 2024 10:34:40 -0400, Frank Li wrote:
> To: Vinod Koul <vkoul@kernel.org>
> To: Shawn Guo <shawnguo@kernel.org>
> To: Sascha Hauer <s.hauer@pengutronix.de>
> To: Pengutronix Kernel Team <kernel@pengutronix.de>
> To: Fabio Estevam <festevam@gmail.com>
> To: NXP Linux Team <linux-imx@nxp.com>
> To: Rob Herring <robh@kernel.org>
> To: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> To: Conor Dooley <conor+dt@kernel.org>
> To: Joy Zou <joy.zou@nxp.com>
> Cc: dmaengine@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Cc: imx@lists.linux.dev
>
> [...]
Applied, thanks!
[1/5] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)
commit: 802ef223101fec83d92e045f89000b228904a580
[2/5] dmaengine: imx-sdma: Support 24bit/3bytes for sg mode
commit: 288109387becd8abadca5c063c70a07ae0dd7716
[3/5] dmaengine: imx-sdma: support dual fifo for DEV_TO_DEV
commit: a20f10d6accb9f5096fa7a7296e5ae34f4562440
[4/5] dt-bindings: fsl-imx-sdma: Add I2C peripheral types ID
(no commit info)
[5/5] dmaengine: imx-sdma: Add i2c dma support
(no commit info)
Best regards,
--
~Vinod
^ permalink raw reply
* Re: [PATCH v2 0/2] Add JH8100 support for snps,dw-axi-dmac
From: Vinod Koul @ 2024-04-07 16:39 UTC (permalink / raw)
To: Eugeniy Paltsev, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Tan Chun Hau
Cc: Ley Foon Tan, Jee Heng Sia, dmaengine, devicetree, linux-kernel
In-Reply-To: <20240327025126.229475-1-chunhau.tan@starfivetech.com>
On Tue, 26 Mar 2024 19:51:24 -0700, Tan Chun Hau wrote:
> Add StarFive JH8100 DMA support.
>
> Changes in v2:
> - Amended commit message according to feedback.
>
> Tan Chun Hau (2):
> dt-bindings: dma: snps,dw-axi-dmac: Add JH8100 support
> dmaengine: dw-axi-dmac: Add support for StarFive JH8100 DMA
>
> [...]
Applied, thanks!
[1/2] dt-bindings: dma: snps,dw-axi-dmac: Add JH8100 support
commit: 9bcf929ba1879887e0464d06cbf9b33839572af7
[2/2] dmaengine: dw-axi-dmac: Add support for StarFive JH8100 DMA
commit: 559a6690187ee0ab7875f7c560d3d19e35423fb3
Best regards,
--
~Vinod
^ permalink raw reply
* Re: [PATCH v3 0/5] dmaengine: fsl-edma: add 8ulp support
From: Vinod Koul @ 2024-04-07 16:39 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peng Fan,
Frank Li
Cc: imx, dmaengine, linux-kernel, devicetree, Joy Zou
In-Reply-To: <20240323-8ulp_edma-v3-0-c0e981027c05@nxp.com>
On Sat, 23 Mar 2024 11:34:49 -0400, Frank Li wrote:
> Do some small clean up.
>
> 0c562876972ee dmaengine: fsl-edma: remove 'slave_id' from fsl_edma_chan
> d9b66cb5fdf62 dmaengine: fsl-edma: add safety check for 'srcid'
> aae21b7528311 dmaengine: fsl-edma: clean up chclk and FSL_EDMA_DRV_HAS_CHCLK
>
> Update binding doc.
> 23a1d1a6609fa dt-bindings: fsl-dma: fsl-edma: add fsl,imx8ulp-edma compatible string
>
> [...]
Applied, thanks!
[1/5] dmaengine: fsl-edma: remove 'slave_id' from fsl_edma_chan
commit: cee8cbfc7be8ff9f3ccf258134f9ab2c273abb75
[2/5] dmaengine: fsl-edma: add safety check for 'srcid'
commit: 6aa60f79e6794bbbc571ea4e0501b9fcc26026e2
[3/5] dmaengine: fsl-edma: clean up chclk and FSL_EDMA_DRV_HAS_CHCLK
commit: 9a5000cf70bcfcb5dd4e5b4bae0a01fb9bdf9fa1
[4/5] dt-bindings: dma: fsl-edma: add fsl,imx8ulp-edma compatible string
commit: b14f56beb289ff67fe484d720bf09092163f90c8
[5/5] dmaengine: fsl-edma: add i.MX8ULP edma support
commit: d8d4355861d874cbd1395ec0edcbe4e0f6940738
Best regards,
--
~Vinod
^ permalink raw reply
* Re: [PATCH] dt-bindings: dma: snps,dma-spear1340: Fix data{-,_}width schema
From: Vinod Koul @ 2024-04-07 16:39 UTC (permalink / raw)
To: Viresh Kumar, Andy Shevchenko, Krzysztof Kozlowski, Conor Dooley,
Rob Herring
Cc: dmaengine, devicetree, linux-kernel
In-Reply-To: <20240311222522.1939951-1-robh@kernel.org>
On Mon, 11 Mar 2024 16:25:22 -0600, Rob Herring wrote:
> 'data-width' and 'data_width' properties are defined as arrays, but the
> schema is defined as a matrix. That works currently since everything gets
> decoded in to matrices, but that is internal to dtschema and could change.
>
>
Applied, thanks!
[1/1] dt-bindings: dma: snps,dma-spear1340: Fix data{-,_}width schema
commit: 7eccb5a5b224be42431c8087c9c9e016636ff3b5
Best regards,
--
~Vinod
^ permalink raw reply
* [PATCH] arm64: dts: rockchip: mark system power controller and fix typo on orangepi-5-plus
From: efectn @ 2024-04-07 17:32 UTC (permalink / raw)
To: heiko, linux-rockchip
Cc: devicetree, linux-arm-kernel, linux-kernel, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sebastian.reichel,
Muhammed Efe Cetin
From: Muhammed Efe Cetin <efectn@protonmail.com>
Mark the PMIC as system power controller, so the board will shut-down
properly and fix the typo on rk806_dvs1_null pins property.
Fixes: 236d225e1ee7 ("arm64: dts: rockchip: Add board device tree for rk3588-orangepi-5-plus")
Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
---
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
index 1b606ea5b6cf..1a604429fb26 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -485,6 +485,7 @@ pmic@0 {
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
<&rk806_dvs2_null>, <&rk806_dvs3_null>;
spi-max-frequency = <1000000>;
+ system-power-controller;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
@@ -506,7 +507,7 @@ pmic@0 {
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
- pins = "gpio_pwrctrl2";
+ pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
--
2.44.0
^ permalink raw reply related
* Re: [PATCH] arm64: dts: rockchip: mark system power controller and fix typo on orangepi-5-plus
From: Dragan Simic @ 2024-04-07 17:46 UTC (permalink / raw)
To: efectn
Cc: heiko, linux-rockchip, devicetree, linux-arm-kernel, linux-kernel,
robh+dt, krzysztof.kozlowski+dt, conor+dt, sebastian.reichel,
Muhammed Efe Cetin
In-Reply-To: <20240407173210.372585-1-efectn@6tel.net>
On 2024-04-07 19:32, efectn@6tel.net wrote:
> From: Muhammed Efe Cetin <efectn@protonmail.com>
>
> Mark the PMIC as system power controller, so the board will shut-down
> properly and fix the typo on rk806_dvs1_null pins property.
>
> Fixes: 236d225e1ee7 ("arm64: dts: rockchip: Add board device tree for
> rk3588-orangepi-5-plus")
> Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
Looking good to me.
Reviewed-by: Dragan Simic <dsimic@manjaro.org>
> ---
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> index 1b606ea5b6cf..1a604429fb26 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> @@ -485,6 +485,7 @@ pmic@0 {
> pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
> <&rk806_dvs2_null>, <&rk806_dvs3_null>;
> spi-max-frequency = <1000000>;
> + system-power-controller;
>
> vcc1-supply = <&vcc5v0_sys>;
> vcc2-supply = <&vcc5v0_sys>;
> @@ -506,7 +507,7 @@ pmic@0 {
> #gpio-cells = <2>;
>
> rk806_dvs1_null: dvs1-null-pins {
> - pins = "gpio_pwrctrl2";
> + pins = "gpio_pwrctrl1";
> function = "pin_fun0";
> };
^ permalink raw reply
* Re: [PATCH v4 3/5] spi: spi-qpic: Add qpic spi nand driver support
From: Alex G. @ 2024-04-07 17:48 UTC (permalink / raw)
To: Md Sadre Alam, andersson, konrad.dybcio, broonie, robh,
krzysztof.kozlowski+dt, conor+dt, miquel.raynal, richard,
vigneshr, manivannan.sadhasivam, neil.armstrong, daniel, arnd,
chris.packham, christophe.kerello, linux-arm-msm, linux-spi,
devicetree, linux-kernel, linux-mtd
Cc: quic_srichara, quic_varada
In-Reply-To: <20240308091752.16136-4-quic_mdalam@quicinc.com>
On 3/8/24 03:17, Md Sadre Alam wrote:
> Add qpic spi nand driver support. The spi nand
> driver currently supported the below commands.
>
> -- RESET
> -- READ ID
> -- SET FEATURE
> -- GET FEATURE
> -- READ PAGE
> -- WRITE PAGE
> -- ERASE PAGE
>
> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> Co-developed-by: Varadarajan Narayanan <quic_varada@quicinc.com>
> Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> ---
For the entire series:
Tested-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index bc7021da2fe9..63764e943d82 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -882,6 +882,14 @@ config SPI_QCOM_QSPI
> help
> QSPI(Quad SPI) driver for Qualcomm QSPI controller.
>
> +config SPI_QPIC_SNAND
> + tristate "QPIC SNAND controller"
> + depends on ARCH_QCOM || COMPILE_TEST
Here, it needs to 'select QPIC_COMMON`. Otherwise it can run into
unresolved symbols:
: drivers/spi/spi-qpic-snand.o: in function `snandc_set_reg':
drivers/spi/spi-qpic-snand.c:56:(.text+0x484): undefined reference to
`qcom_offset_to_nandc_reg'
...
> + help
> + QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
> + QPIC controller supports both parallel nand and serial nand.
> + This config will enable serial nand driver for QPIC controller.
> +
> config SPI_QUP
> tristate "Qualcomm SPI controller with QUP interface"
> depends on ARCH_QCOM || COMPILE_TEST
Alex
^ permalink raw reply
* [PATCH] arm64: dts: rockchip: Designate the system power controller on QuartzPro64
From: Dragan Simic @ 2024-04-07 17:56 UTC (permalink / raw)
To: linux-rockchip
Cc: heiko, linux-arm-kernel, devicetree, robh+dt,
krzysztof.kozlowski+dt, conor+dt
Designate the primary RK806 PMIC on the Pine64 QuartzPro64 as the system
power controller, so the board shuts down properly on poweroff(8).
Signed-off-by: Dragan Simic <dsimic@manjaro.org>
---
arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
index 67414d72e2b6..22bbfbe729c1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
@@ -456,6 +456,7 @@ pmic@0 {
<&rk806_dvs2_null>, <&rk806_dvs3_null>;
pinctrl-names = "default";
spi-max-frequency = <1000000>;
+ system-power-controller;
vcc1-supply = <&vcc4v0_sys>;
vcc2-supply = <&vcc4v0_sys>;
^ permalink raw reply related
* Re: [PATCH v4 3/5] spi: spi-qpic: Add qpic spi nand driver support
From: Alex G. @ 2024-04-07 18:40 UTC (permalink / raw)
To: Md Sadre Alam, andersson, konrad.dybcio, broonie, robh,
krzysztof.kozlowski+dt, conor+dt, miquel.raynal, richard,
vigneshr, manivannan.sadhasivam, neil.armstrong, daniel, arnd,
chris.packham, christophe.kerello, linux-arm-msm, linux-spi,
devicetree, linux-kernel, linux-mtd
Cc: quic_srichara, quic_varada
In-Reply-To: <1c803d8c-80b2-47a9-bc8c-8b13cbfc6841@gmail.com>
On 4/7/24 12:48, Alex G. wrote:
> On 3/8/24 03:17, Md Sadre Alam wrote:
>> Add qpic spi nand driver support. The spi nand
>> driver currently supported the below commands.
>>
>> -- RESET
>> -- READ ID
>> -- SET FEATURE
>> -- GET FEATURE
>> -- READ PAGE
>> -- WRITE PAGE
>> -- ERASE PAGE
>>
>> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Co-developed-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>> Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
>> ---
>
> For the entire series:
>
> Tested-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index bc7021da2fe9..63764e943d82 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -882,6 +882,14 @@ config SPI_QCOM_QSPI
>> help
>> QSPI(Quad SPI) driver for Qualcomm QSPI controller.
>> +config SPI_QPIC_SNAND
>> + tristate "QPIC SNAND controller"
Also, don't tristate this. It can be set as CONFIG_QPIC_COMMON=m, which
will cause the build to fail because you don't have a MODULE_LICENSE().
>> + depends on ARCH_QCOM || COMPILE_TEST
>
> Here, it needs to 'select QPIC_COMMON`. Otherwise it can run into
> unresolved symbols:
>
> : drivers/spi/spi-qpic-snand.o: in function `snandc_set_reg':
> drivers/spi/spi-qpic-snand.c:56:(.text+0x484): undefined reference to
> `qcom_offset_to_nandc_reg'
> ...
>
>> + help
>> + QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
>> + QPIC controller supports both parallel nand and serial nand.
>> + This config will enable serial nand driver for QPIC controller.
>> +
>> config SPI_QUP
>> tristate "Qualcomm SPI controller with QUP interface"
>> depends on ARCH_QCOM || COMPILE_TEST
>
> Alex
Alex
^ permalink raw reply
* Re: [PATCH v4 3/5] spi: spi-qpic: Add qpic spi nand driver support
From: Alex G. @ 2024-04-07 18:45 UTC (permalink / raw)
To: Md Sadre Alam, andersson, konrad.dybcio, broonie, robh,
krzysztof.kozlowski+dt, conor+dt, miquel.raynal, richard,
vigneshr, manivannan.sadhasivam, neil.armstrong, daniel, arnd,
chris.packham, christophe.kerello, linux-arm-msm, linux-spi,
devicetree, linux-kernel, linux-mtd
Cc: quic_srichara, quic_varada
In-Reply-To: <4f72048a-a764-43de-846c-3b4edc1232e3@gmail.com>
On 4/7/24 13:40, Alex G. wrote:
>
>
> On 4/7/24 12:48, Alex G. wrote:
>> On 3/8/24 03:17, Md Sadre Alam wrote:
>>> Add qpic spi nand driver support. The spi nand
>>> driver currently supported the below commands.
>>>
>>> -- RESET
>>> -- READ ID
>>> -- SET FEATURE
>>> -- GET FEATURE
>>> -- READ PAGE
>>> -- WRITE PAGE
>>> -- ERASE PAGE
>>>
>>> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>>> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>>> Co-developed-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>>> Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
>>> ---
>>
>> For the entire series:
>>
>> Tested-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>>
>>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>>> index bc7021da2fe9..63764e943d82 100644
>>> --- a/drivers/spi/Kconfig
>>> +++ b/drivers/spi/Kconfig
>>> @@ -882,6 +882,14 @@ config SPI_QCOM_QSPI
>>> help
>>> QSPI(Quad SPI) driver for Qualcomm QSPI controller.
>>> +config SPI_QPIC_SNAND
>>> + tristate "QPIC SNAND controller"
>
> Also, don't tristate this. It can be set as CONFIG_QPIC_COMMON=m, which
> will cause the build to fail because you don't have a MODULE_LICENSE().
Please disregard my idiotic suggestion here. I meant to make this
comment on the previous patch.
>>> + depends on ARCH_QCOM || COMPILE_TEST
>>
>> Here, it needs to 'select QPIC_COMMON`. Otherwise it can run into
>> unresolved symbols:
>>
>> : drivers/spi/spi-qpic-snand.o: in function `snandc_set_reg':
>> drivers/spi/spi-qpic-snand.c:56:(.text+0x484): undefined reference
>> to `qcom_offset_to_nandc_reg'
>> ...
>>
>>> + help
>>> + QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
>>> + QPIC controller supports both parallel nand and serial nand.
>>> + This config will enable serial nand driver for QPIC controller.
>>> +
>>> config SPI_QUP
>>> tristate "Qualcomm SPI controller with QUP interface"
>>> depends on ARCH_QCOM || COMPILE_TEST
>>
>> Alex
> Alex
^ permalink raw reply
* Re: [PATCH v4 3/5] spi: spi-qpic: Add qpic spi nand driver support
From: Krzysztof Kozlowski @ 2024-04-07 18:54 UTC (permalink / raw)
To: Alex G., Md Sadre Alam, andersson, konrad.dybcio, broonie, robh,
krzysztof.kozlowski+dt, conor+dt, miquel.raynal, richard,
vigneshr, manivannan.sadhasivam, neil.armstrong, daniel, arnd,
chris.packham, christophe.kerello, linux-arm-msm, linux-spi,
devicetree, linux-kernel, linux-mtd
Cc: quic_srichara, quic_varada
In-Reply-To: <1c803d8c-80b2-47a9-bc8c-8b13cbfc6841@gmail.com>
On 07/04/2024 19:48, Alex G. wrote:
> On 3/8/24 03:17, Md Sadre Alam wrote:
>> Add qpic spi nand driver support. The spi nand
>> driver currently supported the below commands.
>>
>> -- RESET
>> -- READ ID
>> -- SET FEATURE
>> -- GET FEATURE
>> -- READ PAGE
>> -- WRITE PAGE
>> -- ERASE PAGE
>>
>> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Co-developed-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>> Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
>> ---
>
> For the entire series:
>
> Tested-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index bc7021da2fe9..63764e943d82 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -882,6 +882,14 @@ config SPI_QCOM_QSPI
>> help
>> QSPI(Quad SPI) driver for Qualcomm QSPI controller.
>>
>> +config SPI_QPIC_SNAND
>> + tristate "QPIC SNAND controller"
>> + depends on ARCH_QCOM || COMPILE_TEST
>
> Here, it needs to 'select QPIC_COMMON`. Otherwise it can run into
> unresolved symbols:
>
> : drivers/spi/spi-qpic-snand.o: in function `snandc_set_reg':
> drivers/spi/spi-qpic-snand.c:56:(.text+0x484): undefined reference to
> `qcom_offset_to_nandc_reg'
No, do not select user-visible symbols. If you observe such issues then
either stubs are missing or depends on.
Best regards,
Krzysztof
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox