* [PATCH v10 0/4] PCI EP driver support MSI doorbell from host
@ 2022-09-13 21:09 Frank Li
2022-09-13 21:09 ` [PATCH v10 1/6] platform-msi: export symbol platform_msi_create_irq_domain() Frank Li
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
┌───────┐ ┌──────────┐
│ │ │ │
┌─────────────┐ │ │ │ PCI Host │
│ MSI │◄┐ │ │ │ │
│ Controller │ │ │ │ │ │
└─────────────┘ └─┼───────┼──────────┼─Bar0 │
│ PCI │ │ Bar1 │
│ Func │ │ Bar2 │
│ │ │ Bar3 │
│ │ │ Bar4 │
│ ├─────────►│ │
└───────┘ └──────────┘
Many PCI controllers provided Endpoint functions.
Generally PCI endpoint is hardware, which is not running a rich OS,
like linux.
But Linux also supports endpoint functions. PCI Host write BAR<n> space
like write to memory. The EP side can't know memory changed by the Host
driver.
PCI Spec has not defined a standard method to do that. Only define
MSI(x) to let EP notified RC status change.
The basic idea is to trigger an IRQ when PCI RC writes to a memory
address. That's what MSI controller provided. EP drivers just need to
request a platform MSI interrupt, struct MSI_msg *msg will pass down a
memory address and data. EP driver will map such memory address to
one of PCI BAR<n>. Host just writes such an address to trigger EP side
IRQ.
If system have gic-its, only need update PCI EP side driver. But i.MX
have not chip support gic-its yet. So we have to use MU to simulate a
MSI controller. Although only 4 MSI IRQs are simulated, it matched
vntb(pci-epf-vntb) network requirement.
After enable MSI, ping delay reduce < 1ms from ~8ms
IRQchip: imx mu worked as MSI controller:
let imx mu worked as MSI controllers. Although IP is not design
as MSI controller, we still can use it if limited IRQ number to 4.
pcie: endpoint: pci-epf-vntb: add endpoint MSI support
Based on ntb-next branch. https://github.com/jonmason/ntb/commits/ntb-next
Using MSI as door bell registers
mu-msi patches (1-4) and vntb patch(5-6) is totally independently.
These can be applied by irqchip and pci's maintainer seperatedly.
i.MX EP function driver is upstreaming by Richard Zhu.
Some dts change missed at this patches. below is reference dts change
--- a/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
@@ -160,5 +160,6 @@ pcieb_ep: pcie_ep@5f010000 {
num-ib-windows = <6>;
num-ob-windows = <6>;
status = "disabled";
+ MSI-parent = <&lsio_mu12>;
};
--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -172,6 +172,19 @@ lsio_mu6: mailbox@5d210000 {
status = "disabled";
};
+ lsio_mu12: mailbox@5d270000 {
+ compatible = "fsl,imx6sx-mu-MSI";
+ msi-controller;
+ interrupt-controller;
+ reg = <0x5d270000 0x10000>, /* A side */
+ <0x5d300000 0x10000>; /* B side */
+ reg-names = "a", "b";
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd IMX_SC_R_MU_12A>,
+ <&pd IMX_SC_R_MU_12B>;
+ power-domain-names = "a", "b";
+ };
+
Change Log
- Change from v9 to v10
fixed build error reported by kernel test robot <lkp@intel.com>
irqchips:
fixed accoring to Marc Zyngier's comments
Added new patch platform-msi: export symbol
platform_msi_create_irq_domain()
Using one lock for both reg and alloc msi irq
Using predefined macro to init cfg data
pcie: endpoint:
fixed according to Manivannan Sadhasivam's feedback
Added makeup patch before enable msi irq
PCI: endpoint: makeup pci-epf-vntb.c
- Change from v8 to v9
fix dt_bind_check error
- Change from v7 to v8
irqchip: using name process-a-side as resource bind name
pcie: endpoint:
- fix build error reported by kernel test robot <lkp@intel.com>
- rename epf_db_phy to epf_db_phys
- rework error message
- rework commit message
- change ntb to vtb at apply irq.
- kept name msi_virqbase because it is msi irq base number,
not base address.
- Change from v6 to v7
pcie: endpoint: add endpoint MSI support
Fine tuning commit message
Fixed issues, reviewed by Bjorn Helgaas
- Change from v5 to v6
Fixed build error found by kernel test robot
- Change from v4 to v5
Fixed dt-binding document
add msi-cell
add interrupt max number
update naming reg-names and power-domain-names.
Fixed irqchip-Add-IMX-MU-MSI-controller-driver.patch
rework commit message
remove some field in struct imx_mu_dcfg
error handle when link power domain failure.
add irq_domain_update_bus_token
- Change from v3 to v4
Fixed dt-binding document according to Krzysztof Kozlowski's feedback
Fixed irqchip-imx-mu-worked-as-msi-controller according to Marc Zyngier's
comments.
There are still two important points, which I am not sure.
1. clean irq_set_affinity after platform_msi_create_irq_domain.
Some function, like platform_msi_write_msg() is static.
so I have to set MSI_FLAG_USE_DEF_CHIP_OPS flags, which will
set irq_set_affinity to default one.
2. about comments
> + msi_data->msi_domain = platform_msi_create_irq_domain(
> + of_node_to_fwnode(msi_data->pdev->dev.of_node),
> + &imx_mu_msi_domain_info,
> + msi_data->parent);
"And you don't get an error due to the fact that you use the same
fwnode for both domains without overriding the domain bus token?"
I did not understand yet.
Fixed static check warning, reported by Dan Carpenter
pcie: endpoint: pci-epf-vntb: add endpoint MSI support
- Change from v2 to v3
Fixed dt-binding docment check failure
Fixed typo a cover letter.
Change according Bjorn's comments at patch
pcie: endpoint: pci-epf-vntb: add endpoint MSI support
- from V1 to V2
Fixed fsl,mu-msi.yaml's problem
Fixed irq-imx-mu-msi.c problem according Marc Zyngier's feeback
Added a new patch to allow pass down .pm by IRQCHIP_PLATFORM_DRIVER_END
--
2.35.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 1/6] platform-msi: export symbol platform_msi_create_irq_domain()
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
@ 2022-09-13 21:09 ` Frank Li
2022-09-13 21:09 ` [PATCH v10 2/6] irqchip: allow pass down .pm field at IRQCHIP_PLATFORM_DRIVER_END Frank Li
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
Make platform msi irqchip driver can be built as module
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/base/platform-msi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 296ea673d6615..12b044151298b 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -138,6 +138,7 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
return domain;
}
+EXPORT_SYMBOL_GPL(platform_msi_create_irq_domain);
static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
irq_write_msi_msg_t write_msi_msg)
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v10 2/6] irqchip: allow pass down .pm field at IRQCHIP_PLATFORM_DRIVER_END
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
2022-09-13 21:09 ` [PATCH v10 1/6] platform-msi: export symbol platform_msi_create_irq_domain() Frank Li
@ 2022-09-13 21:09 ` Frank Li
2022-09-13 21:09 ` [PATCH v10 3/6] irqchip: Add IMX MU MSI controller driver Frank Li
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
IRQCHIP_PLATFORM_DRIVER_* compilation define platform_driver
for irqchip. But can't set .pm field of platform_driver.
Added variadic macros to set .pm field or other field if need.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
include/linux/irqchip.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
index 3a091d0710ae1..d5e6024cb2a8c 100644
--- a/include/linux/irqchip.h
+++ b/include/linux/irqchip.h
@@ -44,7 +44,8 @@ static const struct of_device_id drv_name##_irqchip_match_table[] = {
#define IRQCHIP_MATCH(compat, fn) { .compatible = compat, \
.data = typecheck_irq_init_cb(fn), },
-#define IRQCHIP_PLATFORM_DRIVER_END(drv_name) \
+
+#define IRQCHIP_PLATFORM_DRIVER_END(drv_name, ...) \
{}, \
}; \
MODULE_DEVICE_TABLE(of, drv_name##_irqchip_match_table); \
@@ -56,6 +57,7 @@ static struct platform_driver drv_name##_driver = { \
.owner = THIS_MODULE, \
.of_match_table = drv_name##_irqchip_match_table, \
.suppress_bind_attrs = true, \
+ __VA_ARGS__ \
}, \
}; \
builtin_platform_driver(drv_name##_driver)
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v10 3/6] irqchip: Add IMX MU MSI controller driver
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
2022-09-13 21:09 ` [PATCH v10 1/6] platform-msi: export symbol platform_msi_create_irq_domain() Frank Li
2022-09-13 21:09 ` [PATCH v10 2/6] irqchip: allow pass down .pm field at IRQCHIP_PLATFORM_DRIVER_END Frank Li
@ 2022-09-13 21:09 ` Frank Li
2022-09-13 21:09 ` [PATCH v10 4/6] dt-bindings: irqchip: imx mu work as msi controller Frank Li
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
The MU block found in a number of Freescale/NXP SoCs supports generating
IRQs by writing data to a register.
This enables the MU block to be used as a MSI controller, by leveraging
the platform-MSI API.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/irqchip/Kconfig | 14 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-imx-mu-msi.c | 455 +++++++++++++++++++++++++++++++
3 files changed, 470 insertions(+)
create mode 100644 drivers/irqchip/irq-imx-mu-msi.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 5e4e50122777d..b9adc698ef0fc 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -470,6 +470,20 @@ config IMX_INTMUX
help
Support for the i.MX INTMUX interrupt multiplexer.
+config IMX_MU_MSI
+ tristate "i.MX MU used as MSI controller"
+ depends on OF && HAS_IOMEM
+ default m if ARCH_MXC
+ select IRQ_DOMAIN
+ select IRQ_DOMAIN_HIERARCHY
+ select GENERIC_MSI_IRQ_DOMAIN
+ help
+ Provide a driver for the MU block used as a CPU-to-CPU MSI
+ controller. This requires a specially crafted DT to make use
+ of this driver.
+
+ If unsure, say N
+
config LS1X_IRQ
bool "Loongson-1 Interrupt Controller"
depends on MACH_LOONGSON32
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 5d8e21d3dc6d8..870423746c783 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_RISCV_INTC) += irq-riscv-intc.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
+obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o
obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
new file mode 100644
index 0000000000000..4bb9456ba4820
--- /dev/null
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Freescale MU used as MSI controller
+ *
+ * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
+ * Copyright 2022 NXP
+ * Frank Li <Frank.Li@nxp.com>
+ * Peng Fan <peng.fan@nxp.com>
+ *
+ * Based on drivers/mailbox/imx-mailbox.c
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-iommu.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/spinlock.h>
+
+#define IMX_MU_CHANS 4
+
+enum imx_mu_xcr {
+ IMX_MU_GIER,
+ IMX_MU_GCR,
+ IMX_MU_TCR,
+ IMX_MU_RCR,
+ IMX_MU_xCR_MAX,
+};
+
+enum imx_mu_xsr {
+ IMX_MU_SR,
+ IMX_MU_GSR,
+ IMX_MU_TSR,
+ IMX_MU_RSR,
+ IMX_MU_xSR_MAX
+};
+
+enum imx_mu_type {
+ IMX_MU_V2 = BIT(1),
+};
+
+/* Receive Interrupt Enable */
+#define IMX_MU_xCR_RIEn(data, x) ((data->cfg->type) & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
+#define IMX_MU_xSR_RFn(data, x) ((data->cfg->type) & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
+
+struct imx_mu_dcfg {
+ enum imx_mu_type type;
+ u32 xTR; /* Transmit Register0 */
+ u32 xRR; /* Receive Register0 */
+ u32 xSR[IMX_MU_xSR_MAX]; /* Status Registers */
+ u32 xCR[IMX_MU_xCR_MAX]; /* Control Registers */
+};
+
+struct imx_mu_msi {
+ raw_spinlock_t lock;
+ struct irq_domain *msi_domain;
+ void __iomem *regs;
+ phys_addr_t msiir_addr;
+ const struct imx_mu_dcfg *cfg;
+ unsigned long used;
+ struct clk *clk;
+};
+
+static void imx_mu_write(struct imx_mu_msi *msi_data, u32 val, u32 offs)
+{
+ iowrite32(val, msi_data->regs + offs);
+}
+
+static u32 imx_mu_read(struct imx_mu_msi *msi_data, u32 offs)
+{
+ return ioread32(msi_data->regs + offs);
+}
+
+static u32 imx_mu_xcr_rmw(struct imx_mu_msi *msi_data, enum imx_mu_xcr type, u32 set, u32 clr)
+{
+ unsigned long flags;
+ u32 val;
+
+ raw_spin_lock_irqsave(&msi_data->lock, flags);
+ val = imx_mu_read(msi_data, msi_data->cfg->xCR[type]);
+ val &= ~clr;
+ val |= set;
+ imx_mu_write(msi_data, val, msi_data->cfg->xCR[type]);
+ raw_spin_unlock_irqrestore(&msi_data->lock, flags);
+
+ return val;
+}
+
+static void imx_mu_msi_parent_mask_irq(struct irq_data *data)
+{
+ struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
+
+ imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(msi_data, data->hwirq));
+}
+
+static void imx_mu_msi_parent_unmask_irq(struct irq_data *data)
+{
+ struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
+
+ imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, IMX_MU_xCR_RIEn(msi_data, data->hwirq), 0);
+}
+
+static void imx_mu_msi_parent_ack_irq(struct irq_data *data)
+{
+ struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
+
+ imx_mu_read(msi_data, msi_data->cfg->xRR + data->hwirq * 4);
+}
+
+static struct irq_chip imx_mu_msi_irq_chip = {
+ .name = "MU-MSI",
+ .irq_ack = irq_chip_ack_parent,
+};
+
+static struct msi_domain_ops imx_mu_msi_irq_ops = {
+};
+
+static struct msi_domain_info imx_mu_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+ .ops = &imx_mu_msi_irq_ops,
+ .chip = &imx_mu_msi_irq_chip,
+};
+
+static void imx_mu_msi_parent_compose_msg(struct irq_data *data,
+ struct msi_msg *msg)
+{
+ struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
+ u64 addr = msi_data->msiir_addr + 4 * data->hwirq;
+
+ msg->address_hi = upper_32_bits(addr);
+ msg->address_lo = lower_32_bits(addr);
+ msg->data = data->hwirq;
+}
+
+static int imx_mu_msi_parent_set_affinity(struct irq_data *irq_data,
+ const struct cpumask *mask, bool force)
+{
+ return -EINVAL;
+}
+
+static struct irq_chip imx_mu_msi_parent_chip = {
+ .name = "MU",
+ .irq_mask = imx_mu_msi_parent_mask_irq,
+ .irq_unmask = imx_mu_msi_parent_unmask_irq,
+ .irq_ack = imx_mu_msi_parent_ack_irq,
+ .irq_compose_msi_msg = imx_mu_msi_parent_compose_msg,
+ .irq_set_affinity = imx_mu_msi_parent_set_affinity,
+};
+
+static int imx_mu_msi_domain_irq_alloc(struct irq_domain *domain,
+ unsigned int virq,
+ unsigned int nr_irqs,
+ void *args)
+{
+ struct imx_mu_msi *msi_data = domain->host_data;
+ unsigned long flags;
+ int pos, err = 0;
+
+ WARN_ON(nr_irqs != 1);
+
+ raw_spin_lock_irqsave(&msi_data->lock, flags);
+ pos = find_first_zero_bit(&msi_data->used, IMX_MU_CHANS);
+ if (pos < IMX_MU_CHANS)
+ __set_bit(pos, &msi_data->used);
+ else
+ err = -ENOSPC;
+ raw_spin_unlock_irqrestore(&msi_data->lock, flags);
+
+ if (err)
+ return err;
+
+ irq_domain_set_info(domain, virq, pos,
+ &imx_mu_msi_parent_chip, msi_data,
+ handle_edge_irq, NULL, NULL);
+ return 0;
+}
+
+static void imx_mu_msi_domain_irq_free(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs)
+{
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+ struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(d);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&msi_data->lock, flags);
+ __clear_bit(d->hwirq, &msi_data->used);
+ raw_spin_unlock_irqrestore(&msi_data->lock, flags);
+}
+
+static const struct irq_domain_ops imx_mu_msi_domain_ops = {
+ .alloc = imx_mu_msi_domain_irq_alloc,
+ .free = imx_mu_msi_domain_irq_free,
+};
+
+static void imx_mu_msi_irq_handler(struct irq_desc *desc)
+{
+ struct imx_mu_msi *msi_data = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 status;
+ int i;
+
+ status = imx_mu_read(msi_data, msi_data->cfg->xSR[IMX_MU_RSR]);
+
+ chained_irq_enter(chip, desc);
+ for (i = 0; i < IMX_MU_CHANS; i++) {
+ if (status & IMX_MU_xSR_RFn(msi_data, i))
+ generic_handle_domain_irq(msi_data->msi_domain, i);
+ }
+ chained_irq_exit(chip, desc);
+}
+
+static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *dev)
+{
+ struct fwnode_handle *fwnodes = dev_fwnode(dev);
+ struct irq_domain *parent;
+
+ /* Initialize MSI domain parent */
+ parent = irq_domain_create_linear(fwnodes,
+ IMX_MU_CHANS,
+ &imx_mu_msi_domain_ops,
+ msi_data);
+ if (!parent) {
+ dev_err(dev, "failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
+
+ msi_data->msi_domain = platform_msi_create_irq_domain(fwnodes,
+ &imx_mu_msi_domain_info,
+ parent);
+
+ if (!msi_data->msi_domain) {
+ dev_err(dev, "failed to create MSI domain\n");
+ irq_domain_remove(parent);
+ return -ENOMEM;
+ }
+
+ irq_domain_set_pm_device(msi_data->msi_domain, dev);
+
+ return 0;
+}
+
+/* Register offset of different version MU IP */
+static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
+ .type = 0,
+ .xTR = 0x0,
+ .xRR = 0x10,
+ .xSR = {
+ [IMX_MU_SR] = 0x20,
+ [IMX_MU_GSR] = 0x20,
+ [IMX_MU_TSR] = 0x20,
+ [IMX_MU_RSR] = 0x20,
+ },
+ .xCR = {
+ [IMX_MU_GIER] = 0x24,
+ [IMX_MU_GCR] = 0x24,
+ [IMX_MU_TCR] = 0x24,
+ [IMX_MU_RCR] = 0x24,
+ },
+};
+
+static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
+ .type = 0,
+ .xTR = 0x20,
+ .xRR = 0x40,
+ .xSR = {
+ [IMX_MU_SR] = 0x60,
+ [IMX_MU_GSR] = 0x60,
+ [IMX_MU_TSR] = 0x60,
+ [IMX_MU_RSR] = 0x60,
+ },
+ .xCR = {
+ [IMX_MU_GIER] = 0x64,
+ [IMX_MU_GCR] = 0x64,
+ [IMX_MU_TCR] = 0x64,
+ [IMX_MU_RCR] = 0x64,
+ },
+};
+
+static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
+ .type = IMX_MU_V2,
+ .xTR = 0x200,
+ .xRR = 0x280,
+ .xSR = {
+ [IMX_MU_SR] = 0xC,
+ [IMX_MU_GSR] = 0x118,
+ [IMX_MU_GSR] = 0x124,
+ [IMX_MU_RSR] = 0x12C,
+ },
+ .xCR = {
+ [IMX_MU_GIER] = 0x110,
+ [IMX_MU_GCR] = 0x114,
+ [IMX_MU_TCR] = 0x120,
+ [IMX_MU_RCR] = 0x128
+ },
+};
+
+static int __init imx_mu_of_init(struct device_node *dn,
+ struct device_node *parent,
+ const struct imx_mu_dcfg *cfg)
+{
+ struct platform_device *pdev = of_find_device_by_node(dn);
+ struct device_link *pd_link_a;
+ struct device_link *pd_link_b;
+ struct imx_mu_msi *msi_data;
+ struct resource *res;
+ struct device *pd_a;
+ struct device *pd_b;
+ struct device *dev;
+ int ret;
+ int irq;
+
+ dev = &pdev->dev;
+
+ msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL);
+ if (!msi_data)
+ return -ENOMEM;
+
+ msi_data->cfg = cfg;
+
+ msi_data->regs = devm_platform_ioremap_resource_byname(pdev, "processor-a-side");
+ if (IS_ERR(msi_data->regs)) {
+ dev_err(&pdev->dev, "failed to initialize 'regs'\n");
+ return PTR_ERR(msi_data->regs);
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "processor-b-side");
+ if (!res)
+ return -EIO;
+
+ msi_data->msiir_addr = res->start + msi_data->cfg->xTR;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0)
+ return -ENODEV;
+
+ platform_set_drvdata(pdev, msi_data);
+
+ msi_data->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(msi_data->clk))
+ return PTR_ERR(msi_data->clk);
+
+ pd_a = dev_pm_domain_attach_by_name(dev, "processor-a-side");
+ if (IS_ERR(pd_a))
+ return PTR_ERR(pd_a);
+
+ pd_b = dev_pm_domain_attach_by_name(dev, "processor-b-side");
+ if (IS_ERR(pd_b))
+ return PTR_ERR(pd_b);
+
+ pd_link_a = device_link_add(dev, pd_a,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+
+ if (!pd_link_a) {
+ dev_err(dev, "Failed to add device_link to mu a.\n");
+ goto err_pd_a;
+ }
+
+ pd_link_b = device_link_add(dev, pd_b,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+
+
+ if (!pd_link_b) {
+ dev_err(dev, "Failed to add device_link to mu a.\n");
+ goto err_pd_b;
+ }
+
+ ret = imx_mu_msi_domains_init(msi_data, dev);
+ if (ret)
+ goto err_dm_init;
+
+ pm_runtime_enable(dev);
+
+ irq_set_chained_handler_and_data(irq,
+ imx_mu_msi_irq_handler,
+ msi_data);
+
+ return 0;
+
+err_dm_init:
+ device_link_remove(dev, pd_b);
+err_pd_b:
+ device_link_remove(dev, pd_a);
+err_pd_a:
+ return -EINVAL;
+}
+
+static int __maybe_unused imx_mu_runtime_suspend(struct device *dev)
+{
+ struct imx_mu_msi *priv = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
+static int __maybe_unused imx_mu_runtime_resume(struct device *dev)
+{
+ struct imx_mu_msi *priv = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ dev_err(dev, "failed to enable clock\n");
+
+ return ret;
+}
+
+static const struct dev_pm_ops imx_mu_pm_ops = {
+ SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,
+ imx_mu_runtime_resume, NULL)
+};
+
+static int __init imx_mu_imx7ulp_of_init(struct device_node *dn,
+ struct device_node *parent)
+{
+ return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp);
+}
+
+static int __init imx_mu_imx6sx_of_init(struct device_node *dn,
+ struct device_node *parent)
+{
+ return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx);
+}
+
+static int __init imx_mu_imx8ulp_of_init(struct device_node *dn,
+ struct device_node *parent)
+{
+ return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp);
+}
+
+IRQCHIP_PLATFORM_DRIVER_BEGIN(imx_mu_msi)
+IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
+IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init)
+IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init)
+IRQCHIP_PLATFORM_DRIVER_END(imx_mu_msi, .pm = &imx_mu_pm_ops)
+
+
+MODULE_AUTHOR("Frank Li <Frank.Li@nxp.com>");
+MODULE_DESCRIPTION("Freescale MU MSI controller driver");
+MODULE_LICENSE("GPL");
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v10 4/6] dt-bindings: irqchip: imx mu work as msi controller
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
` (2 preceding siblings ...)
2022-09-13 21:09 ` [PATCH v10 3/6] irqchip: Add IMX MU MSI controller driver Frank Li
@ 2022-09-13 21:09 ` Frank Li
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
2022-09-13 21:09 ` [PATCH v10 6/6] PCI: endpoint: Add vNTB MSI support Frank Li
5 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
I.MX mu support generate irq by write a register. Provide msi controller
support so other driver such as PCI EP can use it by standard msi
interface as doorbell.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
.../interrupt-controller/fsl,mu-msi.yaml | 99 +++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,mu-msi.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,mu-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,mu-msi.yaml
new file mode 100644
index 0000000000000..799ae5c3e32ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,mu-msi.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/fsl,mu-msi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale/NXP i.MX Messaging Unit (MU) work as msi controller
+
+maintainers:
+ - Frank Li <Frank.Li@nxp.com>
+
+description: |
+ The Messaging Unit module enables two processors within the SoC to
+ communicate and coordinate by passing messages (e.g. data, status
+ and control) through the MU interface. The MU also provides the ability
+ for one processor (A side) to signal the other processor (B side) using
+ interrupts.
+
+ Because the MU manages the messaging between processors, the MU uses
+ different clocks (from each side of the different peripheral buses).
+ Therefore, the MU must synchronize the accesses from one side to the
+ other. The MU accomplishes synchronization using two sets of matching
+ registers (Processor A-side, Processor B-side).
+
+ MU can work as msi interrupt controller to do doorbell
+
+allOf:
+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - fsl,imx6sx-mu-msi
+ - fsl,imx7ulp-mu-msi
+ - fsl,imx8ulp-mu-msi
+ - fsl,imx8ulp-mu-msi-s4
+
+ reg:
+ items:
+ - description: a side register base address
+ - description: b side register base address
+
+ reg-names:
+ items:
+ - const: processor-a-side
+ - const: processor-b-side
+
+ interrupts:
+ description: a side interrupt number.
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ power-domains:
+ items:
+ - description: a side power domain
+ - description: b side power domain
+
+ power-domain-names:
+ items:
+ - const: processor-a-side
+ - const: processor-b-side
+
+ interrupt-controller: true
+
+ msi-controller: true
+
+ "#msi-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-controller
+ - msi-controller
+ - "#msi-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/firmware/imx/rsrc.h>
+
+ msi-controller@5d270000 {
+ compatible = "fsl,imx6sx-mu-msi";
+ msi-controller;
+ #msi-cells = <0>;
+ interrupt-controller;
+ reg = <0x5d270000 0x10000>, /* A side */
+ <0x5d300000 0x10000>; /* B side */
+ reg-names = "processor-a-side", "processor-b-side";
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd IMX_SC_R_MU_12A>,
+ <&pd IMX_SC_R_MU_12B>;
+ power-domain-names = "processor-a-side", "processor-b-side";
+ };
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
` (3 preceding siblings ...)
2022-09-13 21:09 ` [PATCH v10 4/6] dt-bindings: irqchip: imx mu work as msi controller Frank Li
@ 2022-09-13 21:09 ` Frank Li
2022-09-13 22:19 ` Bjorn Helgaas
` (2 more replies)
2022-09-13 21:09 ` [PATCH v10 6/6] PCI: endpoint: Add vNTB MSI support Frank Li
5 siblings, 3 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
Remove unused field: epf_db_phy.
Remove __iomem before epf_db.
Remove dupicate check if (readl(ntb->epf_db + i * 4)).
Using readl_relaxed instead of readl.
Using marco ENTRY_SIZE instead of number 4 at all place.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 1466dd1904175..17f030befde52 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -67,6 +67,8 @@ static struct workqueue_struct *kpcintb_workqueue;
#define MAX_DB_COUNT 32
#define MAX_MW 4
+#define ENTRY_SIZE 4
+
enum epf_ntb_bar {
BAR_CONFIG,
BAR_DB,
@@ -136,8 +138,7 @@ struct epf_ntb {
struct epf_ntb_ctrl *reg;
- phys_addr_t epf_db_phy;
- void __iomem *epf_db;
+ void *epf_db;
phys_addr_t vpci_mw_phy[MAX_MW];
void __iomem *vpci_mw_addr[MAX_MW];
@@ -254,12 +255,9 @@ static void epf_ntb_cmd_handler(struct work_struct *work)
ntb = container_of(work, struct epf_ntb, cmd_handler.work);
for (i = 1; i < ntb->db_count; i++) {
- if (readl(ntb->epf_db + i * 4)) {
- if (readl(ntb->epf_db + i * 4))
- ntb->db |= 1 << (i - 1);
-
+ if (readl_relaxed(ntb->epf_db + i * ENTRY_SIZE)) {
ntb_db_event(&ntb->ntb, i);
- writel(0, ntb->epf_db + i * 4);
+ writel(0, ntb->epf_db + i * ENTRY_SIZE);
}
}
@@ -424,7 +422,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
spad_count = ntb->spad_count;
ctrl_size = sizeof(struct epf_ntb_ctrl);
- spad_size = 2 * spad_count * 4;
+ spad_size = 2 * spad_count * ENTRY_SIZE;
if (!align) {
ctrl_size = roundup_pow_of_two(ctrl_size);
@@ -454,7 +452,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
ctrl->num_mws = ntb->num_mws;
ntb->spad_size = spad_size;
- ctrl->db_entry_size = 4;
+ ctrl->db_entry_size = ENTRY_SIZE;
for (i = 0; i < ntb->db_count; i++) {
ntb->reg->db_data[i] = 1 + i;
@@ -516,13 +514,15 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb)
static int epf_ntb_db_bar_init(struct epf_ntb *ntb)
{
const struct pci_epc_features *epc_features;
- u32 align;
struct device *dev = &ntb->epf->dev;
- int ret;
struct pci_epf_bar *epf_bar;
- void __iomem *mw_addr;
enum pci_barno barno;
- size_t size = 4 * ntb->db_count;
+ void *mw_addr;
+ size_t size;
+ u32 align;
+ int ret;
+
+ size = ENTRY_SIZE * ntb->db_count;
epc_features = pci_epc_get_features(ntb->epf->epc,
ntb->epf->func_no,
@@ -1084,11 +1084,11 @@ static int vntb_epf_link_enable(struct ntb_dev *ntb,
static u32 vntb_epf_spad_read(struct ntb_dev *ndev, int idx)
{
struct epf_ntb *ntb = ntb_ndev(ndev);
- int off = ntb->reg->spad_offset, ct = ntb->reg->spad_count * 4;
+ int off = ntb->reg->spad_offset, ct = ntb->reg->spad_count * ENTRY_SIZE;
u32 val;
void __iomem *base = ntb->reg;
- val = readl(base + off + ct + idx * 4);
+ val = readl(base + off + ct + idx * ENTRY_SIZE);
return val;
}
@@ -1096,10 +1096,10 @@ static int vntb_epf_spad_write(struct ntb_dev *ndev, int idx, u32 val)
{
struct epf_ntb *ntb = ntb_ndev(ndev);
struct epf_ntb_ctrl *ctrl = ntb->reg;
- int off = ctrl->spad_offset, ct = ctrl->spad_count * 4;
+ int off = ctrl->spad_offset, ct = ctrl->spad_count * ENTRY_SIZE;
void __iomem *base = ntb->reg;
- writel(val, base + off + ct + idx * 4);
+ writel(val, base + off + ct + idx * ENTRY_SIZE);
return 0;
}
@@ -1111,7 +1111,7 @@ static u32 vntb_epf_peer_spad_read(struct ntb_dev *ndev, int pidx, int idx)
void __iomem *base = ntb->reg;
u32 val;
- val = readl(base + off + idx * 4);
+ val = readl(base + off + idx * ENTRY_SIZE);
return val;
}
@@ -1122,7 +1122,7 @@ static int vntb_epf_peer_spad_write(struct ntb_dev *ndev, int pidx, int idx, u32
int off = ctrl->spad_offset;
void __iomem *base = ntb->reg;
- writel(val, base + off + idx * 4);
+ writel(val, base + off + idx * ENTRY_SIZE);
return 0;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v10 6/6] PCI: endpoint: Add vNTB MSI support
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
` (4 preceding siblings ...)
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
@ 2022-09-13 21:09 ` Frank Li
5 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2022-09-13 21:09 UTC (permalink / raw)
To: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas
Cc: linux-kernel, devicetree, linux-arm-kernel, linux-pci, peng.fan,
aisheng.dong, jdmason, kernel, festevam, linux-imx, kishon,
lorenzo.pieralisi, ntb, lznuaa, imx, manivannan.sadhasivam
┌───────┐ ┌──────────┐
│ │ │ │
┌─────────────┐ │ PCI │ │ PCI Host │
│ MSI │◄┐ │ EP │ │ │
│ Controller │ │ │ │ 3.MSI Write │ │
└────────┬────┘ └─┼───────┼───────────────────┤ │
▲ │ │ │ ├─BAR_n │
│ └────────┼───────┼──────────────────►│ │
│ │ │ 2.Call Back │ │
│ │ │ write_msi_msg() │ │
│ │ │ │ │
│ └───┬───┘ └──────────┘
│ │
└───────────────────┘
1.platform_msi_domain_alloc_irqs()
There is no defined way of raising IRQs by PCI host to the PCI endpoint.
Only define MSI/MSI-X to let EP notified RC status change.
The memory assigned for BAR region by the PCI host is mapped to the
message address of platform msi interrupt controller in PCI Endpoint.
Such that, whenever the PCI host writes to the BAR region, it will
trigger an IRQ in the Endpoint.
Basic working follow as
1. EP function driver call platform_msi_domain_alloc_irqs() alloc a
MSI irq from MSI controller with call back function write_msi_msg();
2. write_msg_msg will config BAR and map to address defined in msi_msg;
3. Host side trigger an IRQ in Endpoint by write to BAR region.
Add MSI support for pci-epf-vntb. Query if system has an MSI controller.
Set up doorbell address according to struct msi_msg.
So PCI RC can write this doorbell address to trigger EP side's IRQ.
If no MSI controller exists, fall back to software polling.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 151 +++++++++++++++---
1 file changed, 128 insertions(+), 23 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 17f030befde52..90271c0394e83 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -44,6 +44,7 @@
#include <linux/pci-epc.h>
#include <linux/pci-epf.h>
#include <linux/ntb.h>
+#include <linux/msi.h>
static struct workqueue_struct *kpcintb_workqueue;
@@ -138,12 +139,15 @@ struct epf_ntb {
struct epf_ntb_ctrl *reg;
+ phys_addr_t epf_db_phys;
void *epf_db;
phys_addr_t vpci_mw_phy[MAX_MW];
void __iomem *vpci_mw_addr[MAX_MW];
struct delayed_work cmd_handler;
+
+ int msi_virqbase;
};
#define to_epf_ntb(epf_group) container_of((epf_group), struct epf_ntb, group)
@@ -254,10 +258,13 @@ static void epf_ntb_cmd_handler(struct work_struct *work)
ntb = container_of(work, struct epf_ntb, cmd_handler.work);
- for (i = 1; i < ntb->db_count; i++) {
- if (readl_relaxed(ntb->epf_db + i * ENTRY_SIZE)) {
- ntb_db_event(&ntb->ntb, i);
- writel(0, ntb->epf_db + i * ENTRY_SIZE);
+ if (!ntb->epf_db_phys) {
+ for (i = 1; i < ntb->db_count; i++) {
+ if (readl_relaxed(ntb->epf_db + i * ENTRY_SIZE)) {
+ ntb->db |= 1 << (i - 1);
+ ntb_db_event(&ntb->ntb, i);
+ writel(0, ntb->epf_db + i * ENTRY_SIZE);
+ }
}
}
@@ -456,7 +463,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
for (i = 0; i < ntb->db_count; i++) {
ntb->reg->db_data[i] = 1 + i;
- ntb->reg->db_offset[i] = 0;
+ ntb->reg->db_offset[i] = ENTRY_SIZE * i;
}
return 0;
@@ -507,6 +514,28 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb)
return 0;
}
+static int epf_ntb_db_size(struct epf_ntb *ntb)
+{
+ const struct pci_epc_features *epc_features;
+ size_t size = ENTRY_SIZE * ntb->db_count;
+ u32 align;
+
+ epc_features = pci_epc_get_features(ntb->epf->epc,
+ ntb->epf->func_no,
+ ntb->epf->vfunc_no);
+ align = epc_features->align;
+
+ if (size < 128)
+ size = 128;
+
+ if (align)
+ size = ALIGN(size, align);
+ else
+ size = roundup_pow_of_two(size);
+
+ return size;
+}
+
/**
* epf_ntb_db_bar_init() - Configure Doorbell window BARs
* @ntb: NTB device that facilitates communication between HOST and vHOST
@@ -522,33 +551,30 @@ static int epf_ntb_db_bar_init(struct epf_ntb *ntb)
u32 align;
int ret;
- size = ENTRY_SIZE * ntb->db_count;
-
epc_features = pci_epc_get_features(ntb->epf->epc,
ntb->epf->func_no,
ntb->epf->vfunc_no);
align = epc_features->align;
-
- if (size < 128)
- size = 128;
-
- if (align)
- size = ALIGN(size, align);
- else
- size = roundup_pow_of_two(size);
+ size = epf_ntb_db_size(ntb);
barno = ntb->epf_ntb_bar[BAR_DB];
+ epf_bar = &ntb->epf->bar[barno];
- mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0);
- if (!mw_addr) {
- dev_err(dev, "Failed to allocate OB address\n");
- return -ENOMEM;
+ if (ntb->epf_db_phys) {
+ mw_addr = NULL;
+ epf_bar->phys_addr = ntb->epf_db_phys;
+ epf_bar->barno = barno;
+ epf_bar->size = size;
+ } else {
+ mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0);
+ if (!mw_addr) {
+ dev_err(dev, "Failed to allocate doorbell address\n");
+ return -ENOMEM;
+ }
}
ntb->epf_db = mw_addr;
- epf_bar = &ntb->epf->bar[barno];
-
ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar);
if (ret) {
dev_err(dev, "Doorbell BAR set failed\n");
@@ -704,6 +730,84 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
return 0;
}
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+static void epf_ntb_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+ struct epf_ntb *ntb = dev_get_drvdata(desc->dev);
+ struct epf_ntb_ctrl *reg = ntb->reg;
+ int size = epf_ntb_db_size(ntb);
+ u64 addr;
+
+ addr = msg->address_hi;
+ addr <<= 32;
+ addr |= msg->address_lo;
+
+ reg->db_data[desc->msi_index] = msg->data;
+
+ if (!desc->msi_index)
+ ntb->epf_db_phys = round_down(addr, size);
+
+ reg->db_offset[desc->msi_index] = addr - ntb->epf_db_phys;
+}
+#endif
+
+static irqreturn_t epf_ntb_interrupt_handler(int irq, void *data)
+{
+ struct epf_ntb *ntb = data;
+ int index;
+
+ index = irq - ntb->msi_virqbase;
+ ntb->db |= 1 << (index - 1);
+ ntb_db_event(&ntb->ntb, index);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+static void epf_ntb_epc_msi_init(struct epf_ntb *ntb)
+{
+ struct device *dev = &ntb->epf->dev;
+ struct irq_domain *domain;
+ int virq;
+ int ret;
+ int i;
+
+ domain = dev_get_msi_domain(ntb->epf->epc->dev.parent);
+ if (!domain)
+ return;
+
+ dev_set_msi_domain(dev, domain);
+
+ if (platform_msi_domain_alloc_irqs(&ntb->epf->dev,
+ ntb->db_count,
+ epf_ntb_write_msi_msg)) {
+ dev_err(dev, "Can't allocate MSI, falling back to polling mode\n");
+ return;
+ }
+ dev_info(dev, "Using MSI as doorbell\n");
+
+ for (i = 0; i < ntb->db_count; i++) {
+ virq = msi_get_virq(dev, i);
+ ret = devm_request_irq(dev, virq,
+ epf_ntb_interrupt_handler, 0,
+ "pci_epf_vntb", ntb);
+
+ if (ret) {
+ dev_err(dev, "Failed to request doorbell IRQ! Falling back to polling mode");
+ ntb->epf_db_phys = 0;
+ break;
+ }
+
+ if (!i)
+ ntb->msi_virqbase = virq; /* msi start virq number */
+ }
+}
+#else
+static void epf_ntb_epc_msi_init(struct epf_ntb *ntb)
+{
+ return;
+}
+#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
/**
* epf_ntb_epc_init() - Initialize NTB interface
* @ntb: NTB device that facilitates communication between HOST and vHOST2
@@ -1299,14 +1403,15 @@ static int epf_ntb_bind(struct pci_epf *epf)
goto err_bar_alloc;
}
+ epf_set_drvdata(epf, ntb);
+ epf_ntb_epc_msi_init(ntb);
+
ret = epf_ntb_epc_init(ntb);
if (ret) {
dev_err(dev, "Failed to initialize EPC\n");
goto err_bar_alloc;
}
- epf_set_drvdata(epf, ntb);
-
pci_space[0] = (ntb->vntb_pid << 16) | ntb->vntb_vid;
pci_vntb_table[0].vendor = ntb->vntb_vid;
pci_vntb_table[0].device = ntb->vntb_pid;
--
2.35.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
@ 2022-09-13 22:19 ` Bjorn Helgaas
2022-09-14 15:25 ` kernel test robot
2022-09-18 12:53 ` kernel test robot
2 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2022-09-13 22:19 UTC (permalink / raw)
To: Frank Li
Cc: maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo, s.hauer,
kw, bhelgaas, linux-kernel, devicetree, linux-arm-kernel,
linux-pci, peng.fan, aisheng.dong, jdmason, kernel, festevam,
linux-imx, kishon, lorenzo.pieralisi, ntb, lznuaa, imx,
manivannan.sadhasivam
In subject, capitalize and change "makeup" to "Clean up":
PCI: endpoint: pci-epf-vntb: Clean up
On Tue, Sep 13, 2022 at 04:09:56PM -0500, Frank Li wrote:
> Remove unused field: epf_db_phy.
> Remove __iomem before epf_db.
> Remove dupicate check if (readl(ntb->epf_db + i * 4)).
> Using readl_relaxed instead of readl.
> Using marco ENTRY_SIZE instead of number 4 at all place.
Add "()" after function names.
s/marco/macro/
It would be nice if "ENTRY_SIZE" had a hint about what kind of entry
we're talking about.
Since this is a collection of random cleanups, I noticed a typo in
epf_ntb_configure_interrupt() kernel-doc: s/capaiblity/capability/
The struct epf_ntb_ctrl definition is also whitespace-damaged. The
members of struct epf_ntb_ctrl and struct epf_ntb should follow the
same indentation style. Some members of struct epf_ntb_ctrl are
indented with a tab, others with space. Either make them all tabs and
indent struct epf_ntb similarly, or indent the struct epf_ntb_ctrl
members with a single space.
The comments in the file have a whole collection of ways to spell
vhost: Virtual Host, VHOST, VHost, vHOST, vhost. Make them all the
same, please. You can use "Virtual Host (VHOST)" or whatever the
first time if you want to use the short version later.
Same for host/HOST/etc. I don't want to read things like this:
@ntb: NTB device that facilitates communication between HOST and vHOST2
Wrapper to initialize a particular EPC interface and start the
workqueue to check for commands from host.
and wonder whether "host" is supposed to be the same as "HOST". Also,
why does that say "vHOST*2*"?
There are several instances of "HOST1" and "HOST2" (and "vHOST2").
Should those appear somewhere in the diagram at the top of the file?
The diagram starts with "/**" which means it's kernel-doc, but the
diagram is not kernel-doc. Please run this:
scripts/kernel-doc -v -none drivers/pci/endpoint/functions/pci-epf-vntb.c
and fix all the warnings.
Bjorn
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
2022-09-13 22:19 ` Bjorn Helgaas
@ 2022-09-14 15:25 ` kernel test robot
2022-09-18 12:53 ` kernel test robot
2 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2022-09-14 15:25 UTC (permalink / raw)
To: Frank Li, maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo,
s.hauer, kw, bhelgaas
Cc: kbuild-all, linux-kernel, devicetree, linux-arm-kernel,
linux-pci, peng.fan, aisheng.dong, jdmason, kernel, festevam,
linux-imx, kishon, lorenzo.pieralisi, ntb, lznuaa, imx,
manivannan.sadhasivam
Hi Frank,
I love your patch! Perhaps something to improve:
[auto build test WARNING on jonmason-ntb/ntb-next]
[also build test WARNING on driver-core/driver-core-testing linus/master v6.0-rc5 next-20220914]
[cannot apply to tip/irq/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Frank-Li/platform-msi-export-symbol-platform_msi_create_irq_domain/20220914-060955
base: https://github.com/jonmason/ntb ntb-next
config: ia64-randconfig-s051-20220914 (https://download.01.org/0day-ci/archive/20220914/202209142334.YTRtjuFD-lkp@intel.com/config)
compiler: ia64-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/c0b811e4bf3a50a612ed143d284880e09790eff5
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Frank-Li/platform-msi-export-symbol-platform_msi_create_irq_domain/20220914-060955
git checkout c0b811e4bf3a50a612ed143d284880e09790eff5
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=ia64 SHELL=/bin/bash drivers/pci/endpoint/functions/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const volatile [noderef] __iomem *addr @@ got void * @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: expected void const volatile [noderef] __iomem *addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: got void *
>> drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile [noderef] __iomem *addr @@ got void * @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: expected void volatile [noderef] __iomem *addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: got void *
>> drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *virt_addr @@ got void *[assigned] mw_addr @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: expected void [noderef] __iomem *virt_addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: got void *[assigned] mw_addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c: note: in included file (through arch/ia64/include/asm/io.h, include/linux/io.h):
include/asm-generic/io.h:335:15: sparse: sparse: cast to restricted __le32
vim +258 drivers/pci/endpoint/functions/pci-epf-vntb.c
236
237 /**
238 * epf_ntb_cmd_handler() - Handle commands provided by the NTB Host
239 * @work: work_struct for the epf_ntb_epc
240 *
241 * Workqueue function that gets invoked for the two epf_ntb_epc
242 * periodically (once every 5ms) to see if it has received any commands
243 * from NTB host. The host can send commands to configure doorbell or
244 * configure memory window or to update link status.
245 */
246 static void epf_ntb_cmd_handler(struct work_struct *work)
247 {
248 struct epf_ntb_ctrl *ctrl;
249 u32 command, argument;
250 struct epf_ntb *ntb;
251 struct device *dev;
252 int ret;
253 int i;
254
255 ntb = container_of(work, struct epf_ntb, cmd_handler.work);
256
257 for (i = 1; i < ntb->db_count; i++) {
> 258 if (readl_relaxed(ntb->epf_db + i * ENTRY_SIZE)) {
259 ntb_db_event(&ntb->ntb, i);
> 260 writel(0, ntb->epf_db + i * ENTRY_SIZE);
261 }
262 }
263
264 ctrl = ntb->reg;
265 command = ctrl->command;
266 if (!command)
267 goto reset_handler;
268 argument = ctrl->argument;
269
270 ctrl->command = 0;
271 ctrl->argument = 0;
272
273 ctrl = ntb->reg;
274 dev = &ntb->epf->dev;
275
276 switch (command) {
277 case COMMAND_CONFIGURE_DOORBELL:
278 ctrl->command_status = COMMAND_STATUS_OK;
279 break;
280 case COMMAND_TEARDOWN_DOORBELL:
281 ctrl->command_status = COMMAND_STATUS_OK;
282 break;
283 case COMMAND_CONFIGURE_MW:
284 ret = epf_ntb_configure_mw(ntb, argument);
285 if (ret < 0)
286 ctrl->command_status = COMMAND_STATUS_ERROR;
287 else
288 ctrl->command_status = COMMAND_STATUS_OK;
289 break;
290 case COMMAND_TEARDOWN_MW:
291 epf_ntb_teardown_mw(ntb, argument);
292 ctrl->command_status = COMMAND_STATUS_OK;
293 break;
294 case COMMAND_LINK_UP:
295 ntb->linkup = true;
296 ret = epf_ntb_link_up(ntb, true);
297 if (ret < 0)
298 ctrl->command_status = COMMAND_STATUS_ERROR;
299 else
300 ctrl->command_status = COMMAND_STATUS_OK;
301 goto reset_handler;
302 case COMMAND_LINK_DOWN:
303 ntb->linkup = false;
304 ret = epf_ntb_link_up(ntb, false);
305 if (ret < 0)
306 ctrl->command_status = COMMAND_STATUS_ERROR;
307 else
308 ctrl->command_status = COMMAND_STATUS_OK;
309 break;
310 default:
311 dev_err(dev, "UNKNOWN command: %d\n", command);
312 break;
313 }
314
315 reset_handler:
316 queue_delayed_work(kpcintb_workqueue, &ntb->cmd_handler,
317 msecs_to_jiffies(5));
318 }
319
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
2022-09-13 22:19 ` Bjorn Helgaas
2022-09-14 15:25 ` kernel test robot
@ 2022-09-18 12:53 ` kernel test robot
2 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2022-09-18 12:53 UTC (permalink / raw)
To: Frank Li, maz, tglx, robh+dt, krzysztof.kozlowski+dt, shawnguo,
s.hauer, kw, bhelgaas
Cc: kbuild-all, linux-kernel, devicetree, linux-arm-kernel,
linux-pci, peng.fan, aisheng.dong, jdmason, kernel, festevam,
linux-imx, kishon, lorenzo.pieralisi, ntb, lznuaa, imx,
manivannan.sadhasivam
Hi Frank,
I love your patch! Perhaps something to improve:
[auto build test WARNING on jonmason-ntb/ntb-next]
[also build test WARNING on driver-core/driver-core-testing linus/master v6.0-rc5 next-20220916]
[cannot apply to tip/irq/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Frank-Li/platform-msi-export-symbol-platform_msi_create_irq_domain/20220914-060955
base: https://github.com/jonmason/ntb ntb-next
config: mips-randconfig-s042-20220918 (https://download.01.org/0day-ci/archive/20220918/202209182035.SS1p5KkG-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/c0b811e4bf3a50a612ed143d284880e09790eff5
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Frank-Li/platform-msi-export-symbol-platform_msi_create_irq_domain/20220914-060955
git checkout c0b811e4bf3a50a612ed143d284880e09790eff5
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=mips SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const volatile [noderef] __iomem *mem @@ got void * @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: expected void const volatile [noderef] __iomem *mem
drivers/pci/endpoint/functions/pci-epf-vntb.c:258:47: sparse: got void *
>> drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile [noderef] __iomem *mem @@ got void * @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: expected void volatile [noderef] __iomem *mem
drivers/pci/endpoint/functions/pci-epf-vntb.c:260:47: sparse: got void *
drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *virt_addr @@ got void *[assigned] mw_addr @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: expected void [noderef] __iomem *virt_addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:560:66: sparse: got void *[assigned] mw_addr
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1106:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1117:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1128:33: sparse: got struct epf_ntb_ctrl *reg
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void [noderef] __iomem *base @@ got struct epf_ntb_ctrl *reg @@
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: expected void [noderef] __iomem *base
drivers/pci/endpoint/functions/pci-epf-vntb.c:1140:33: sparse: got struct epf_ntb_ctrl *reg
vim +258 drivers/pci/endpoint/functions/pci-epf-vntb.c
236
237 /**
238 * epf_ntb_cmd_handler() - Handle commands provided by the NTB Host
239 * @work: work_struct for the epf_ntb_epc
240 *
241 * Workqueue function that gets invoked for the two epf_ntb_epc
242 * periodically (once every 5ms) to see if it has received any commands
243 * from NTB host. The host can send commands to configure doorbell or
244 * configure memory window or to update link status.
245 */
246 static void epf_ntb_cmd_handler(struct work_struct *work)
247 {
248 struct epf_ntb_ctrl *ctrl;
249 u32 command, argument;
250 struct epf_ntb *ntb;
251 struct device *dev;
252 int ret;
253 int i;
254
255 ntb = container_of(work, struct epf_ntb, cmd_handler.work);
256
257 for (i = 1; i < ntb->db_count; i++) {
> 258 if (readl_relaxed(ntb->epf_db + i * ENTRY_SIZE)) {
259 ntb_db_event(&ntb->ntb, i);
> 260 writel(0, ntb->epf_db + i * ENTRY_SIZE);
261 }
262 }
263
264 ctrl = ntb->reg;
265 command = ctrl->command;
266 if (!command)
267 goto reset_handler;
268 argument = ctrl->argument;
269
270 ctrl->command = 0;
271 ctrl->argument = 0;
272
273 ctrl = ntb->reg;
274 dev = &ntb->epf->dev;
275
276 switch (command) {
277 case COMMAND_CONFIGURE_DOORBELL:
278 ctrl->command_status = COMMAND_STATUS_OK;
279 break;
280 case COMMAND_TEARDOWN_DOORBELL:
281 ctrl->command_status = COMMAND_STATUS_OK;
282 break;
283 case COMMAND_CONFIGURE_MW:
284 ret = epf_ntb_configure_mw(ntb, argument);
285 if (ret < 0)
286 ctrl->command_status = COMMAND_STATUS_ERROR;
287 else
288 ctrl->command_status = COMMAND_STATUS_OK;
289 break;
290 case COMMAND_TEARDOWN_MW:
291 epf_ntb_teardown_mw(ntb, argument);
292 ctrl->command_status = COMMAND_STATUS_OK;
293 break;
294 case COMMAND_LINK_UP:
295 ntb->linkup = true;
296 ret = epf_ntb_link_up(ntb, true);
297 if (ret < 0)
298 ctrl->command_status = COMMAND_STATUS_ERROR;
299 else
300 ctrl->command_status = COMMAND_STATUS_OK;
301 goto reset_handler;
302 case COMMAND_LINK_DOWN:
303 ntb->linkup = false;
304 ret = epf_ntb_link_up(ntb, false);
305 if (ret < 0)
306 ctrl->command_status = COMMAND_STATUS_ERROR;
307 else
308 ctrl->command_status = COMMAND_STATUS_OK;
309 break;
310 default:
311 dev_err(dev, "UNKNOWN command: %d\n", command);
312 break;
313 }
314
315 reset_handler:
316 queue_delayed_work(kpcintb_workqueue, &ntb->cmd_handler,
317 msecs_to_jiffies(5));
318 }
319
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-09-18 12:53 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-13 21:09 [PATCH v10 0/4] PCI EP driver support MSI doorbell from host Frank Li
2022-09-13 21:09 ` [PATCH v10 1/6] platform-msi: export symbol platform_msi_create_irq_domain() Frank Li
2022-09-13 21:09 ` [PATCH v10 2/6] irqchip: allow pass down .pm field at IRQCHIP_PLATFORM_DRIVER_END Frank Li
2022-09-13 21:09 ` [PATCH v10 3/6] irqchip: Add IMX MU MSI controller driver Frank Li
2022-09-13 21:09 ` [PATCH v10 4/6] dt-bindings: irqchip: imx mu work as msi controller Frank Li
2022-09-13 21:09 ` [PATCH v10 5/6] PCI: endpoint: makeup pci-epf-vntb.c Frank Li
2022-09-13 22:19 ` Bjorn Helgaas
2022-09-14 15:25 ` kernel test robot
2022-09-18 12:53 ` kernel test robot
2022-09-13 21:09 ` [PATCH v10 6/6] PCI: endpoint: Add vNTB MSI support Frank Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).