* Re: [PATCH v7 6/6] spmi: pmic-arb: Add multi bus support
From: Neil Armstrong @ 2024-04-02 8:25 UTC (permalink / raw)
To: Abel Vesa, Stephen Boyd, Matthias Brugger, Bjorn Andersson,
Konrad Dybcio, Dmitry Baryshkov, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, linux-kernel, linux-arm-kernel,
linux-arm-msm, linux-mediatek, devicetree
In-Reply-To: <20240329-spmi-multi-master-support-v7-6-7b902824246c@linaro.org>
Hi Abel,
On 29/03/2024 19:54, Abel Vesa wrote:
> 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.
>
> 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 19ff8665f3d9..56f2b3190d82 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
> @@ -148,6 +151,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;
> @@ -165,6 +169,7 @@ struct spmi_pmic_arb_bus {
> u16 min_apid;
> u16 max_apid;
> int irq;
> + u8 id;
> };
>
> /**
> @@ -179,7 +184,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;
> };
>
> /**
> @@ -219,7 +226,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,
> @@ -308,8 +315,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;
> }
> @@ -325,8 +332,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;
> }
>
> @@ -1005,11 +1012,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;
> + }
Shouldn't be here
> +
> mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
> sizeof(*mapping_table), GFP_KERNEL);
> if (!mapping_table)
> @@ -1252,11 +1265,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;
> + }
Shouldn't be here
> +
> bus->base_apid = 0;
> bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> PMIC_ARB_FEATURES_PERIPH_MASK;
> @@ -1328,6 +1347,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;
> +}
Shouldn't be here
> +
> /*
> * v7 offset per ee and per apid for observer channels and per apid for
> * read/write channels.
> @@ -1580,7 +1643,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,
Shouldn't be here
> .ppid_to_apid = pmic_arb_ppid_to_apid_v5,
> .non_data_cmd = pmic_arb_non_data_cmd_v2,
> .offset = pmic_arb_offset_v7,
> @@ -1604,6 +1667,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;
> @@ -1622,7 +1686,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;
>
> bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
> sizeof(*bus->ppid_to_apid),
> @@ -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_MAX_BUSES; 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;
> @@ -1761,21 +1865,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);
>
With issues fixed, it looks fine.
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v7 5/6] spmi: pmic-arb: Register controller for bus instead of arbiter
From: Neil Armstrong @ 2024-04-02 8:23 UTC (permalink / raw)
To: Abel Vesa, Stephen Boyd, Matthias Brugger, Bjorn Andersson,
Konrad Dybcio, Dmitry Baryshkov, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, linux-kernel, linux-arm-kernel,
linux-arm-msm, linux-mediatek, devicetree
In-Reply-To: <20240329-spmi-multi-master-support-v7-5-7b902824246c@linaro.org>
Hi Abel,
On 29/03/2024 19:54, Abel Vesa wrote:
> 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.
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
> ---
> drivers/spmi/spmi-pmic-arb.c | 703 +++++++++++++++++++++++--------------------
> 1 file changed, 372 insertions(+), 331 deletions(-)
>
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 188252bfb95f..19ff8665f3d9 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,58 +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.
> - * @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
> + * @spmic: spmi controller registered for this bus
> * @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.
> - * @domain: irq domain object for PMIC IRQ domain
> - * @spmic: SPMI controller object
> - * @ver_ops: version dependent operations.
> + * @mapping_table_valid:bitmap containing valid-only periphs.
> * @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
> + * @min_apid: minimum APID (used for bounding IRQ search)
> + * @max_apid: maximum APID
> + * @irq: PMIC ARB interrupt.
> + */
> +struct spmi_pmic_arb_bus {
> + struct spmi_pmic_arb *pmic_arb;
> + struct irq_domain *domain;
> + void __iomem *intr;
> + void __iomem *cnfg;
> + struct spmi_controller *spmic;
> + u16 base_apid;
> + int apid_count;
> + u32 *mapping_table;
> + DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
> + 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
> + * @lock: lock to synchronize accesses.
> + * @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 *intr;
> - void __iomem *cnfg;
> void __iomem *core;
> resource_size_t core_size;
> 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;
> int max_periphs;
> + struct spmi_pmic_arb_bus *bus;
> };
>
> /**
> @@ -204,21 +219,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);
I still get:
drivers/spmi/spmi-pmic-arb.c:237: warning: Function parameter or struct member 'get_core_resources' not described in 'pmic_arb_ver_ops
> - int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> - 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,
> @@ -235,6 +250,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
> @@ -249,6 +265,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.
> @@ -266,13 +283,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;
>
> @@ -315,13 +333,14 @@ 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;
>
> @@ -357,20 +376,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;
> }
> @@ -394,7 +414,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;
>
> @@ -416,12 +437,13 @@ 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);
> + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
> 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;
> @@ -433,21 +455,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
> 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;
> }
> @@ -473,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 */
> @@ -492,12 +516,13 @@ 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);
> + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
> 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;
> @@ -513,18 +538,19 @@ 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);
> + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
> 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;
> @@ -567,25 +593,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);
> }
>
> @@ -593,47 +619,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);
> @@ -645,16 +673,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;
> @@ -665,7 +694,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;
>
> @@ -679,9 +708,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++;
> }
> }
> @@ -690,19 +719,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++;
> }
> }
> @@ -717,12 +746,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);
> @@ -738,14 +768,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))) {
> @@ -802,9 +833,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,
> @@ -826,17 +857,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;
> }
>
> @@ -863,15 +895,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;
> @@ -879,37 +912,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)
> @@ -920,7 +953,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);
> }
>
> @@ -928,7 +961,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;
> @@ -939,20 +972,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;
> }
> @@ -970,43 +1005,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, int index)
> +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;
>
> - if (index) {
> - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> - index);
> - return -EINVAL;
> - }
Spurious code removal
> -
> - 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 +1046,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 +1056,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 +1068,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 +1097,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 +1136,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 +1173,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 +1186,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 +1208,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,33 +1252,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, int index)
> +static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus)
> {
> + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
> int ret;
>
> - if (index) {
> - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> - index);
> - return -EINVAL;
> - }
> -
> - pmic_arb->base_apid = 0;
> - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> + 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;
> }
> @@ -1257,15 +1285,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
> * 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;
>
> @@ -1275,8 +1304,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;
> }
> @@ -1299,62 +1328,20 @@ 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 *pmic_arb, int index)
> -{
> - int ret;
> -
> - if (index == 0) {
> - pmic_arb->base_apid = 0;
> - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> - PMIC_ARB_FEATURES_PERIPH_MASK;
> - } else if (index == 1) {
> - pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> - PMIC_ARB_FEATURES_PERIPH_MASK;
> - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
> - PMIC_ARB_FEATURES_PERIPH_MASK;
> - } else {
> - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> - index);
> - return -EINVAL;
> - }
> -
> - 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;
> -}
Spurious code removal
> -
> /*
> * 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;
>
> @@ -1364,8 +1351,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;
> }
> @@ -1387,104 +1374,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;
> }
>
> @@ -1504,9 +1497,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;
> }
>
> /*
> @@ -1515,9 +1508,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);
Spurious whitespace
> }
>
> static const struct pmic_arb_ver_ops pmic_arb_v1 = {
> @@ -1587,7 +1580,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_v7,
> + .init_apid = pmic_arb_init_apid_v5,
Seems to be a spurious change
> .ppid_to_apid = pmic_arb_ppid_to_apid_v5,
> .non_data_cmd = pmic_arb_non_data_cmd_v2,
> .offset = pmic_arb_offset_v7,
> @@ -1607,29 +1600,120 @@ 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;
> +
> + 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);
> + raw_spin_lock_init(&pmic_arb->lock);
> +
> hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
>
> if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
> @@ -1643,30 +1727,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, 0);
> - 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) {
> @@ -1695,42 +1761,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[] = {
>
With the issues fixed, it looks fine overall.
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH 2/4] firmware: ti_sci: Unconditionally register reset handler
From: Markus Schneider-Pargmann @ 2024-04-02 8:19 UTC (permalink / raw)
To: Andrew Davis
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Santosh Shilimkar,
Nishanth Menon, Vignesh Raghavendra, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20240326223730.54639-3-afd@ti.com>
On Tue, Mar 26, 2024 at 05:37:28PM -0500, Andrew Davis wrote:
> There was once a limitation that there could only be one system
> reset handler. Due to that we only would register this handler
> when a non-standard device tree property was found, else we left
> the default handler in place (usually PSCI). Now that we can
> have multiple handlers, and TI-SCI reset is always available
> in the firmware, register this handler unconditionally.
>
> This priority is left at the default so higher priority handlers
> (like PSCI) are still attempted first.
>
> Signed-off-by: Andrew Davis <afd@ti.com>
Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
Best
Markus
> ---
> drivers/firmware/ti_sci.c | 15 ++++-----------
> 1 file changed, 4 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 9885e1763591b..160968301b1fb 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -3299,7 +3299,6 @@ static int ti_sci_probe(struct platform_device *pdev)
> struct mbox_client *cl;
> int ret = -EINVAL;
> int i;
> - int reboot = 0;
> u32 h_id;
>
> desc = device_get_match_data(dev);
> @@ -3323,8 +3322,6 @@ static int ti_sci_probe(struct platform_device *pdev)
> }
> }
>
> - reboot = of_property_read_bool(dev->of_node,
> - "ti,system-reboot-controller");
> INIT_LIST_HEAD(&info->node);
> minfo = &info->minfo;
>
> @@ -3395,14 +3392,10 @@ static int ti_sci_probe(struct platform_device *pdev)
>
> ti_sci_setup_ops(info);
>
> - if (reboot) {
> - ret = devm_register_restart_handler(dev,
> - tisci_reboot_handler,
> - info);
> - if (ret) {
> - dev_err(dev, "reboot registration fail(%d)\n", ret);
> - goto out;
> - }
> + ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
> + if (ret) {
> + dev_err(dev, "reboot registration fail(%d)\n", ret);
> + goto out;
> }
>
> dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
> --
> 2.39.2
>
^ permalink raw reply
* Re: [PATCH 1/4] firmware: ti_sci: Use devm_register_restart_handler()
From: Markus Schneider-Pargmann @ 2024-04-02 8:14 UTC (permalink / raw)
To: Andrew Davis
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Santosh Shilimkar,
Nishanth Menon, Vignesh Raghavendra, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20240326223730.54639-2-afd@ti.com>
On Tue, Mar 26, 2024 at 05:37:27PM -0500, Andrew Davis wrote:
> Use device life-cycle managed register function to simplify probe.
>
> Signed-off-by: Andrew Davis <afd@ti.com>
> Reviewed-by: Gabriel Somlo <gsomlo@gmail.com>
Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
Best
Markus
> ---
> drivers/firmware/ti_sci.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 8b9a2556de16d..9885e1763591b 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -87,7 +87,6 @@ struct ti_sci_desc {
> * struct ti_sci_info - Structure representing a TI SCI instance
> * @dev: Device pointer
> * @desc: SoC description for this instance
> - * @nb: Reboot Notifier block
> * @d: Debugfs file entry
> * @debug_region: Memory region where the debug message are available
> * @debug_region_size: Debug region size
> @@ -103,7 +102,6 @@ struct ti_sci_desc {
> */
> struct ti_sci_info {
> struct device *dev;
> - struct notifier_block nb;
> const struct ti_sci_desc *desc;
> struct dentry *d;
> void __iomem *debug_region;
> @@ -122,7 +120,6 @@ struct ti_sci_info {
>
> #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl)
> #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
> -#define reboot_to_ti_sci_info(n) container_of(n, struct ti_sci_info, nb)
>
> #ifdef CONFIG_DEBUG_FS
>
> @@ -3254,10 +3251,9 @@ devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
> }
> EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
>
> -static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
> - void *cmd)
> +static int tisci_reboot_handler(struct sys_off_data *data)
> {
> - struct ti_sci_info *info = reboot_to_ti_sci_info(nb);
> + struct ti_sci_info *info = data->cb_data;
> const struct ti_sci_handle *handle = &info->handle;
>
> ti_sci_cmd_core_reboot(handle);
> @@ -3400,10 +3396,9 @@ static int ti_sci_probe(struct platform_device *pdev)
> ti_sci_setup_ops(info);
>
> if (reboot) {
> - info->nb.notifier_call = tisci_reboot_handler;
> - info->nb.priority = 128;
> -
> - ret = register_restart_handler(&info->nb);
> + ret = devm_register_restart_handler(dev,
> + tisci_reboot_handler,
> + info);
> if (ret) {
> dev_err(dev, "reboot registration fail(%d)\n", ret);
> goto out;
> --
> 2.39.2
>
^ permalink raw reply
* Re: [PATCH v7 3/6] spmi: pmic-arb: Make the APID init a version operation
From: Neil Armstrong @ 2024-04-02 8:14 UTC (permalink / raw)
To: Abel Vesa, Stephen Boyd, Matthias Brugger, Bjorn Andersson,
Konrad Dybcio, Dmitry Baryshkov, AngeloGioacchino Del Regno,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Srini Kandagatla, Johan Hovold, linux-kernel, linux-arm-kernel,
linux-arm-msm, linux-mediatek, devicetree
In-Reply-To: <20240329-spmi-multi-master-support-v7-3-7b902824246c@linaro.org>
On 29/03/2024 19:54, Abel Vesa wrote:
> 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.
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
> ---
> drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++----------------
> 1 file changed, 124 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 9ed1180fe31f..38fed8a585fe 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c
> @@ -183,6 +183,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.
> @@ -202,6 +203,7 @@ struct spmi_pmic_arb {
> */
> struct pmic_arb_ver_ops {
> const char *ver_str;
> + int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> 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,
> @@ -942,6 +944,38 @@ 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, int index)
> +{
> + u32 *mapping_table;
> +
> + if (index) {
> + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> + index);
> + return -EINVAL;
> + }
> +
> + 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;
> @@ -1144,6 +1178,40 @@ 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 index)
> +{
> + int ret;
> +
> + if (index) {
> + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> + index);
> + return -EINVAL;
> + }
> +
> + 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.
> @@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
> return offset;
> }
>
> +/*
> + * 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 *pmic_arb, int index)
> +{
> + int ret;
> +
> + if (index == 0) {
> + pmic_arb->base_apid = 0;
> + pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> + PMIC_ARB_FEATURES_PERIPH_MASK;
> + } else if (index == 1) {
> + pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
> + PMIC_ARB_FEATURES_PERIPH_MASK;
> + pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
> + PMIC_ARB_FEATURES_PERIPH_MASK;
> + } else {
> + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
> + index);
> + return -EINVAL;
> + }
> +
> + 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;
> +}
> +
> /*
> * v7 offset per ee and per apid for observer channels and per apid for
> * read/write channels.
> @@ -1358,6 +1469,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,
> @@ -1372,6 +1484,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,
> @@ -1386,6 +1499,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,
> @@ -1400,6 +1514,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,
> @@ -1414,6 +1529,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_v7,
> .ppid_to_apid = pmic_arb_ppid_to_apid_v5,
> .non_data_cmd = pmic_arb_non_data_cmd_v2,
> .offset = pmic_arb_offset_v7,
> @@ -1439,7 +1555,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;
>
> @@ -1467,12 +1582,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) {
> @@ -1506,58 +1615,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, 0);
> + if (err)
> + return err;
>
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
> pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
> @@ -1599,16 +1667,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);
> @@ -1617,15 +1675,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);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
^ permalink raw reply
* Re: [PATCH] arm64: dts: debix-a: Remove i2c2 from base .dts
From: Marco Felsch @ 2024-04-02 8:05 UTC (permalink / raw)
To: Laurent Pinchart
Cc: devicetree, imx, linux-arm-kernel, Rob Herring, Conor Dooley,
Krzysztof Kozlowski, Fabio Estevam, Sascha Hauer, Jacopo Mondi,
Pengutronix Kernel Team, Jacopo Mondi, Shawn Guo
In-Reply-To: <20240402075903.GB10288@pendragon.ideasonboard.com>
On 24-04-02, Laurent Pinchart wrote:
> Hi Marco,
>
> On Tue, Apr 02, 2024 at 08:54:43AM +0200, Marco Felsch wrote:
> > On 24-03-26, Laurent Pinchart wrote:
> > > From: Jacopo Mondi <jacopo@jmondi.org>
> > >
> > > The I2C2 bus is used for the CSI and DSI connectors only, no devices are
> > > connected to it on neither the Debix Model A nor its IO board. Remove
> > > the bus from the board's .dts and rely on display panel or camera sensor
> > > overlsy to enable it when necessary.
> >
> > I would rather remove the status line instead of removing the whole node
> > since the bus is intented to be used for CSI and DSI and therefore the
> > muxing should be valid. This makes it easier for overlay authors since
> > they don't need to check the mux setup each time.
>
> Seems sensible to me. I will drop the clock-frequency property in
> addition to the status property, as the frequency depends solely on the
> devices connected to the CSI and DSI connectors.
Make sense. With these changes, feel free to add my:
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Regards,
Marco
> > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > > .../boot/dts/freescale/imx8mp-debix-model-a.dts | 14 --------------
> > > 1 file changed, 14 deletions(-)
> > >
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > > index 5ac77eaf23d5..26c303b7c7fa 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > > @@ -210,13 +210,6 @@ ldo5: LDO5 {
> > > };
> > > };
> > >
> > > -&i2c2 {
> > > - clock-frequency = <100000>;
> > > - pinctrl-names = "default";
> > > - pinctrl-0 = <&pinctrl_i2c2>;
> > > - status = "okay";
> > > -};
> > > -
> > > &i2c3 {
> > > clock-frequency = <400000>;
> > > pinctrl-names = "default";
> > > @@ -392,13 +385,6 @@ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2
> > > >;
> > > };
> > >
> > > - pinctrl_i2c2: i2c2grp {
> > > - fsl,pins = <
> > > - MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
> > > - MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2
> > > - >;
> > > - };
> > > -
> > > pinctrl_i2c3: i2c3grp {
> > > fsl,pins = <
> > > MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2
>
> --
> Regards,
>
> Laurent Pinchart
>
^ permalink raw reply
* [PATCH v1 5/5] LoongArch: dts: Add PWM support to Loongson-2K2000
From: Binbin Zhou @ 2024-04-02 7:59 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou
In-Reply-To: <cover.1711953223.git.zhoubinbin@loongson.cn>
The module is supported, enable it.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
arch/loongarch/boot/dts/loongson-2k2000.dtsi | 60 ++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
index 605efaba7292..278cbc27d19b 100644
--- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
@@ -126,6 +126,66 @@ msi: msi-controller@1fe01140 {
interrupt-parent = <&eiointc>;
};
+ pwm@100a0000 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0000 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@100a0100 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0100 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@100a0200 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0200 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@100a0300 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0300 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@100a0400 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0400 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@100a0500 {
+ compatible = "loongson,ls2k2000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x100a0500 0x0 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_MISC_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
rtc0: rtc@100d0100 {
compatible = "loongson,ls2k2000-rtc", "loongson,ls7a-rtc";
reg = <0x0 0x100d0100 0x0 0x100>;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 4/5] LoongArch: dts: Add PWM support to Loongson-2K1000
From: Binbin Zhou @ 2024-04-02 7:59 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou
In-Reply-To: <cover.1711953223.git.zhoubinbin@loongson.cn>
The module is supported, enable it.
Also, add the pwm-fan and cooling-maps associated with it.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
.../boot/dts/loongson-2k1000-ref.dts | 24 +++++++++++
arch/loongarch/boot/dts/loongson-2k1000.dtsi | 42 ++++++++++++++++++-
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
index ed4d32434041..a7cd3912f30d 100644
--- a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
+++ b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
@@ -5,6 +5,7 @@
/dts-v1/;
+#include "dt-bindings/thermal/thermal.h"
#include "loongson-2k1000.dtsi"
/ {
@@ -38,6 +39,13 @@ linux,cma {
linux,cma-default;
};
};
+
+ fan0: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <255 153 85 25>;
+ pwms = <&pwm1 1 100000 0>;
+ #cooling-cells = <2>;
+ };
};
&gmac0 {
@@ -97,6 +105,22 @@ spidev@0 {
};
};
+&pwm1 {
+ status = "okay";
+
+ pinctrl-0 = <&pwm1_pins_default>;
+ pinctrl-names = "default";
+};
+
+&cpu_thermal {
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device = <&fan0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
index 49a70f8c3cab..0ebaace3214b 100644
--- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
@@ -68,7 +68,7 @@ i2c-gpio-1 {
};
thermal-zones {
- cpu-thermal {
+ cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tsensor 0>;
@@ -316,6 +316,46 @@ i2c3: i2c@1fe21800 {
status = "disabled";
};
+ pwm@1fe22000 {
+ compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1fe22000 0x0 0x10>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@1fe22010 {
+ compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1fe22010 0x0 0x10>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@1fe22020 {
+ compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1fe22020 0x0 0x10>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@1fe22030 {
+ compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1fe22030 0x0 0x10>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
pmc: power-management@1fe27000 {
compatible = "loongson,ls2k1000-pmc", "loongson,ls2k0500-pmc", "syscon";
reg = <0x0 0x1fe27000 0x0 0x58>;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] arm64: dts: debix-a: Remove i2c2 from base .dts
From: Laurent Pinchart @ 2024-04-02 7:59 UTC (permalink / raw)
To: Marco Felsch
Cc: devicetree, imx, linux-arm-kernel, Rob Herring, Conor Dooley,
Krzysztof Kozlowski, Fabio Estevam, Sascha Hauer, Jacopo Mondi,
Pengutronix Kernel Team, Jacopo Mondi, Shawn Guo
In-Reply-To: <20240402065443.hpinj7oftcst6fwd@pengutronix.de>
Hi Marco,
On Tue, Apr 02, 2024 at 08:54:43AM +0200, Marco Felsch wrote:
> On 24-03-26, Laurent Pinchart wrote:
> > From: Jacopo Mondi <jacopo@jmondi.org>
> >
> > The I2C2 bus is used for the CSI and DSI connectors only, no devices are
> > connected to it on neither the Debix Model A nor its IO board. Remove
> > the bus from the board's .dts and rely on display panel or camera sensor
> > overlsy to enable it when necessary.
>
> I would rather remove the status line instead of removing the whole node
> since the bus is intented to be used for CSI and DSI and therefore the
> muxing should be valid. This makes it easier for overlay authors since
> they don't need to check the mux setup each time.
Seems sensible to me. I will drop the clock-frequency property in
addition to the status property, as the frequency depends solely on the
devices connected to the CSI and DSI connectors.
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > .../boot/dts/freescale/imx8mp-debix-model-a.dts | 14 --------------
> > 1 file changed, 14 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > index 5ac77eaf23d5..26c303b7c7fa 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
> > @@ -210,13 +210,6 @@ ldo5: LDO5 {
> > };
> > };
> >
> > -&i2c2 {
> > - clock-frequency = <100000>;
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&pinctrl_i2c2>;
> > - status = "okay";
> > -};
> > -
> > &i2c3 {
> > clock-frequency = <400000>;
> > pinctrl-names = "default";
> > @@ -392,13 +385,6 @@ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2
> > >;
> > };
> >
> > - pinctrl_i2c2: i2c2grp {
> > - fsl,pins = <
> > - MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
> > - MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2
> > - >;
> > - };
> > -
> > pinctrl_i2c3: i2c3grp {
> > fsl,pins = <
> > MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH v1 2/5] pwm: Add Loongson PWM controller support
From: Binbin Zhou @ 2024-04-02 7:58 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou, Juxin Gao
In-Reply-To: <cover.1711953223.git.zhoubinbin@loongson.cn>
This commit adds a generic PWM framework driver for the PWM controller
found on Loongson family chips.
Signed-off-by: Juxin Gao <gaojuxin@loongson.com>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
MAINTAINERS | 1 +
drivers/pwm/Kconfig | 10 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-loongson.c | 300 +++++++++++++++++++++++++++++++++++++
4 files changed, 312 insertions(+)
create mode 100644 drivers/pwm/pwm-loongson.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 9c4f3186e7f4..66946f4cc3db 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12758,6 +12758,7 @@ M: Binbin Zhou <zhoubinbin@loongson.cn>
L: linux-pwm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
+F: drivers/pwm/pwm-loongson.c
LOONGSON-2 SOC SERIES CLOCK DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 4b956d661755..bb163c65e5ae 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -324,6 +324,16 @@ config PWM_KEEMBAY
To compile this driver as a module, choose M here: the module
will be called pwm-keembay.
+config PWM_LOONGSON
+ tristate "Loongson PWM support"
+ depends on MACH_LOONGSON64
+ help
+ Generic PWM framework driver for Loongson family.
+ It can be found on Loongson-2K series cpu and Loongson LS7A bridge chips.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-loongson.
+
config PWM_LP3943
tristate "TI/National Semiconductor LP3943 PWM support"
depends on MFD_LP3943
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index c5ec9e168ee7..bffa49500277 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PWM_INTEL_LGM) += pwm-intel-lgm.o
obj-$(CONFIG_PWM_IQS620A) += pwm-iqs620a.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_KEEMBAY) += pwm-keembay.o
+obj-$(CONFIG_PWM_LOONGSON) += pwm-loongson.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c
new file mode 100644
index 000000000000..0afae42113a5
--- /dev/null
+++ b/drivers/pwm/pwm-loongson.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Loongson PWM driver
+ *
+ * Author: Juxin Gao <gaojuxin@loongson.cn>
+ * Further cleanup and restructuring by:
+ * Binbin Zhou <zhoubinbin@loongson.cn>
+ *
+ * Copyright (C) 2017-2024 Loongson Technology Corporation Limited.
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/units.h>
+
+/* Loongson PWM registers */
+#define PWM_DUTY 0x4 /* Low Pulse Buffer Register */
+#define PWM_PERIOD 0x8 /* Pulse Period Buffer Register */
+#define PWM_CTRL 0xc /* Control Register */
+
+/* Control register bits */
+#define PWM_CTRL_EN BIT(0) /* Counter Enable Bit */
+#define PWM_CTRL_OE BIT(3) /* Pulse Output Enable Control Bit, Valid Low */
+#define PWM_CTRL_SINGLE BIT(4) /* Single Pulse Control Bit */
+#define PWM_CTRL_INTE BIT(5) /* Interrupt Enable Bit */
+#define PWM_CTRL_INT BIT(6) /* Interrupt Bit */
+#define PWM_CTRL_RST BIT(7) /* Counter Reset Bit */
+#define PWM_CTRL_CAPTE BIT(8) /* Measurement Pulse Enable Bit */
+#define PWM_CTRL_INVERT BIT(9) /* Output flip-flop Enable Bit */
+#define PWM_CTRL_DZONE BIT(10) /* Anti-dead Zone Enable Bit */
+
+#define PWM_FREQ_STD (50 * HZ_PER_KHZ)
+
+struct pwm_loongson_ddata {
+ struct pwm_chip chip;
+ struct clk *clk;
+ void __iomem *base;
+ /* The following for PM */
+ u32 ctrl;
+ u32 duty;
+ u32 period;
+};
+
+static inline struct pwm_loongson_ddata *to_pwm_loongson_ddata(struct pwm_chip *chip)
+{
+ return container_of(chip, struct pwm_loongson_ddata, chip);
+}
+
+static inline u32 pwm_loongson_readl(struct pwm_loongson_ddata *ddata, u64 offset)
+{
+ return readl(ddata->base + offset);
+}
+
+static inline void pwm_loongson_writel(struct pwm_loongson_ddata *ddata,
+ u32 val, u64 offset)
+{
+ writel(val, ddata->base + offset);
+}
+
+static int pwm_loongson_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
+ u16 val;
+
+ val = pwm_loongson_readl(ddata, PWM_CTRL);
+
+ if (polarity == PWM_POLARITY_INVERSED)
+ /* Duty cycle defines LOW period of PWM */
+ val |= PWM_CTRL_INVERT;
+ else
+ /* Duty cycle defines HIGH period of PWM */
+ val &= ~PWM_CTRL_INVERT;
+
+ pwm_loongson_writel(ddata, val, PWM_CTRL);
+ return 0;
+}
+
+static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
+ u32 val;
+
+ if (pwm->state.polarity == PWM_POLARITY_NORMAL)
+ pwm_loongson_writel(ddata, ddata->period, PWM_DUTY);
+ else if (pwm->state.polarity == PWM_POLARITY_INVERSED)
+ pwm_loongson_writel(ddata, 0, PWM_DUTY);
+
+ val = pwm_loongson_readl(ddata, PWM_CTRL);
+ val &= ~PWM_CTRL_EN;
+ pwm_loongson_writel(ddata, val, PWM_CTRL);
+}
+
+static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
+ u32 val;
+
+ pwm_loongson_writel(ddata, ddata->duty, PWM_DUTY);
+ pwm_loongson_writel(ddata, ddata->period, PWM_PERIOD);
+
+ val = pwm_loongson_readl(ddata, PWM_CTRL);
+ val |= PWM_CTRL_EN;
+ pwm_loongson_writel(ddata, val, PWM_CTRL);
+
+ return 0;
+}
+
+static u32 pwm_loongson_set_config(struct pwm_loongson_ddata *ddata, int ns,
+ u64 clk_rate, u64 offset)
+{
+ u32 val;
+ u64 c;
+
+ c = clk_rate * ns;
+ do_div(c, NSEC_PER_SEC);
+ val = c < 1 ? 1 : c;
+
+ pwm_loongson_writel(ddata, val, offset);
+
+ return val;
+}
+
+static int pwm_loongson_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
+ struct device *dev = chip->dev;
+ u64 clk_rate;
+
+ if (period_ns > NANOHZ_PER_HZ || duty_ns > NANOHZ_PER_HZ)
+ return -ERANGE;
+
+ clk_rate = has_acpi_companion(dev) ? PWM_FREQ_STD
+ : clk_get_rate(ddata->clk);
+
+ ddata->period = pwm_loongson_set_config(ddata, period_ns,
+ clk_rate, PWM_PERIOD);
+ ddata->duty = pwm_loongson_set_config(ddata, duty_ns, clk_rate, PWM_DUTY);
+
+ return 0;
+}
+
+static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ int err;
+ bool enabled = pwm->state.enabled;
+
+ if (state->polarity != pwm->state.polarity) {
+ if (enabled) {
+ pwm_loongson_disable(chip, pwm);
+ enabled = false;
+ }
+
+ err = pwm_loongson_set_polarity(chip, pwm, state->polarity);
+ if (err)
+ return err;
+ }
+
+ if (!state->enabled) {
+ if (enabled)
+ pwm_loongson_disable(chip, pwm);
+ return 0;
+ }
+
+ err = pwm_loongson_config(chip, pwm, state->duty_cycle, state->period);
+ if (err)
+ return err;
+
+ if (!enabled)
+ err = pwm_loongson_enable(chip, pwm);
+
+ return err;
+}
+
+static int pwm_loongson_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
+ u32 period, duty, ctrl;
+ u64 ns;
+
+ period = pwm_loongson_readl(ddata, PWM_PERIOD);
+ ns = period * NSEC_PER_SEC;
+ state->period = do_div(ns, period);
+
+ duty = pwm_loongson_readl(ddata, PWM_DUTY);
+ ns = duty * NSEC_PER_SEC;
+ state->duty_cycle = do_div(ns, duty);
+
+ ctrl = pwm_loongson_readl(ddata, PWM_CTRL);
+ state->polarity = (ctrl & PWM_CTRL_INVERT) ? PWM_POLARITY_INVERSED
+ : PWM_POLARITY_NORMAL;
+ state->enabled = (ctrl & PWM_CTRL_EN) ? true : false;
+
+ ddata->ctrl = ctrl;
+ ddata->duty = pwm_loongson_readl(ddata, PWM_DUTY);
+ ddata->period = pwm_loongson_readl(ddata, PWM_PERIOD);
+
+ return 0;
+}
+
+static const struct pwm_ops pwm_loongson_ops = {
+ .apply = pwm_loongson_apply,
+ .get_state = pwm_loongson_get_state,
+};
+
+static int pwm_loongson_probe(struct platform_device *pdev)
+{
+ struct pwm_loongson_ddata *ddata;
+ struct device *dev = &pdev->dev;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ ddata->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ddata->base))
+ return PTR_ERR(ddata->base);
+
+ if (!has_acpi_companion(dev)) {
+ ddata->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(ddata->clk))
+ return PTR_ERR(ddata->clk);
+ }
+
+ ddata->chip.dev = dev;
+ ddata->chip.ops = &pwm_loongson_ops;
+ ddata->chip.npwm = 1;
+ platform_set_drvdata(pdev, ddata);
+
+ return devm_pwmchip_add(dev, &ddata->chip);
+}
+
+static int pwm_loongson_suspend(struct device *dev)
+{
+ struct pwm_loongson_ddata *ddata = dev_get_drvdata(dev);
+
+ ddata->ctrl = pwm_loongson_readl(ddata, PWM_CTRL);
+ ddata->duty = pwm_loongson_readl(ddata, PWM_DUTY);
+ ddata->period = pwm_loongson_readl(ddata, PWM_PERIOD);
+
+ clk_disable_unprepare(ddata->clk);
+
+ return 0;
+}
+
+static int pwm_loongson_resume(struct device *dev)
+{
+ struct pwm_loongson_ddata *ddata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(ddata->clk);
+ if (ret)
+ return ret;
+
+ pwm_loongson_writel(ddata, ddata->ctrl, PWM_CTRL);
+ pwm_loongson_writel(ddata, ddata->duty, PWM_DUTY);
+ pwm_loongson_writel(ddata, ddata->period, PWM_PERIOD);
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(pwm_loongson_pm_ops, pwm_loongson_suspend,
+ pwm_loongson_resume);
+
+static const struct acpi_device_id pwm_loongson_acpi_ids[] = {
+ { "LOON0006" },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, pwm_loongson_acpi_ids);
+
+static const struct of_device_id pwm_loongson_of_ids[] = {
+ { .compatible = "loongson,ls7a-pwm" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, pwm_loongson_of_ids);
+
+static struct platform_driver pwm_loongson_driver = {
+ .probe = pwm_loongson_probe,
+ .driver = {
+ .name = "loongson-pwm",
+ .pm = pm_ptr(&pwm_loongson_pm_ops),
+ .of_match_table = pwm_loongson_of_ids,
+ .acpi_match_table = pwm_loongson_acpi_ids,
+ },
+};
+module_platform_driver(pwm_loongson_driver);
+
+MODULE_DESCRIPTION("Loongson PWM driver");
+MODULE_AUTHOR("Loongson Technology Corporation Limited");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related
* [PATCH v1 3/5] LoongArch: dts: Add PWM support to Loongson-2K0500
From: Binbin Zhou @ 2024-04-02 7:58 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou
In-Reply-To: <cover.1711953223.git.zhoubinbin@loongson.cn>
The module is supported, enable it.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
arch/loongarch/boot/dts/loongson-2k0500.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi
index 413b83366367..86e86a267779 100644
--- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi
@@ -148,6 +148,26 @@ eiointc: interrupt-controller@1fe11600 {
interrupts = <3>;
};
+ pwm@1ff5c000 {
+ compatible = "loongson,ls2k0500-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1ff5c000 0x0 0x10>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <20>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm@1ff5c010 {
+ compatible = "loongson,ls2k0500-pwm", "loongson,ls7a-pwm";
+ reg = <0x0 0x1ff5c010 0x0 0x10>;
+ interrupt-parent = <&eiointc>;
+ interrupts = <21>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
gmac0: ethernet@1f020000 {
compatible = "snps,dwmac-3.70a";
reg = <0x0 0x1f020000 0x0 0x10000>;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 1/5] dt-bindings: pwm: Add Loongson PWM controller
From: Binbin Zhou @ 2024-04-02 7:58 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou
In-Reply-To: <cover.1711953223.git.zhoubinbin@loongson.cn>
Add Loongson PWM controller binding with DT schema format using
json-schema.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
.../devicetree/bindings/pwm/pwm-loongson.yaml | 64 +++++++++++++++++++
MAINTAINERS | 6 ++
2 files changed, 70 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
diff --git a/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
new file mode 100644
index 000000000000..d25904468353
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/pwm-loongson.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson PWM Controller
+
+maintainers:
+ - Binbin Zhou <zhoubinbin@loongson.cn>
+
+description:
+ It is the generic PWM framework driver for Loongson family.
+ Each PWM has one pulse width output signal and one pulse input
+ signal to be measured.
+ It can be found on Loongson-2K series cpus and Loongson LS7A bridge chips.
+
+allOf:
+ - $ref: pwm.yaml#
+
+properties:
+ compatible:
+ oneOf:
+ - const: loongson,ls7a-pwm
+ - items:
+ - enum:
+ - loongson,ls2k0500-pwm
+ - loongson,ls2k1000-pwm
+ - loongson,ls2k2000-pwm
+ - const: loongson,ls7a-pwm
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ '#pwm-cells':
+ const: 3
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - '#pwm-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/loongson,ls2k-clk.h>
+ pwm@1fe22000 {
+ compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm";
+ reg = <0x1fe22000 0x10>;
+ interrupt-parent = <&liointc0>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
+ #pwm-cells = <3>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 96496dbcae6d..9c4f3186e7f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12753,6 +12753,12 @@ S: Maintained
F: Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
F: drivers/i2c/busses/i2c-ls2x.c
+LOONGSON PWM DRIVER
+M: Binbin Zhou <zhoubinbin@loongson.cn>
+L: linux-pwm@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
+
LOONGSON-2 SOC SERIES CLOCK DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: linux-clk@vger.kernel.org
--
2.43.0
^ permalink raw reply related
* [PATCH v1 0/5] pwm: Introduce pwm driver for the Loongson family chips
From: Binbin Zhou @ 2024-04-02 7:58 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Huacai Chen, loongson-kernel, linux-pwm, devicetree, Xuerui Wang,
loongarch, Binbin Zhou
Hi all:
This patchset introduce a generic PWM framework driver for Loongson family.
Each PWM has one pulse width output signal and one pulse input signal to be measured.
It can be found on Loongson-2K series cpus and Loongson LS7A bridge chips.
Thanks.
Binbin Zhou (5):
dt-bindings: pwm: Add Loongson PWM controller
pwm: Add Loongson PWM controller support
LoongArch: dts: Add PWM support to Loongson-2K0500
LoongArch: dts: Add PWM support to Loongson-2K1000
LoongArch: dts: Add PWM support to Loongson-2K2000
.../devicetree/bindings/pwm/pwm-loongson.yaml | 64 ++++
MAINTAINERS | 7 +
arch/loongarch/boot/dts/loongson-2k0500.dtsi | 20 ++
.../boot/dts/loongson-2k1000-ref.dts | 24 ++
arch/loongarch/boot/dts/loongson-2k1000.dtsi | 42 ++-
arch/loongarch/boot/dts/loongson-2k2000.dtsi | 60 ++++
drivers/pwm/Kconfig | 10 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-loongson.c | 300 ++++++++++++++++++
9 files changed, 527 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
create mode 100644 drivers/pwm/pwm-loongson.c
--
2.43.0
^ permalink raw reply
* Re: [PATCH v2 17/18] dt-bindings: pci: rockchip,rk3399-pcie-ep: Add ep-gpios property
From: Damien Le Moal @ 2024-04-02 7:55 UTC (permalink / raw)
To: Krzysztof Kozlowski, Manivannan Sadhasivam, Lorenzo Pieralisi,
Kishon Vijay Abraham I, Shawn Lin, Krzysztof Wilczyński,
Bjorn Helgaas, Heiko Stuebner, linux-pci, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
Cc: linux-rockchip, linux-arm-kernel, Rick Wertenbroek,
Wilfred Mallawa, Niklas Cassel
In-Reply-To: <80c4c37b-8c5c-4628-a455-fcccfc3b3730@kernel.org>
On 4/2/24 16:38, Damien Le Moal wrote:
> On 4/2/24 16:33, Krzysztof Kozlowski wrote:
>> On 02/04/2024 01:36, Damien Le Moal wrote:
>>> On 4/1/24 18:57, Krzysztof Kozlowski wrote:
>>>> On 01/04/2024 01:06, Damien Le Moal wrote:
>>>>> On 3/30/24 18:16, Krzysztof Kozlowski wrote:
>>>>>> On 30/03/2024 05:19, Damien Le Moal wrote:
>>>>>>> From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>>>
>>>>>>> Describe the `ep-gpios` property which is used to map the PERST# input
>>>>>>> signal for endpoint mode.
>>>>>>>
>>>>>>> Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>>>>>> ---
>>>>>>> .../devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml | 3 +++
>>>>>>> 1 file changed, 3 insertions(+)
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>>> index 6b62f6f58efe..9331d44d6963 100644
>>>>>>> --- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>>> +++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>>> @@ -30,6 +30,9 @@ properties:
>>>>>>> maximum: 32
>>>>>>> default: 32
>>>>>>>
>>>>>>> + ep-gpios:
>>>>>>> + description: Input GPIO configured for the PERST# signal.
>>>>>>
>>>>>> Missing maxItems. But more important: why existing property perst-gpios,
>>>>>> which you already have there in common schema, is not correct for this case?
>>>>>
>>>>> I am confused... Where do you find perst-gpios defined for the rk3399 ?
>>>>> Under Documentation/devicetree/bindings/pci/, the only schema I see using
>>>>> perst-gpios property are for the qcom (Qualcomm) controllers.
>>>>
>>>> You are right, it's so far only in Qualcomm.
>>>>
>>>>> The RC bindings for the rockchip rk3399 PCIe controller
>>>>> (pci/rockchip,rk3399-pcie.yaml) already define the ep-gpios property. So if
>>>>
>>>> Any reason why this cannot be named like GPIO? Is there already a user
>>>> of this in Linux kernel? Commit msg says nothing about this, so that's
>>>> why I would expect name matching the signal.
>>>
>>> The RC-mode PCIe controller node of the rk3399 DTS already defines the ep-gpios
>>> property for RC side PERST# signal handling. So we simply reused the exact same
>>> name to be consistent between RC and EP. I personnally have no preferences. If
>>> there is an effort to rename such signal with some preferred pattern, I will
>>> follow. For the EP node, there was no PERST signal handling in the driver and
>>> no property defined for it, so any name is fine. "perst-gpios" would indeed be
>>> a better name, but again, given that the RC controller node has ep-gpios, we
>>> reused that. What is your recommendation here ?
>>
>> Actually I don't know, perst and ep would work for me. If you do not
>> have code for this in the driver yet (nothing is shared between ep and
>> host), then maybe let's go with perst to match the actual name.
>
> That works for me. The other simple solution would be to move the RC node
> ep-gpios description to the common schema pci/rockchip,rk3399-pcie-common.yaml,
> maybe ? Otherwise, perst-gpios like the Qualcomm schemas would be nice too.
Thinking more about this, I think moving the ep-gpios description to the common
schema is the right thing to do given that the driver uses common code between
RC and EP to get that property. But if that is not acceptable, I can rename it
and get that property in the controller EP mode initialization code. That will
be add a little more code in the driver.
>
>>
>> Anyway, you need maxItems. I sent a patch for the other binding:
>> https://lore.kernel.org/all/20240401100058.15749-1-krzysztof.kozlowski@linaro.org/
>
> Thanks for that.
>
>>
>> Best regards,
>> Krzysztof
>>
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH v3 6/7] PCI: dwc: rcar-gen4: Add support for r8a779g0
From: Geert Uytterhoeven @ 2024-04-02 7:53 UTC (permalink / raw)
To: Yoshihiro Shimoda
Cc: lpieralisi, kw, robh, bhelgaas, krzysztof.kozlowski+dt, conor+dt,
jingoohan1, mani, marek.vasut+renesas, linux-pci, devicetree,
linux-renesas-soc
In-Reply-To: <20240401023942.134704-7-yoshihiro.shimoda.uh@renesas.com>
Hi Shimoda-san,
On Mon, Apr 1, 2024 at 4:40 AM Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
> This driver previously supported r8a779f0 (R-Car S4-8). Add support
> for r8a779g0 (R-Car V4H).
>
> To support r8a779g0, it requires specific firmware.
>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Thanks for your patch!
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +static int rcar_gen4_pcie_update_phy_firmware(struct rcar_gen4_pcie *rcar)
> +{
> + const u32 check_addr[] = { 0x00101018, 0x00101118, 0x00101021, 0x00101121};
> + struct dw_pcie *dw = &rcar->dw;
> + const struct firmware *fw;
> + unsigned int i, timeout;
> + u32 data;
> + int ret;
> +
> + ret = request_firmware(&fw, RCAR_GEN4_PCIE_FIRMWARE_NAME, dw->dev);
> + if (ret) {
> + dev_err(dw->dev, "%s: Requesting firmware failed\n", __func__);
> + return ret;
> + }
> +
> + for (i = 0; i < (fw->size / 2); i++) {
> + data = fw->data[i * 2] | fw->data[(i * 2) + 1] << 8;
> + timeout = 100;
> +retry_data:
> + dw_pcie_writel_dbi(dw, PRTLGC89, RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR + i);
> + dw_pcie_writel_dbi(dw, PRTLGC90, data);
> + if (rcar_gen4_pcie_reg_check_bit(rcar, PRTLGC89, BIT(30)) < 0) {
If you would invert the logic here, you could "break" here, ...
> + if (!(--timeout)) {
> + ret = -ETIMEDOUT;
> + goto exit;
> + }
> + usleep_range(100, 200);
> + goto retry_data;
... and convert "retry_data: ... goto retry_data" into "do { ... } while (1)",
avoiding the goto.
> + }
> + }
> +
> + rcar_gen4_pcie_phy_reg_update_bits(rcar, RCAR_GEN4_PCIE_PHY_0f8, BIT(17), BIT(17));
> +
> + for (i = 0; i < ARRAY_SIZE(check_addr); i++) {
> + timeout = 100;
> +retry_check:
> + dw_pcie_writel_dbi(dw, PRTLGC89, check_addr[i]);
> + ret = rcar_gen4_pcie_reg_check_bit(rcar, PRTLGC89, BIT(30));
> + ret |= rcar_gen4_pcie_reg_check_bit(rcar, PRTLGC90, BIT(0));
> + if (ret < 0) {
> + if (!(--timeout)) {
> + ret = -ETIMEDOUT;
> + goto exit;
> + }
> + usleep_range(100, 200);
> + goto retry_check;
Likewise.
> + }
> + }
> +
> + ret = 0;
> +exit:
> + release_firmware(fw);
> +
> + return ret;
> +}
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 06/10] dt-bindings: iio: dac: add bindings doc for AXI DAC driver
From: Nuno Sá @ 2024-04-02 7:51 UTC (permalink / raw)
To: David Lechner, nuno.sa
Cc: linux-iio, devicetree, Dragos Bogdan, Jonathan Cameron,
Lars-Peter Clausen, Michael Hennerich, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan
In-Reply-To: <CAMknhBHKcy9KO=8vuAvF0twY4x14sFq3FLW4ygORMn2G5k7WSg@mail.gmail.com>
On Fri, 2024-03-29 at 13:46 -0500, David Lechner wrote:
> On Thu, Mar 28, 2024 at 8:22 AM Nuno Sa via B4 Relay
> <devnull+nuno.sa.analog.com@kernel.org> wrote:
> >
> > From: Nuno Sa <nuno.sa@analog.com>
> >
> > This adds the bindings documentation for the AXI DAC driver.
> >
> > Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> > ---
> > .../devicetree/bindings/iio/dac/adi,axi-dac.yaml | 62 ++++++++++++++++++++++
> > MAINTAINERS | 7 +++
> > 2 files changed, 69 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> > b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> > new file mode 100644
> > index 000000000000..1018fd274f04
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> > @@ -0,0 +1,62 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/iio/dac/adi,axi-dac.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Analog Devices AXI DAC IP core
> > +
> > +maintainers:
> > + - Nuno Sa <nuno.sa@analog.com>
> > +
> > +description: |
> > + Analog Devices Generic AXI DAC IP core for interfacing a DAC device
> > + with a high speed serial (JESD204B/C) or source synchronous parallel
> > + interface (LVDS/CMOS).
> > + Usually, some other interface type (i.e SPI) is used as a control
> > + interface for the actual DAC, while this IP core will interface
> > + to the data-lines of the DAC and handle the streaming of data into
> > + memory via DMA.
>
> Isn't it the other way around for DAC, from memory to hardware?
Good catch! Yes, copy paste from the axi-adc and obviously missed this :)
- Nuno Sá
^ permalink raw reply
* Re: [PATCH 07/10] dt-bindings: iio: dac: add bindings doc for AD9739A
From: Nuno Sá @ 2024-04-02 7:50 UTC (permalink / raw)
To: David Lechner, nuno.sa
Cc: linux-iio, devicetree, Dragos Bogdan, Jonathan Cameron,
Lars-Peter Clausen, Michael Hennerich, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan
In-Reply-To: <CAMknhBHA3LOhZicUCG32RyiV4+OROJymzm0Qc=wqhfo3u=8vnQ@mail.gmail.com>
On Fri, 2024-03-29 at 14:06 -0500, David Lechner wrote:
> On Thu, Mar 28, 2024 at 8:23 AM Nuno Sa via B4 Relay
> <devnull+nuno.sa.analog.com@kernel.org> wrote:
> >
> > From: Nuno Sa <nuno.sa@analog.com>
> >
> > This adds the bindings documentation for the 14 bit
> > RF Digital-to-Analog converter.
> >
> > Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> > ---
> > .../devicetree/bindings/iio/dac/adi,ad9739a.yaml | 88 ++++++++++++++++++++++
> > MAINTAINERS | 8 ++
> > 2 files changed, 96 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> > b/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> > new file mode 100644
> > index 000000000000..24bcec763a9b
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> > @@ -0,0 +1,88 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/iio/dac/adi,ad9739a.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Analog Devices AD9739A RF DAC
> > +
> > +maintainers:
> > + - Dragos Bogdan <dragos.bogdan@analog.com>
> > + - Nuno Sa <nuno.sa@analog.com>
> > +
> > +description: |
> > + The AD9739A is a 14-bit, 2.5 GSPS high performance RF DACs that are capable
> > + of synthesizing wideband signals from dc up to 3 GHz.
> > +
> > +
> > https://www.analog.com/media/en/technical-documentation/data-sheets/ad9737a_9739a.pdf
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - adi,ad9739a
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + clocks:
> > + maxItems: 1
>
> I also see an IRQ pin on the datasheet. Do we need an interrupts
> property for that?
>
Likely we'll never use it. But yes, it can be documented in the bindings...
> > +
> > + reset-gpios:
> > + maxItems: 1
> > +
> > + vdd_3_3-supply:
> > + description: 3.3V Digital input supply.
>
> vdd33-supply would better match the datasheet name
>
> > +
> > + vdd-supply:
> > + description: 1.8V Digital input supply.
> > +
> > + vdda-supply:
> > + description: 3.3V Analog input supply.
> > +
> > + vddc-supply:
> > + description: 1.8V Clock input supply.
>
> I see a VREF voltage reference input in the datasheet. Do we need a vref-supply?
Same as the IRQ pin.
- Nuno Sá
^ permalink raw reply
* Re: [PATCH 07/10] dt-bindings: iio: dac: add bindings doc for AD9739A
From: Nuno Sá @ 2024-04-02 7:49 UTC (permalink / raw)
To: Krzysztof Kozlowski, David Lechner, nuno.sa
Cc: linux-iio, devicetree, Dragos Bogdan, Jonathan Cameron,
Lars-Peter Clausen, Michael Hennerich, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan
In-Reply-To: <3d876e90-4821-4c00-b880-6966b53c70a7@linaro.org>
On Sat, 2024-03-30 at 19:27 +0100, Krzysztof Kozlowski wrote:
> On 29/03/2024 20:06, David Lechner wrote:
> >
> > > +
> > > + reset-gpios:
> > > + maxItems: 1
> > > +
> > > + vdd_3_3-supply:
> > > + description: 3.3V Digital input supply.
> >
> > vdd33-supply would better match the datasheet name
>
> And would conform to coding style. No underscores in names.
>
> Nuno,
> To avoid comments like this one, please read and follow DTS coding style
> when you work with DTS or Devicetree bindings.
>
Noted...
Thanks!
- Nuno Sá
>
^ permalink raw reply
* Re: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
From: Cristian Marussi @ 2024-04-02 7:48 UTC (permalink / raw)
To: Peng Fan
Cc: Andy Shevchenko, Peng Fan (OSS), Sudeep Holla, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Linus Walleij, Dan Carpenter,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <DU0PR04MB9417E797F4E0F7BB6154B3BE88382@DU0PR04MB9417.eurprd04.prod.outlook.com>
On Sun, Mar 31, 2024 at 01:44:28PM +0000, Peng Fan wrote:
> Hi Andy,
>
Hi Peng,
> > Subject: Re: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> > protocol basic support
> >
> > Sat, Mar 23, 2024 at 08:15:16PM +0800, Peng Fan (OSS) kirjoitti:
> > > From: Peng Fan <peng.fan@nxp.com>
> > >
> > > Add basic implementation of the SCMI v3.2 pincontrol protocol.
> >
> > ...
> >
> > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
> > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
> > > scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
> > > system.o voltage.o powercap.o
> >
> > Actually you want to have := here.
> >
> > > +scmi-protocols-y += pinctrl.o
> >
> >
> >
> > > scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y)
> > > $(scmi-transport-y)
> >
> > Side note: The -objs has to be -y
> >
> > ...
> >
> > > +#include <linux/module.h>
> > > +#include <linux/scmi_protocol.h>
> > > +#include <linux/slab.h>
> >
> > This is semi-random list of headers. Please, follow IWYU principle (include
> > what you use). There are a lot of inclusions I see missing (just in the context of
> > this page I see bits.h, types.h, and asm/byteorder.h).
>
> Is there any documentation about this requirement?
> Some headers are already included by others.
>
Andy made (mostly) the same remarks on this same patch ~1-year ago on
this same patch while it was posted by Oleksii.
And I told that time that most of the remarks around devm_ usage were
wrong due to how the SCMI core handles protocol initialization (using a
devres group transparently).
This is what I answered that time.
https://lore.kernel.org/linux-arm-kernel/ZJ78hBcjAhiU+ZBO@e120937-lin/#t
I wont repeat myself, but, in a nutshell the memory allocation like it
is now is fine: a bit happens via devm_ at protocol initialization, the
other is doe via explicit kmalloc at runtime and freed via kfree at
remove time (if needed...i.e. checking the present flag of some structs)
I'll made further remarks on v7 that you just posted.
Thanks,
Cristian
^ permalink raw reply
* Re: [PATCH v2 17/18] dt-bindings: pci: rockchip,rk3399-pcie-ep: Add ep-gpios property
From: Damien Le Moal @ 2024-04-02 7:38 UTC (permalink / raw)
To: Krzysztof Kozlowski, Manivannan Sadhasivam, Lorenzo Pieralisi,
Kishon Vijay Abraham I, Shawn Lin, Krzysztof Wilczyński,
Bjorn Helgaas, Heiko Stuebner, linux-pci, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
Cc: linux-rockchip, linux-arm-kernel, Rick Wertenbroek,
Wilfred Mallawa, Niklas Cassel
In-Reply-To: <57d5d6ea-5fef-423c-9f85-5f295bfa4c5f@linaro.org>
On 4/2/24 16:33, Krzysztof Kozlowski wrote:
> On 02/04/2024 01:36, Damien Le Moal wrote:
>> On 4/1/24 18:57, Krzysztof Kozlowski wrote:
>>> On 01/04/2024 01:06, Damien Le Moal wrote:
>>>> On 3/30/24 18:16, Krzysztof Kozlowski wrote:
>>>>> On 30/03/2024 05:19, Damien Le Moal wrote:
>>>>>> From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>>
>>>>>> Describe the `ep-gpios` property which is used to map the PERST# input
>>>>>> signal for endpoint mode.
>>>>>>
>>>>>> Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>>>>> ---
>>>>>> .../devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml | 3 +++
>>>>>> 1 file changed, 3 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> index 6b62f6f58efe..9331d44d6963 100644
>>>>>> --- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> +++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> @@ -30,6 +30,9 @@ properties:
>>>>>> maximum: 32
>>>>>> default: 32
>>>>>>
>>>>>> + ep-gpios:
>>>>>> + description: Input GPIO configured for the PERST# signal.
>>>>>
>>>>> Missing maxItems. But more important: why existing property perst-gpios,
>>>>> which you already have there in common schema, is not correct for this case?
>>>>
>>>> I am confused... Where do you find perst-gpios defined for the rk3399 ?
>>>> Under Documentation/devicetree/bindings/pci/, the only schema I see using
>>>> perst-gpios property are for the qcom (Qualcomm) controllers.
>>>
>>> You are right, it's so far only in Qualcomm.
>>>
>>>> The RC bindings for the rockchip rk3399 PCIe controller
>>>> (pci/rockchip,rk3399-pcie.yaml) already define the ep-gpios property. So if
>>>
>>> Any reason why this cannot be named like GPIO? Is there already a user
>>> of this in Linux kernel? Commit msg says nothing about this, so that's
>>> why I would expect name matching the signal.
>>
>> The RC-mode PCIe controller node of the rk3399 DTS already defines the ep-gpios
>> property for RC side PERST# signal handling. So we simply reused the exact same
>> name to be consistent between RC and EP. I personnally have no preferences. If
>> there is an effort to rename such signal with some preferred pattern, I will
>> follow. For the EP node, there was no PERST signal handling in the driver and
>> no property defined for it, so any name is fine. "perst-gpios" would indeed be
>> a better name, but again, given that the RC controller node has ep-gpios, we
>> reused that. What is your recommendation here ?
>
> Actually I don't know, perst and ep would work for me. If you do not
> have code for this in the driver yet (nothing is shared between ep and
> host), then maybe let's go with perst to match the actual name.
Forgot to add: the driver code for the EP PERST gpio handling is added in patch
18 of the series, after this one.
>
> Anyway, you need maxItems. I sent a patch for the other binding:
> https://lore.kernel.org/all/20240401100058.15749-1-krzysztof.kozlowski@linaro.org/
>
> Best regards,
> Krzysztof
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH v2 17/18] dt-bindings: pci: rockchip,rk3399-pcie-ep: Add ep-gpios property
From: Damien Le Moal @ 2024-04-02 7:38 UTC (permalink / raw)
To: Krzysztof Kozlowski, Manivannan Sadhasivam, Lorenzo Pieralisi,
Kishon Vijay Abraham I, Shawn Lin, Krzysztof Wilczyński,
Bjorn Helgaas, Heiko Stuebner, linux-pci, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
Cc: linux-rockchip, linux-arm-kernel, Rick Wertenbroek,
Wilfred Mallawa, Niklas Cassel
In-Reply-To: <57d5d6ea-5fef-423c-9f85-5f295bfa4c5f@linaro.org>
On 4/2/24 16:33, Krzysztof Kozlowski wrote:
> On 02/04/2024 01:36, Damien Le Moal wrote:
>> On 4/1/24 18:57, Krzysztof Kozlowski wrote:
>>> On 01/04/2024 01:06, Damien Le Moal wrote:
>>>> On 3/30/24 18:16, Krzysztof Kozlowski wrote:
>>>>> On 30/03/2024 05:19, Damien Le Moal wrote:
>>>>>> From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>>
>>>>>> Describe the `ep-gpios` property which is used to map the PERST# input
>>>>>> signal for endpoint mode.
>>>>>>
>>>>>> Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>>>>> ---
>>>>>> .../devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml | 3 +++
>>>>>> 1 file changed, 3 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> index 6b62f6f58efe..9331d44d6963 100644
>>>>>> --- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> +++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>>> @@ -30,6 +30,9 @@ properties:
>>>>>> maximum: 32
>>>>>> default: 32
>>>>>>
>>>>>> + ep-gpios:
>>>>>> + description: Input GPIO configured for the PERST# signal.
>>>>>
>>>>> Missing maxItems. But more important: why existing property perst-gpios,
>>>>> which you already have there in common schema, is not correct for this case?
>>>>
>>>> I am confused... Where do you find perst-gpios defined for the rk3399 ?
>>>> Under Documentation/devicetree/bindings/pci/, the only schema I see using
>>>> perst-gpios property are for the qcom (Qualcomm) controllers.
>>>
>>> You are right, it's so far only in Qualcomm.
>>>
>>>> The RC bindings for the rockchip rk3399 PCIe controller
>>>> (pci/rockchip,rk3399-pcie.yaml) already define the ep-gpios property. So if
>>>
>>> Any reason why this cannot be named like GPIO? Is there already a user
>>> of this in Linux kernel? Commit msg says nothing about this, so that's
>>> why I would expect name matching the signal.
>>
>> The RC-mode PCIe controller node of the rk3399 DTS already defines the ep-gpios
>> property for RC side PERST# signal handling. So we simply reused the exact same
>> name to be consistent between RC and EP. I personnally have no preferences. If
>> there is an effort to rename such signal with some preferred pattern, I will
>> follow. For the EP node, there was no PERST signal handling in the driver and
>> no property defined for it, so any name is fine. "perst-gpios" would indeed be
>> a better name, but again, given that the RC controller node has ep-gpios, we
>> reused that. What is your recommendation here ?
>
> Actually I don't know, perst and ep would work for me. If you do not
> have code for this in the driver yet (nothing is shared between ep and
> host), then maybe let's go with perst to match the actual name.
That works for me. The other simple solution would be to move the RC node
ep-gpios description to the common schema pci/rockchip,rk3399-pcie-common.yaml,
maybe ? Otherwise, perst-gpios like the Qualcomm schemas would be nice too.
>
> Anyway, you need maxItems. I sent a patch for the other binding:
> https://lore.kernel.org/all/20240401100058.15749-1-krzysztof.kozlowski@linaro.org/
Thanks for that.
>
> Best regards,
> Krzysztof
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH v3] dt-bindings: ata: ahci-da850: Convert to dtschema
From: Animesh Agarwal @ 2024-04-02 7:37 UTC (permalink / raw)
To: Damien Le Moal
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-ide,
devicetree, linux-kernel
In-Reply-To: <24c917f6-9ff8-4bca-8cc2-5c14c64c2c9b@kernel.org>
On Tue, Apr 2, 2024 at 12:55 PM Damien Le Moal <dlemoal@kernel.org> wrote:
> Applied to for-6.10. Thanks !
Thanks for your time Damien.
---
Animesh Agarwal
^ permalink raw reply
* [PATCH] arch: arm: mxc: phyCARD-i.MX27: Add USB support
From: Michael Grzeschik @ 2024-04-02 7:35 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, imx, linux-arm-kernel, linux-kernel,
Michael Grzeschik
This patch adds the pinmux and nodes for usbotg and usbh2.
In v6 revision of the pca100 the usb phys were changed to usb3320 which
are connected by their reset pins. We add the phy configuration to the
description.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
.../dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi | 78 ++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
index abc9233c5a1b1..31b3fc972abbf 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
@@ -15,6 +15,22 @@ memory@a0000000 {
device_type = "memory";
reg = <0xa0000000 0x08000000>; /* 128MB */
};
+
+ usbotgphy: usbotgphy {
+ compatible = "usb-nop-xceiv";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotgphy>;
+ reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
+ #phy-cells = <0>;
+ };
+
+ usbh2phy: usbh2phy {
+ compatible = "usb-nop-xceiv";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2phy>;
+ reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+ #phy-cells = <0>;
+ };
};
&cspi1 {
@@ -84,6 +100,52 @@ MX27_PAD_NFRE_B__NFRE_B 0x0
MX27_PAD_NFWE_B__NFWE_B 0x0
>;
};
+
+ pinctrl_usbotgphy: usbotgphygrp {
+ fsl,pins = <
+ MX27_PAD_USBH1_RCV__GPIO2_25 0x1 /* reset gpio */
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+ MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+ MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+ MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+ MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+ MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+ MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+ MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+ MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+ MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+ MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+ MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+ >;
+ };
+
+ pinctrl_usbh2phy: usbh2phygrp {
+ fsl,pins = <
+ MX27_PAD_USBH1_SUSP__GPIO2_22 0x0 /* reset gpio */
+ >;
+ };
+
+ pinctrl_usbh2: usbh2grp {
+ fsl,pins = <
+ MX27_PAD_USBH2_CLK__USBH2_CLK 0x0
+ MX27_PAD_USBH2_DIR__USBH2_DIR 0x0
+ MX27_PAD_USBH2_NXT__USBH2_NXT 0x0
+ MX27_PAD_USBH2_STP__USBH2_STP 0x0
+ MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x0
+ MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x0
+ MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x0
+ MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x0
+ MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x0
+ MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x0
+ MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x0
+ MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x0
+ >;
+ };
};
};
@@ -95,3 +157,19 @@ &nfc {
nand-on-flash-bbt;
status = "okay";
};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ phy_type = "ulpi";
+ phys = <&usbotgphy>;
+ status = "okay";
+};
+
+&usbh2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2>;
+ phy_type = "ulpi";
+ phys = <&usbh2phy>;
+ status = "okay";
+};
---
base-commit: 5bab5dc780c9ed0c69fc2f828015532acf4a7848
change-id: 20240328-pca100-a600ac4384e7
Best regards,
--
Michael Grzeschik <m.grzeschik@pengutronix.de>
^ permalink raw reply related
* Re: [PATCH v2 17/18] dt-bindings: pci: rockchip,rk3399-pcie-ep: Add ep-gpios property
From: Krzysztof Kozlowski @ 2024-04-02 7:33 UTC (permalink / raw)
To: Damien Le Moal, Manivannan Sadhasivam, Lorenzo Pieralisi,
Kishon Vijay Abraham I, Shawn Lin, Krzysztof Wilczyński,
Bjorn Helgaas, Heiko Stuebner, linux-pci, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
Cc: linux-rockchip, linux-arm-kernel, Rick Wertenbroek,
Wilfred Mallawa, Niklas Cassel
In-Reply-To: <49ecab2e-8f36-47be-a1b0-1bb0089dab0f@kernel.org>
On 02/04/2024 01:36, Damien Le Moal wrote:
> On 4/1/24 18:57, Krzysztof Kozlowski wrote:
>> On 01/04/2024 01:06, Damien Le Moal wrote:
>>> On 3/30/24 18:16, Krzysztof Kozlowski wrote:
>>>> On 30/03/2024 05:19, Damien Le Moal wrote:
>>>>> From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>>
>>>>> Describe the `ep-gpios` property which is used to map the PERST# input
>>>>> signal for endpoint mode.
>>>>>
>>>>> Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
>>>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>>>> ---
>>>>> .../devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml | 3 +++
>>>>> 1 file changed, 3 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>> index 6b62f6f58efe..9331d44d6963 100644
>>>>> --- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>> +++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
>>>>> @@ -30,6 +30,9 @@ properties:
>>>>> maximum: 32
>>>>> default: 32
>>>>>
>>>>> + ep-gpios:
>>>>> + description: Input GPIO configured for the PERST# signal.
>>>>
>>>> Missing maxItems. But more important: why existing property perst-gpios,
>>>> which you already have there in common schema, is not correct for this case?
>>>
>>> I am confused... Where do you find perst-gpios defined for the rk3399 ?
>>> Under Documentation/devicetree/bindings/pci/, the only schema I see using
>>> perst-gpios property are for the qcom (Qualcomm) controllers.
>>
>> You are right, it's so far only in Qualcomm.
>>
>>> The RC bindings for the rockchip rk3399 PCIe controller
>>> (pci/rockchip,rk3399-pcie.yaml) already define the ep-gpios property. So if
>>
>> Any reason why this cannot be named like GPIO? Is there already a user
>> of this in Linux kernel? Commit msg says nothing about this, so that's
>> why I would expect name matching the signal.
>
> The RC-mode PCIe controller node of the rk3399 DTS already defines the ep-gpios
> property for RC side PERST# signal handling. So we simply reused the exact same
> name to be consistent between RC and EP. I personnally have no preferences. If
> there is an effort to rename such signal with some preferred pattern, I will
> follow. For the EP node, there was no PERST signal handling in the driver and
> no property defined for it, so any name is fine. "perst-gpios" would indeed be
> a better name, but again, given that the RC controller node has ep-gpios, we
> reused that. What is your recommendation here ?
Actually I don't know, perst and ep would work for me. If you do not
have code for this in the driver yet (nothing is shared between ep and
host), then maybe let's go with perst to match the actual name.
Anyway, you need maxItems. I sent a patch for the other binding:
https://lore.kernel.org/all/20240401100058.15749-1-krzysztof.kozlowski@linaro.org/
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3] dt-bindings: ata: ahci-da850: Convert to dtschema
From: Damien Le Moal @ 2024-04-02 7:25 UTC (permalink / raw)
To: Animesh Agarwal
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-ide,
devicetree, linux-kernel
In-Reply-To: <20240327064354.17384-1-animeshagarwal28@gmail.com>
On 3/27/24 15:43, Animesh Agarwal wrote:
> Convert the ahci-da850 bindings to DT schema.
>
> Signed-off-by: Animesh Agarwal <animeshagarwal28@gmail.com>
Applied to for-6.10. Thanks !
--
Damien Le Moal
Western Digital Research
^ 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