From: Nipun Gupta <nipun.gupta@amd.com> To: <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <gregkh@linuxfoundation.org>, <rafael@kernel.org>, <eric.auger@redhat.com>, <alex.williamson@redhat.com>, <cohuck@redhat.com>, <puneet.gupta@amd.com>, <song.bao.hua@hisilicon.com>, <mchehab+huawei@kernel.org>, <maz@kernel.org>, <f.fainelli@gmail.com>, <jeffrey.l.hugo@gmail.com>, <saravanak@google.com>, <Michael.Srba@seznam.cz>, <mani@kernel.org>, <yishaih@nvidia.com>, <jgg@ziepe.ca>, <jgg@nvidia.com>, <robin.murphy@arm.com>, <will@kernel.org>, <joro@8bytes.org>, <masahiroy@kernel.org>, <ndesaulniers@google.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kbuild@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>, <kvm@vger.kernel.org> Cc: <okaya@kernel.org>, <harpreet.anand@amd.com>, <nikhil.agarwal@amd.com>, <michal.simek@amd.com>, <aleksandar.radovanovic@amd.com>, <git@amd.com>, Nipun Gupta <nipun.gupta@amd.com> Subject: [RFC PATCH v3 4/7] bus/cdx: add cdx-MSI domain with gic-its domain as parent Date: Tue, 6 Sep 2022 19:17:58 +0530 [thread overview] Message-ID: <20220906134801.4079497-5-nipun.gupta@amd.com> (raw) In-Reply-To: <20220906134801.4079497-1-nipun.gupta@amd.com> Devices on cdx bus are dynamically detected and registered using platform_device_register API. As these devices are not linked to of node they need a separate MSI domain for handling device ID to be provided to the GIC ITS domain. This also introduces APIs to alloc and free IRQs for CDX domain. Signed-off-by: Nipun Gupta <nipun.gupta@amd.com> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@amd.com> --- drivers/bus/cdx/cdx.c | 18 +++ drivers/bus/cdx/cdx.h | 19 +++ drivers/bus/cdx/cdx_msi.c | 236 +++++++++++++++++++++++++++++++++++ drivers/bus/cdx/mcdi_stubs.c | 1 + include/linux/cdx/cdx_bus.h | 19 +++ 5 files changed, 293 insertions(+) create mode 100644 drivers/bus/cdx/cdx_msi.c diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c index fc417c32c59b..02ececce1c84 100644 --- a/drivers/bus/cdx/cdx.c +++ b/drivers/bus/cdx/cdx.c @@ -17,6 +17,7 @@ #include <linux/dma-map-ops.h> #include <linux/property.h> #include <linux/iommu.h> +#include <linux/msi.h> #include <linux/cdx/cdx_bus.h> #include "cdx.h" @@ -236,6 +237,7 @@ static int cdx_device_add(struct device *parent, struct cdx_dev_params_t *dev_params) { struct cdx_device *cdx_dev; + struct irq_domain *cdx_msi_domain; int ret; cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); @@ -252,6 +254,7 @@ static int cdx_device_add(struct device *parent, /* Populate CDX dev params */ cdx_dev->req_id = dev_params->req_id; + cdx_dev->num_msi = dev_params->num_msi; cdx_dev->vendor = dev_params->vendor; cdx_dev->device = dev_params->device; cdx_dev->bus_id = dev_params->bus_id; @@ -269,6 +272,21 @@ static int cdx_device_add(struct device *parent, dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", cdx_dev->bus_id, cdx_dev->func_id); + /* If CDX MSI domain is not created, create one. */ + cdx_msi_domain = cdx_find_msi_domain(parent); + if (!cdx_msi_domain) { + cdx_msi_domain = cdx_msi_domain_init(parent); + if (!cdx_msi_domain) { + dev_err(&cdx_dev->dev, + "cdx_msi_domain_init() failed: %d", ret); + kfree(cdx_dev); + return -1; + } + } + + /* Set the MSI domain */ + dev_set_msi_domain(&cdx_dev->dev, cdx_msi_domain); + ret = device_add(&cdx_dev->dev); if (ret != 0) { dev_err(&cdx_dev->dev, diff --git a/drivers/bus/cdx/cdx.h b/drivers/bus/cdx/cdx.h index db0569431c10..95df440ebd73 100644 --- a/drivers/bus/cdx/cdx.h +++ b/drivers/bus/cdx/cdx.h @@ -20,6 +20,7 @@ * @res: array of MMIO region entries * @res_count: number of valid MMIO regions * @req_id: Requestor ID associated with CDX device + * @num_msi: Number of MSI's supported by the device */ struct cdx_dev_params_t { u16 vendor; @@ -29,6 +30,24 @@ struct cdx_dev_params_t { struct resource res[MAX_CDX_DEV_RESOURCES]; u8 res_count; u32 req_id; + u32 num_msi; }; +/** + * cdx_msi_domain_init - Init the CDX bus MSI domain. + * @dev: Device of the CDX bus controller + * + * Return CDX MSI domain, NULL on failure + */ +struct irq_domain *cdx_msi_domain_init(struct device *dev); + +/** + * cdx_find_msi_domain - Get the CDX-MSI domain. + * @dev: CDX controller generic device + * + * Return CDX MSI domain, NULL on error or if CDX-MSI domain is + * not yet created. + */ +struct irq_domain *cdx_find_msi_domain(struct device *parent); + #endif /* _CDX_H_ */ diff --git a/drivers/bus/cdx/cdx_msi.c b/drivers/bus/cdx/cdx_msi.c new file mode 100644 index 000000000000..2fb7bac18393 --- /dev/null +++ b/drivers/bus/cdx/cdx_msi.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD CDX bus driver MSI support + * + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + */ + +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/msi.h> +#include <linux/cdx/cdx_bus.h> + +#include "cdx.h" + +#ifdef GENERIC_MSI_DOMAIN_OPS +/* + * Generate a unique ID identifying the interrupt (only used within the MSI + * irqdomain. Combine the req_id with the interrupt index. + */ +static irq_hw_number_t cdx_domain_calc_hwirq(struct cdx_device *dev, + struct msi_desc *desc) +{ + /* + * Make the base hwirq value for req_id*10000 so it is readable + * as a decimal value in /proc/interrupts. + */ + return (irq_hw_number_t)(desc->msi_index + (dev->req_id * 10000)); +} + +static void cdx_msi_set_desc(msi_alloc_info_t *arg, + struct msi_desc *desc) +{ + arg->desc = desc; + arg->hwirq = cdx_domain_calc_hwirq(to_cdx_device(desc->dev), desc); +} +#else +#define cdx_msi_set_desc NULL +#endif + +static void cdx_msi_update_dom_ops(struct msi_domain_info *info) +{ + struct msi_domain_ops *ops = info->ops; + + if (!ops) + return; + + /* set_desc should not be set by the caller */ + if (!ops->set_desc) + ops->set_desc = cdx_msi_set_desc; +} + +static void cdx_msi_write_msg(struct irq_data *irq_data, + struct msi_msg *msg) +{ + /* + * Do nothing as CDX devices have these pre-populated + * in the hardware itself. + */ +} + +static void cdx_msi_update_chip_ops(struct msi_domain_info *info) +{ + struct irq_chip *chip = info->chip; + + if (!chip) + return; + + /* + * irq_write_msi_msg should not be set by the caller + */ + if (!chip->irq_write_msi_msg) + chip->irq_write_msi_msg = cdx_msi_write_msg; +} +/** + * cdx_msi_create_irq_domain - Create a CDX MSI interrupt domain + * @fwnode: Optional firmware node of the interrupt controller + * @info: MSI domain info + * @parent: Parent irq domain + * + * Updates the domain and chip ops and creates a CDX MSI + * interrupt domain. + * + * Returns: + * A domain pointer or NULL in case of failure. + */ +static struct irq_domain *cdx_msi_create_irq_domain(struct fwnode_handle *fwnode, + struct msi_domain_info *info, + struct irq_domain *parent) +{ + if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE))) + info->flags &= ~MSI_FLAG_LEVEL_CAPABLE; + if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) + cdx_msi_update_dom_ops(info); + if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) + cdx_msi_update_chip_ops(info); + info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | MSI_FLAG_FREE_MSI_DESCS; + + return msi_create_irq_domain(fwnode, info, parent); +} + +int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) +{ + struct irq_domain *msi_domain; + int ret; + + msi_domain = dev_get_msi_domain(dev); + if (!msi_domain) { + dev_err(dev, "msi domain get failed\n"); + return -EINVAL; + } + + ret = msi_setup_device_data(dev); + if (ret) { + dev_err(dev, "msi setup device failed: %d\n", ret); + return ret; + } + + msi_lock_descs(dev); + if (msi_first_desc(dev, MSI_DESC_ALL)) + ret = -EINVAL; + msi_unlock_descs(dev); + if (ret) { + dev_err(dev, "msi setup device failed: %d\n", ret); + return ret; + } + + ret = msi_domain_alloc_irqs(msi_domain, dev, irq_count); + if (ret) + dev_err(dev, "Failed to allocate IRQs\n"); + + return ret; +} +EXPORT_SYMBOL(cdx_msi_domain_alloc_irqs); + +void cdx_msi_domain_free_irqs(struct device *dev) +{ + struct irq_domain *msi_domain; + + msi_domain = dev_get_msi_domain(dev); + if (!msi_domain) + return; + + msi_domain_free_irqs(msi_domain, dev); +} +EXPORT_SYMBOL(cdx_msi_domain_free_irqs); + +static struct irq_chip cdx_msi_irq_chip = { + .name = "CDX-MSI", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = msi_domain_set_affinity +}; + +static int cdx_msi_prepare(struct irq_domain *msi_domain, + struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + struct msi_domain_info *msi_info; + struct device *parent = dev->parent; + u32 dev_id; + int ret; + + /* Retrieve device ID from requestor ID using parent device */ + ret = of_map_id(parent->of_node, cdx_dev->req_id, "msi-map", + "msi-map-mask", NULL, &dev_id); + if (ret) { + dev_err(dev, "of_map_id failed for MSI: %d\n", ret); + return ret; + } + + /* Set the device Id to be passed to the GIC-ITS */ + info->scratchpad[0].ul = dev_id; + + msi_info = msi_get_domain_info(msi_domain->parent); + + /* Allocate at least 32 MSIs, and always as a power of 2 */ + nvec = max_t(int, 32, roundup_pow_of_two(nvec)); + return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); +} + +static struct msi_domain_ops cdx_msi_ops __ro_after_init = { + .msi_prepare = cdx_msi_prepare, +}; + +static struct msi_domain_info cdx_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), + .ops = &cdx_msi_ops, + .chip = &cdx_msi_irq_chip, +}; + +struct irq_domain *cdx_msi_domain_init(struct device *dev) +{ + struct irq_domain *parent; + struct irq_domain *cdx_msi_domain; + struct fwnode_handle *fwnode_handle; + struct device_node *parent_node; + struct device_node *np = dev->of_node; + + fwnode_handle = of_node_to_fwnode(np); + + parent_node = of_parse_phandle(np, "msi-map", 1); + if (!parent_node) { + dev_err(dev, "msi-map not present on cdx controller\n"); + return NULL; + } + + parent = irq_find_matching_fwnode(of_node_to_fwnode(parent_node), + DOMAIN_BUS_NEXUS); + if (!parent || !msi_get_domain_info(parent)) { + dev_err(dev, "unable to locate ITS domain\n"); + return NULL; + } + + cdx_msi_domain = cdx_msi_create_irq_domain(fwnode_handle, + &cdx_msi_domain_info, parent); + if (!cdx_msi_domain) { + dev_err(dev, "unable to create CDX-MSI domain\n"); + return NULL; + } + + dev_dbg(dev, "CDX-MSI domain created\n"); + + return cdx_msi_domain; +} + +struct irq_domain *cdx_find_msi_domain(struct device *parent) +{ + return irq_find_host(parent->of_node); +} diff --git a/drivers/bus/cdx/mcdi_stubs.c b/drivers/bus/cdx/mcdi_stubs.c index cc9d30fa02f8..2c8db1f5a057 100644 --- a/drivers/bus/cdx/mcdi_stubs.c +++ b/drivers/bus/cdx/mcdi_stubs.c @@ -45,6 +45,7 @@ int cdx_mcdi_get_func_config(struct cdx_mcdi_t *cdx_mcdi, dev_params->res_count = 2; dev_params->req_id = 0x250; + dev_params->num_msi = 4; dev_params->vendor = 0x10ee; dev_params->device = 0x8084; dev_params->bus_id = bus_id; diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index 6e870b2c87d9..bf86024783d2 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -25,6 +25,7 @@ * @dma_mask: Default DMA mask * @flags: CDX device flags * @req_id: Requestor ID associated with CDX device + * @num_msi: Number of MSI's supported by the device * @driver_override: driver name to force a match; do not set directly, * because core frees it; use driver_set_override() to * set or clear it. @@ -40,6 +41,7 @@ struct cdx_device { u64 dma_mask; u16 flags; u32 req_id; + u32 num_msi; const char *driver_override; }; @@ -90,4 +92,21 @@ void cdx_driver_unregister(struct cdx_driver *driver); extern struct bus_type cdx_bus_type; +/** + * cdx_msi_domain_alloc_irqs - Allocate MSI's for the CDX device + * @dev: device pointer + * @irq_count: Number of MSI's to be allocated + * + * Return 0 for success, -errno on failure + */ +int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count); + +/** + * cdx_msi_domain_free_irqs - Free MSI's for CDX device + * @dev: device pointer + * + * Return 0 for success, -errno on failure + */ +void cdx_msi_domain_free_irqs(struct device *dev); + #endif /* _CDX_BUS_H_ */ -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Nipun Gupta <nipun.gupta@amd.com> To: <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <gregkh@linuxfoundation.org>, <rafael@kernel.org>, <eric.auger@redhat.com>, <alex.williamson@redhat.com>, <cohuck@redhat.com>, <puneet.gupta@amd.com>, <song.bao.hua@hisilicon.com>, <mchehab+huawei@kernel.org>, <maz@kernel.org>, <f.fainelli@gmail.com>, <jeffrey.l.hugo@gmail.com>, <saravanak@google.com>, <Michael.Srba@seznam.cz>, <mani@kernel.org>, <yishaih@nvidia.com>, <jgg@ziepe.ca>, <jgg@nvidia.com>, <robin.murphy@arm.com>, <will@kernel.org>, <joro@8bytes.org>, <masahiroy@kernel.org>, <ndesaulniers@google.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kbuild@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>, <kvm@vger.kernel.org> Cc: <okaya@kernel.org>, <harpreet.anand@amd.com>, <nikhil.agarwal@amd.com>, <michal.simek@amd.com>, <aleksandar.radovanovic@amd.com>, <git@amd.com>, Nipun Gupta <nipun.gupta@amd.com> Subject: [RFC PATCH v3 4/7] bus/cdx: add cdx-MSI domain with gic-its domain as parent Date: Tue, 6 Sep 2022 19:17:58 +0530 [thread overview] Message-ID: <20220906134801.4079497-5-nipun.gupta@amd.com> (raw) In-Reply-To: <20220906134801.4079497-1-nipun.gupta@amd.com> Devices on cdx bus are dynamically detected and registered using platform_device_register API. As these devices are not linked to of node they need a separate MSI domain for handling device ID to be provided to the GIC ITS domain. This also introduces APIs to alloc and free IRQs for CDX domain. Signed-off-by: Nipun Gupta <nipun.gupta@amd.com> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@amd.com> --- drivers/bus/cdx/cdx.c | 18 +++ drivers/bus/cdx/cdx.h | 19 +++ drivers/bus/cdx/cdx_msi.c | 236 +++++++++++++++++++++++++++++++++++ drivers/bus/cdx/mcdi_stubs.c | 1 + include/linux/cdx/cdx_bus.h | 19 +++ 5 files changed, 293 insertions(+) create mode 100644 drivers/bus/cdx/cdx_msi.c diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c index fc417c32c59b..02ececce1c84 100644 --- a/drivers/bus/cdx/cdx.c +++ b/drivers/bus/cdx/cdx.c @@ -17,6 +17,7 @@ #include <linux/dma-map-ops.h> #include <linux/property.h> #include <linux/iommu.h> +#include <linux/msi.h> #include <linux/cdx/cdx_bus.h> #include "cdx.h" @@ -236,6 +237,7 @@ static int cdx_device_add(struct device *parent, struct cdx_dev_params_t *dev_params) { struct cdx_device *cdx_dev; + struct irq_domain *cdx_msi_domain; int ret; cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); @@ -252,6 +254,7 @@ static int cdx_device_add(struct device *parent, /* Populate CDX dev params */ cdx_dev->req_id = dev_params->req_id; + cdx_dev->num_msi = dev_params->num_msi; cdx_dev->vendor = dev_params->vendor; cdx_dev->device = dev_params->device; cdx_dev->bus_id = dev_params->bus_id; @@ -269,6 +272,21 @@ static int cdx_device_add(struct device *parent, dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", cdx_dev->bus_id, cdx_dev->func_id); + /* If CDX MSI domain is not created, create one. */ + cdx_msi_domain = cdx_find_msi_domain(parent); + if (!cdx_msi_domain) { + cdx_msi_domain = cdx_msi_domain_init(parent); + if (!cdx_msi_domain) { + dev_err(&cdx_dev->dev, + "cdx_msi_domain_init() failed: %d", ret); + kfree(cdx_dev); + return -1; + } + } + + /* Set the MSI domain */ + dev_set_msi_domain(&cdx_dev->dev, cdx_msi_domain); + ret = device_add(&cdx_dev->dev); if (ret != 0) { dev_err(&cdx_dev->dev, diff --git a/drivers/bus/cdx/cdx.h b/drivers/bus/cdx/cdx.h index db0569431c10..95df440ebd73 100644 --- a/drivers/bus/cdx/cdx.h +++ b/drivers/bus/cdx/cdx.h @@ -20,6 +20,7 @@ * @res: array of MMIO region entries * @res_count: number of valid MMIO regions * @req_id: Requestor ID associated with CDX device + * @num_msi: Number of MSI's supported by the device */ struct cdx_dev_params_t { u16 vendor; @@ -29,6 +30,24 @@ struct cdx_dev_params_t { struct resource res[MAX_CDX_DEV_RESOURCES]; u8 res_count; u32 req_id; + u32 num_msi; }; +/** + * cdx_msi_domain_init - Init the CDX bus MSI domain. + * @dev: Device of the CDX bus controller + * + * Return CDX MSI domain, NULL on failure + */ +struct irq_domain *cdx_msi_domain_init(struct device *dev); + +/** + * cdx_find_msi_domain - Get the CDX-MSI domain. + * @dev: CDX controller generic device + * + * Return CDX MSI domain, NULL on error or if CDX-MSI domain is + * not yet created. + */ +struct irq_domain *cdx_find_msi_domain(struct device *parent); + #endif /* _CDX_H_ */ diff --git a/drivers/bus/cdx/cdx_msi.c b/drivers/bus/cdx/cdx_msi.c new file mode 100644 index 000000000000..2fb7bac18393 --- /dev/null +++ b/drivers/bus/cdx/cdx_msi.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD CDX bus driver MSI support + * + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + */ + +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/msi.h> +#include <linux/cdx/cdx_bus.h> + +#include "cdx.h" + +#ifdef GENERIC_MSI_DOMAIN_OPS +/* + * Generate a unique ID identifying the interrupt (only used within the MSI + * irqdomain. Combine the req_id with the interrupt index. + */ +static irq_hw_number_t cdx_domain_calc_hwirq(struct cdx_device *dev, + struct msi_desc *desc) +{ + /* + * Make the base hwirq value for req_id*10000 so it is readable + * as a decimal value in /proc/interrupts. + */ + return (irq_hw_number_t)(desc->msi_index + (dev->req_id * 10000)); +} + +static void cdx_msi_set_desc(msi_alloc_info_t *arg, + struct msi_desc *desc) +{ + arg->desc = desc; + arg->hwirq = cdx_domain_calc_hwirq(to_cdx_device(desc->dev), desc); +} +#else +#define cdx_msi_set_desc NULL +#endif + +static void cdx_msi_update_dom_ops(struct msi_domain_info *info) +{ + struct msi_domain_ops *ops = info->ops; + + if (!ops) + return; + + /* set_desc should not be set by the caller */ + if (!ops->set_desc) + ops->set_desc = cdx_msi_set_desc; +} + +static void cdx_msi_write_msg(struct irq_data *irq_data, + struct msi_msg *msg) +{ + /* + * Do nothing as CDX devices have these pre-populated + * in the hardware itself. + */ +} + +static void cdx_msi_update_chip_ops(struct msi_domain_info *info) +{ + struct irq_chip *chip = info->chip; + + if (!chip) + return; + + /* + * irq_write_msi_msg should not be set by the caller + */ + if (!chip->irq_write_msi_msg) + chip->irq_write_msi_msg = cdx_msi_write_msg; +} +/** + * cdx_msi_create_irq_domain - Create a CDX MSI interrupt domain + * @fwnode: Optional firmware node of the interrupt controller + * @info: MSI domain info + * @parent: Parent irq domain + * + * Updates the domain and chip ops and creates a CDX MSI + * interrupt domain. + * + * Returns: + * A domain pointer or NULL in case of failure. + */ +static struct irq_domain *cdx_msi_create_irq_domain(struct fwnode_handle *fwnode, + struct msi_domain_info *info, + struct irq_domain *parent) +{ + if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE))) + info->flags &= ~MSI_FLAG_LEVEL_CAPABLE; + if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) + cdx_msi_update_dom_ops(info); + if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) + cdx_msi_update_chip_ops(info); + info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | MSI_FLAG_FREE_MSI_DESCS; + + return msi_create_irq_domain(fwnode, info, parent); +} + +int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) +{ + struct irq_domain *msi_domain; + int ret; + + msi_domain = dev_get_msi_domain(dev); + if (!msi_domain) { + dev_err(dev, "msi domain get failed\n"); + return -EINVAL; + } + + ret = msi_setup_device_data(dev); + if (ret) { + dev_err(dev, "msi setup device failed: %d\n", ret); + return ret; + } + + msi_lock_descs(dev); + if (msi_first_desc(dev, MSI_DESC_ALL)) + ret = -EINVAL; + msi_unlock_descs(dev); + if (ret) { + dev_err(dev, "msi setup device failed: %d\n", ret); + return ret; + } + + ret = msi_domain_alloc_irqs(msi_domain, dev, irq_count); + if (ret) + dev_err(dev, "Failed to allocate IRQs\n"); + + return ret; +} +EXPORT_SYMBOL(cdx_msi_domain_alloc_irqs); + +void cdx_msi_domain_free_irqs(struct device *dev) +{ + struct irq_domain *msi_domain; + + msi_domain = dev_get_msi_domain(dev); + if (!msi_domain) + return; + + msi_domain_free_irqs(msi_domain, dev); +} +EXPORT_SYMBOL(cdx_msi_domain_free_irqs); + +static struct irq_chip cdx_msi_irq_chip = { + .name = "CDX-MSI", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = msi_domain_set_affinity +}; + +static int cdx_msi_prepare(struct irq_domain *msi_domain, + struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + struct msi_domain_info *msi_info; + struct device *parent = dev->parent; + u32 dev_id; + int ret; + + /* Retrieve device ID from requestor ID using parent device */ + ret = of_map_id(parent->of_node, cdx_dev->req_id, "msi-map", + "msi-map-mask", NULL, &dev_id); + if (ret) { + dev_err(dev, "of_map_id failed for MSI: %d\n", ret); + return ret; + } + + /* Set the device Id to be passed to the GIC-ITS */ + info->scratchpad[0].ul = dev_id; + + msi_info = msi_get_domain_info(msi_domain->parent); + + /* Allocate at least 32 MSIs, and always as a power of 2 */ + nvec = max_t(int, 32, roundup_pow_of_two(nvec)); + return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); +} + +static struct msi_domain_ops cdx_msi_ops __ro_after_init = { + .msi_prepare = cdx_msi_prepare, +}; + +static struct msi_domain_info cdx_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), + .ops = &cdx_msi_ops, + .chip = &cdx_msi_irq_chip, +}; + +struct irq_domain *cdx_msi_domain_init(struct device *dev) +{ + struct irq_domain *parent; + struct irq_domain *cdx_msi_domain; + struct fwnode_handle *fwnode_handle; + struct device_node *parent_node; + struct device_node *np = dev->of_node; + + fwnode_handle = of_node_to_fwnode(np); + + parent_node = of_parse_phandle(np, "msi-map", 1); + if (!parent_node) { + dev_err(dev, "msi-map not present on cdx controller\n"); + return NULL; + } + + parent = irq_find_matching_fwnode(of_node_to_fwnode(parent_node), + DOMAIN_BUS_NEXUS); + if (!parent || !msi_get_domain_info(parent)) { + dev_err(dev, "unable to locate ITS domain\n"); + return NULL; + } + + cdx_msi_domain = cdx_msi_create_irq_domain(fwnode_handle, + &cdx_msi_domain_info, parent); + if (!cdx_msi_domain) { + dev_err(dev, "unable to create CDX-MSI domain\n"); + return NULL; + } + + dev_dbg(dev, "CDX-MSI domain created\n"); + + return cdx_msi_domain; +} + +struct irq_domain *cdx_find_msi_domain(struct device *parent) +{ + return irq_find_host(parent->of_node); +} diff --git a/drivers/bus/cdx/mcdi_stubs.c b/drivers/bus/cdx/mcdi_stubs.c index cc9d30fa02f8..2c8db1f5a057 100644 --- a/drivers/bus/cdx/mcdi_stubs.c +++ b/drivers/bus/cdx/mcdi_stubs.c @@ -45,6 +45,7 @@ int cdx_mcdi_get_func_config(struct cdx_mcdi_t *cdx_mcdi, dev_params->res_count = 2; dev_params->req_id = 0x250; + dev_params->num_msi = 4; dev_params->vendor = 0x10ee; dev_params->device = 0x8084; dev_params->bus_id = bus_id; diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index 6e870b2c87d9..bf86024783d2 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -25,6 +25,7 @@ * @dma_mask: Default DMA mask * @flags: CDX device flags * @req_id: Requestor ID associated with CDX device + * @num_msi: Number of MSI's supported by the device * @driver_override: driver name to force a match; do not set directly, * because core frees it; use driver_set_override() to * set or clear it. @@ -40,6 +41,7 @@ struct cdx_device { u64 dma_mask; u16 flags; u32 req_id; + u32 num_msi; const char *driver_override; }; @@ -90,4 +92,21 @@ void cdx_driver_unregister(struct cdx_driver *driver); extern struct bus_type cdx_bus_type; +/** + * cdx_msi_domain_alloc_irqs - Allocate MSI's for the CDX device + * @dev: device pointer + * @irq_count: Number of MSI's to be allocated + * + * Return 0 for success, -errno on failure + */ +int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count); + +/** + * cdx_msi_domain_free_irqs - Free MSI's for CDX device + * @dev: device pointer + * + * Return 0 for success, -errno on failure + */ +void cdx_msi_domain_free_irqs(struct device *dev); + #endif /* _CDX_BUS_H_ */ -- 2.25.1
next prev parent reply other threads:[~2022-09-06 14:03 UTC|newest] Thread overview: 198+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-08-03 12:26 [RFC PATCH 0/2] add support for CDX bus MSI domain Nipun Gupta 2022-08-03 12:26 ` Nipun Gupta 2022-08-03 12:26 ` [RFC PATCH 1/2] irqchip: cdx-bus: add cdx-MSI domain with gic-its domain as parent Nipun Gupta 2022-08-03 12:26 ` Nipun Gupta 2022-08-03 12:33 ` Greg KH 2022-08-03 12:33 ` Greg KH 2022-08-03 12:37 ` Gupta, Nipun 2022-08-03 12:37 ` Gupta, Nipun 2022-08-04 8:49 ` Marc Zyngier 2022-08-04 8:49 ` Marc Zyngier 2022-08-04 9:18 ` Gupta, Nipun 2022-08-04 9:18 ` Gupta, Nipun 2022-08-04 10:38 ` Marc Zyngier 2022-08-04 12:11 ` Gupta, Nipun 2022-08-04 12:11 ` Gupta, Nipun 2022-08-03 12:26 ` [RFC PATCH 2/2] driver core: add compatible string in sysfs for platform devices Nipun Gupta 2022-08-03 12:26 ` Nipun Gupta 2022-08-03 12:31 ` Greg KH 2022-08-03 12:31 ` Greg KH 2022-08-03 12:46 ` Gupta, Nipun 2022-08-03 12:46 ` Gupta, Nipun 2022-08-03 14:16 ` [RFC PATCH 0/2] add support for CDX bus MSI domain Robin Murphy 2022-08-03 14:16 ` Robin Murphy 2022-08-04 4:23 ` Gupta, Nipun 2022-08-04 4:23 ` Gupta, Nipun 2022-08-17 16:00 ` Jason Gunthorpe 2022-08-17 16:00 ` Jason Gunthorpe 2022-08-17 15:05 ` [RFC PATCH v2 0/6] add support for CDX bus controller Nipun Gupta 2022-08-17 15:05 ` [RFC PATCH v2 1/6] Documentation: DT: Add entry for CDX controller Nipun Gupta 2022-08-18 9:54 ` Krzysztof Kozlowski 2022-08-18 9:59 ` Krzysztof Kozlowski 2022-09-05 14:05 ` Gupta, Nipun 2022-09-06 6:55 ` Krzysztof Kozlowski 2022-09-06 7:03 ` Gupta, Nipun 2022-09-06 7:20 ` Krzysztof Kozlowski 2022-08-17 15:05 ` [RFC PATCH v2 2/6] bus/cdx: add the cdx bus driver Nipun Gupta 2022-08-17 15:32 ` Greg KH 2022-08-17 15:46 ` Marc Zyngier 2022-08-22 13:21 ` Gupta, Nipun 2022-08-22 13:29 ` Greg KH 2022-08-24 8:50 ` Gupta, Nipun 2022-08-24 12:11 ` Greg KH 2022-08-24 23:31 ` Jason Gunthorpe 2022-08-25 18:38 ` Saravana Kannan 2022-08-25 19:57 ` Robin Murphy 2022-08-26 0:08 ` Jason Gunthorpe 2022-08-29 4:49 ` Gupta, Nipun 2022-08-29 4:49 ` Gupta, Nipun 2022-08-29 15:31 ` Jason Gunthorpe 2022-08-30 7:06 ` Gupta, Nipun 2022-08-30 11:25 ` Robin Murphy 2022-08-30 13:01 ` Jason Gunthorpe 2022-08-30 13:12 ` Gupta, Nipun 2022-08-17 15:05 ` [RFC PATCH v2 3/6] bus/cdx: add cdx-MSI domain with gic-its domain as parent Nipun Gupta 2022-08-17 15:33 ` Greg KH 2022-08-17 15:05 ` [RFC PATCH v2 4/6] bus/cdx: add rescan and reset support Nipun Gupta 2022-08-17 15:05 ` [RFC PATCH v2 5/6] vfio: platform: reset: add reset for cdx devices Nipun Gupta 2022-08-17 15:05 ` [RFC PATCH v2 6/6] driver core: add compatible string in sysfs for platform devices Nipun Gupta 2022-08-17 15:30 ` Greg KH 2022-08-17 16:04 ` Saravana Kannan 2022-09-05 13:54 ` Gupta, Nipun 2022-09-06 13:47 ` [RFC PATCH v3 0/7] add support for CDX bus Nipun Gupta 2022-09-06 13:47 ` Nipun Gupta 2022-09-06 13:47 ` [RFC PATCH v3 1/7] dt-bindings: bus: add CDX bus device tree bindings Nipun Gupta 2022-09-06 13:47 ` Nipun Gupta 2022-09-06 17:46 ` Rob Herring 2022-09-06 17:46 ` Rob Herring 2022-09-07 3:13 ` Gupta, Nipun 2022-09-07 3:13 ` Gupta, Nipun 2022-09-08 10:51 ` Krzysztof Kozlowski 2022-09-08 10:51 ` Krzysztof Kozlowski 2022-09-06 13:47 ` [RFC PATCH v3 2/7] bus/cdx: add the cdx bus driver Nipun Gupta 2022-09-06 13:47 ` Nipun Gupta 2022-09-07 0:32 ` Saravana Kannan 2022-09-07 0:32 ` Saravana Kannan 2022-09-07 3:21 ` Gupta, Nipun 2022-09-07 3:21 ` Gupta, Nipun 2022-09-07 18:06 ` Saravana Kannan 2022-09-07 18:06 ` Saravana Kannan 2022-09-07 12:32 ` Greg KH 2022-09-07 12:32 ` Greg KH 2022-09-08 13:29 ` Gupta, Nipun 2022-09-08 13:29 ` Gupta, Nipun 2022-09-06 13:47 ` [RFC PATCH v3 3/7] iommu/arm-smmu-v3: support ops registration for CDX bus Nipun Gupta 2022-09-06 13:47 ` Nipun Gupta 2022-09-07 0:10 ` Saravana Kannan 2022-09-07 0:10 ` Saravana Kannan 2022-09-07 3:17 ` Gupta, Nipun 2022-09-07 3:17 ` Gupta, Nipun 2022-09-07 8:27 ` Robin Murphy 2022-09-07 8:27 ` Robin Murphy 2022-09-07 18:24 ` Saravana Kannan 2022-09-07 18:24 ` Saravana Kannan 2022-09-07 20:40 ` Robin Murphy 2022-09-07 20:40 ` Robin Murphy 2022-09-08 0:14 ` Saravana Kannan 2022-09-08 0:14 ` Saravana Kannan 2022-09-06 13:47 ` Nipun Gupta [this message] 2022-09-06 13:47 ` [RFC PATCH v3 4/7] bus/cdx: add cdx-MSI domain with gic-its domain as parent Nipun Gupta 2022-09-06 17:19 ` Jason Gunthorpe 2022-09-06 17:19 ` Jason Gunthorpe 2022-09-07 11:17 ` Marc Zyngier 2022-09-07 11:17 ` Marc Zyngier 2022-09-07 11:33 ` Robin Murphy 2022-09-07 11:33 ` Robin Murphy 2022-09-07 12:14 ` Marc Zyngier 2022-09-07 12:14 ` Marc Zyngier 2022-09-07 11:35 ` Radovanovic, Aleksandar 2022-09-07 11:35 ` Radovanovic, Aleksandar 2022-09-07 12:32 ` Marc Zyngier 2022-09-07 13:18 ` Radovanovic, Aleksandar 2022-09-07 13:18 ` Radovanovic, Aleksandar 2022-09-08 8:08 ` Marc Zyngier 2022-09-08 9:51 ` Radovanovic, Aleksandar 2022-09-08 9:51 ` Radovanovic, Aleksandar 2022-09-08 11:49 ` Robin Murphy 2022-09-08 11:49 ` Robin Murphy 2022-09-08 14:18 ` Marc Zyngier 2022-09-07 13:18 ` Marc Zyngier 2022-09-07 13:18 ` Marc Zyngier 2022-09-08 14:13 ` Gupta, Nipun 2022-09-08 14:13 ` Gupta, Nipun 2022-09-08 14:29 ` Marc Zyngier 2022-09-09 6:32 ` Gupta, Nipun 2022-09-09 6:32 ` Gupta, Nipun 2022-10-12 10:04 ` Gupta, Nipun 2022-10-12 10:04 ` Gupta, Nipun 2022-10-12 10:34 ` Radovanovic, Aleksandar 2022-10-12 10:34 ` Radovanovic, Aleksandar 2022-10-12 13:02 ` Jason Gunthorpe 2022-10-12 13:02 ` Jason Gunthorpe 2022-10-12 13:37 ` Radovanovic, Aleksandar 2022-10-12 13:37 ` Radovanovic, Aleksandar 2022-10-12 14:38 ` Jason Gunthorpe 2022-10-12 14:38 ` Jason Gunthorpe 2022-10-12 15:09 ` Radovanovic, Aleksandar 2022-10-12 15:09 ` Radovanovic, Aleksandar 2022-10-13 12:43 ` Jason Gunthorpe 2022-10-13 12:43 ` Jason Gunthorpe 2022-10-14 11:18 ` Radovanovic, Aleksandar 2022-10-14 11:18 ` Radovanovic, Aleksandar 2022-10-14 11:54 ` gregkh 2022-10-14 11:54 ` gregkh 2022-10-14 12:13 ` Radovanovic, Aleksandar 2022-10-14 12:13 ` Radovanovic, Aleksandar 2022-10-14 13:46 ` gregkh 2022-10-14 13:46 ` gregkh 2022-10-14 13:58 ` Jason Gunthorpe 2022-10-14 13:58 ` Jason Gunthorpe 2022-09-06 13:47 ` [RFC PATCH v3 5/7] bus/cdx: add bus and device attributes Nipun Gupta 2022-09-06 13:47 ` Nipun Gupta 2022-09-06 13:48 ` [RFC PATCH v3 6/7] vfio/cdx: add support for CDX bus Nipun Gupta 2022-09-06 13:48 ` Nipun Gupta 2022-09-06 17:20 ` Jason Gunthorpe 2022-09-06 17:20 ` Jason Gunthorpe 2022-09-06 17:23 ` Gupta, Nipun 2022-09-06 17:23 ` Gupta, Nipun 2022-09-06 13:48 ` [RFC PATCH v3 7/7] vfio/cdx: add interrupt support Nipun Gupta 2022-09-06 13:48 ` Nipun Gupta 2022-10-14 4:40 ` [RFC PATCH v4 0/8] add support for CDX bus Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 4:40 ` [RFC PATCH v4 1/8] dt-bindings: bus: add CDX bus device tree bindings Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 14:17 ` Rob Herring 2022-10-14 14:17 ` Rob Herring 2022-10-17 10:18 ` Gupta, Nipun 2022-10-17 10:18 ` Gupta, Nipun 2022-10-14 4:40 ` [RFC PATCH v4 2/8] bus/cdx: add the cdx bus driver Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 7:15 ` Greg KH 2022-10-14 7:15 ` Greg KH 2022-10-14 8:12 ` Gupta, Nipun 2022-10-14 8:12 ` Gupta, Nipun 2022-10-14 7:18 ` Greg KH 2022-10-14 7:18 ` Greg KH 2022-10-14 8:20 ` Gupta, Nipun 2022-10-14 8:20 ` Gupta, Nipun 2022-10-14 4:40 ` [RFC PATCH v4 3/8] iommu/arm-smmu-v3: support ops registration for CDX bus Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 4:51 ` Gupta, Nipun 2022-10-14 4:51 ` Gupta, Nipun 2022-10-14 4:40 ` [RFC PATCH v4 4/8] bux/cdx: support dma configuration for CDX devices Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 4:40 ` [RFC PATCH v4 5/8] bus/cdx: add bus and device attributes Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 4:40 ` [RFC PATCH v4 6/8] irq/msi: use implicit msi domain for alloc and free Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 4:40 ` [RFC PATCH v4 7/8] bus/cdx: add cdx-MSI domain with gic-its domain as parent Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-17 13:08 ` kernel test robot 2022-11-17 19:10 ` Thomas Gleixner 2022-11-17 19:10 ` Thomas Gleixner 2022-10-14 4:40 ` [RFC PATCH v4 8/8] bus/cdx: add cdx controller Nipun Gupta 2022-10-14 4:40 ` Nipun Gupta 2022-10-14 14:10 ` [RFC PATCH v4 0/8] add support for CDX bus Rob Herring 2022-10-14 14:10 ` Rob Herring 2022-10-17 10:08 ` Gupta, Nipun 2022-10-17 10:08 ` Gupta, Nipun
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220906134801.4079497-5-nipun.gupta@amd.com \ --to=nipun.gupta@amd.com \ --cc=Michael.Srba@seznam.cz \ --cc=aleksandar.radovanovic@amd.com \ --cc=alex.williamson@redhat.com \ --cc=cohuck@redhat.com \ --cc=devicetree@vger.kernel.org \ --cc=eric.auger@redhat.com \ --cc=f.fainelli@gmail.com \ --cc=git@amd.com \ --cc=gregkh@linuxfoundation.org \ --cc=harpreet.anand@amd.com \ --cc=jeffrey.l.hugo@gmail.com \ --cc=jgg@nvidia.com \ --cc=jgg@ziepe.ca \ --cc=joro@8bytes.org \ --cc=krzysztof.kozlowski+dt@linaro.org \ --cc=kvm@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kbuild@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mani@kernel.org \ --cc=masahiroy@kernel.org \ --cc=maz@kernel.org \ --cc=mchehab+huawei@kernel.org \ --cc=michal.simek@amd.com \ --cc=ndesaulniers@google.com \ --cc=nikhil.agarwal@amd.com \ --cc=okaya@kernel.org \ --cc=puneet.gupta@amd.com \ --cc=rafael@kernel.org \ --cc=robh+dt@kernel.org \ --cc=robin.murphy@arm.com \ --cc=saravanak@google.com \ --cc=song.bao.hua@hisilicon.com \ --cc=will@kernel.org \ --cc=yishaih@nvidia.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.