From: "Yun Wu (Abel)" <wuyun.wu@huawei.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
Jiang Liu <jiang.liu@linux.intel.com>,
Bjorn Helgaas <bhelgaas@google.com>,
"Grant Likely" <grant.likely@linaro.org>,
Marc Zyngier <marc.zyngier@arm.com>,
Yingjoe Chen <yingjoe.chen@mediatek.com>,
Yijing Wang <wangyijing@huawei.com>
Subject: Re: [patch 09/16] genirq: Add generic msi irq domain support
Date: Tue, 18 Nov 2014 20:07:03 +0800 [thread overview]
Message-ID: <546B3667.9040506@huawei.com> (raw)
In-Reply-To: <20141112134120.569789374@linutronix.de>
On 2014/11/12 21:43, Thomas Gleixner wrote:
> From: Jiang Liu <jiang.liu@linux.intel.com>
>
> Implement the basic functions for MSI interrupt support with
> hierarchical interrupt domains.
>
> [ tglx: Extracted and combined from several patches ]
>
> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Yingjoe Chen <yingjoe.chen@mediatek.com>
> Cc: Yijing Wang <wangyijing@huawei.com>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> include/linux/msi.h | 35 +++++++++++++++
> kernel/irq/Kconfig | 10 ++++
> kernel/irq/Makefile | 1
> kernel/irq/msi.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 165 insertions(+)
>
> Index: tip/include/linux/msi.h
> ===================================================================
> --- tip.orig/include/linux/msi.h
> +++ tip/include/linux/msi.h
> @@ -77,4 +77,39 @@ struct msi_chip {
> void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
> };
>
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +struct irq_domain;
> +struct irq_chip;
> +struct device_node;
> +struct msi_domain_info;
> +
> +struct msi_domain_ops {
> + void (*calc_hwirq)(struct msi_domain_info *info, void *arg,
> + struct msi_desc *desc);
> + irq_hw_number_t (*get_hwirq)(struct msi_domain_info *info, void *arg);
> + int (*msi_init)(struct irq_domain *domain,
> + struct msi_domain_info *info,
> + unsigned int virq, irq_hw_number_t hwirq,
> + void *arg);
> + void (*msi_free)(struct irq_domain *domain,
> + struct msi_domain_info *info,
> + unsigned int virq);
> +};
> +
> +struct msi_domain_info {
> + struct msi_domain_ops *ops;
> + struct irq_chip *chip;
> + void *data;
> +};
> +
> +int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
> + bool force);
> +
> +struct irq_domain *msi_create_irq_domain(struct device_node *of_node,
> + struct msi_domain_info *info,
> + struct irq_domain *parent);
> +struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
> +
> +#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
> +
> #endif /* LINUX_MSI_H */
> Index: tip/kernel/irq/Kconfig
> ===================================================================
> --- tip.orig/kernel/irq/Kconfig
> +++ tip/kernel/irq/Kconfig
> @@ -60,6 +60,16 @@ config IRQ_DOMAIN_HIERARCHY
> bool
> select IRQ_DOMAIN
>
> +# Generic MSI interrupt support
> +config GENERIC_MSI_IRQ
> + bool
> +
> +# Generic MSI hierarchical interrupt domain support
> +config GENERIC_MSI_IRQ_DOMAIN
> + bool
> + select IRQ_DOMAIN_HIERARCHY
> + select GENERIC_MSI_IRQ
> +
> config HANDLE_DOMAIN_IRQ
> bool
>
> Index: tip/kernel/irq/Makefile
> ===================================================================
> --- tip.orig/kernel/irq/Makefile
> +++ tip/kernel/irq/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o
> obj-$(CONFIG_PROC_FS) += proc.o
> obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
> obj-$(CONFIG_PM_SLEEP) += pm.o
> +obj-$(CONFIG_GENERIC_MSI_IRQ) += msi.o
> Index: tip/kernel/irq/msi.c
> ===================================================================
> --- /dev/null
> +++ tip/kernel/irq/msi.c
> @@ -0,0 +1,119 @@
> +/*
> + * linux/kernel/irq/msi.c
> + *
> + * Copyright (C) 2014 Intel Corp.
> + * Author: Jiang Liu <jiang.liu@linux.intel.com>
> + *
> + * This file is licensed under GPLv2.
> + *
> + * This file contains common code to support Message Signalled Interrupt for
> + * PCI compatible and non PCI compatible devices.
> + */
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/msi.h>
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +int msi_domain_set_affinity(struct irq_data *irq_data,
> + const struct cpumask *mask, bool force)
> +{
> + struct irq_data *parent = irq_data->parent_data;
> + struct msi_msg msg;
> + int ret;
> +
> + ret = parent->chip->irq_set_affinity(parent, mask, force);
> + if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) {
> + BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg));
> + irq_chip_write_msi_msg(irq_data, &msg);
> + }
> +
> + return ret;
> +}
> +
> +static void msi_domain_activate(struct irq_domain *domain,
> + struct irq_data *irq_data)
> +{
> + struct msi_msg msg;
> +
> + BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg));
> + irq_chip_write_msi_msg(irq_data, &msg);
> +}
> +
> +static void msi_domain_deactivate(struct irq_domain *domain,
> + struct irq_data *irq_data)
> +{
> + struct msi_msg msg;
> +
> + memset(&msg, 0, sizeof(msg));
> + irq_chip_write_msi_msg(irq_data, &msg);
> +}
> +
> +static int msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
> + unsigned int nr_irqs, void *arg)
> +{
> + struct msi_domain_info *info = domain->host_data;
> + struct msi_domain_ops *ops = info->ops;
> + irq_hw_number_t hwirq = ops->get_hwirq(info, arg);
> + int i, ret;
> +
> + if (irq_find_mapping(domain, hwirq) > 0)
> + return -EEXIST;
I think we need to check range here.
I fixed this by applying a patch showed in the bottom.
> +
> + ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
> + if (ret < 0)
> + return ret;
> +
> + for (i = 0; i < nr_irqs; i++) {
> + ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg);
> + if (ret < 0) {
> + if (ops->msi_free) {
> + for (i--; i > 0; i--)
while (i--) ?
Regards,
Abel
> + ops->msi_free(domain, info, virq + i);
> + }
> + irq_domain_free_irqs_top(domain, virq, nr_irqs);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void msi_domain_free(struct irq_domain *domain, unsigned int virq,
> + unsigned int nr_irqs)
> +{
> + struct msi_domain_info *info = domain->host_data;
> + int i;
> +
> + if (info->ops->msi_free) {
> + for (i = 0; i < nr_irqs; i++)
> + info->ops->msi_free(domain, info, virq + i);
> + }
> + irq_domain_free_irqs_top(domain, virq, nr_irqs);
> +}
> +
> +static struct irq_domain_ops msi_domain_ops = {
> + .alloc = msi_domain_alloc,
> + .free = msi_domain_free,
> + .activate = msi_domain_activate,
> + .deactivate = msi_domain_deactivate,
> +};
> +
> +struct irq_domain *msi_create_irq_domain(struct device_node *of_node,
> + struct msi_domain_info *info,
> + struct irq_domain *parent)
> +{
> + struct irq_domain *domain;
> +
> + domain = irq_domain_add_tree(of_node, &msi_domain_ops, info);
> + if (domain)
> + domain->parent = parent;
> +
> + return domain;
> +}
> +
> +struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain)
> +{
> + return (struct msi_domain_info *)domain->host_data;
> +}
> +
> +#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
>
>
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index cc18182..6d1be00 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -568,6 +568,34 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
}
EXPORT_SYMBOL_GPL(irq_find_mapping);
+/**
+ * irq_find_mapping_many() - Find a range of linux irqs from a range of hwirqs.
+ * @domain: domain owning these hardware interrupts
+ * @hwirq: start hardware irq number in @domain space
+ * @count: number of interrupts to find
+ *
+ * Returns the first linux irq number on success, or 0 when not found, or error.
+ */
+int irq_find_mapping_many(struct irq_domain *domain, irq_hw_number_t hwirq,
+ int count)
+{
+ unsigned int from;
+ int i;
+
+ for (i = from = 0; i < count; i++) {
+ if (!from) {
+ from = irq_find_mapping(domain, hwirq + i);
+ if (from && i)
+ return -1;
+ } else if ((from + i) != irq_find_mapping(domain, hwirq + i)) {
+ return -1;
+ }
+ }
+
+ return from;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping_many);
+
#ifdef CONFIG_IRQ_DOMAIN_DEBUG
static int virq_debug_show(struct seq_file *m, void *private)
{
next prev parent reply other threads:[~2014-11-18 12:07 UTC|newest]
Thread overview: 94+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-12 13:42 [patch 00/16] genirq: Hierarchical irq domains and generic MSI interrupt code Thomas Gleixner
2014-11-12 13:42 ` [patch 01/16] irqdomain: Introduce new interfaces to support hierarchy irqdomains Thomas Gleixner
2014-11-18 9:24 ` Yun Wu (Abel)
2014-11-18 9:54 ` Thomas Gleixner
2014-11-18 11:48 ` Yun Wu (Abel)
2014-11-24 12:33 ` Yun Wu (Abel)
2014-11-24 13:13 ` Thomas Gleixner
2014-11-24 14:01 ` Yun Wu (Abel)
2014-11-24 14:11 ` Jiang Liu
2014-11-24 14:19 ` Yun Wu (Abel)
2014-11-24 14:33 ` Jiang Liu
2014-11-24 14:46 ` Yun Wu (Abel)
2014-11-24 14:32 ` Thomas Gleixner
2014-11-24 14:45 ` Yun Wu (Abel)
2014-11-12 13:42 ` [patch 02/16] irqdomain: Do irq_find_mapping and set_type for hierarchy irqdomain in case OF Thomas Gleixner
2014-11-12 13:42 ` [patch 03/16] genirq: Introduce helper functions to support stacked irq_chip Thomas Gleixner
2014-11-12 13:42 ` [patch 04/16] genirq: Introduce irq_chip.irq_compose_msi_msg() to support stacked irqchip Thomas Gleixner
2014-11-18 9:26 ` Yun Wu (Abel)
2014-11-18 10:02 ` Thomas Gleixner
2014-11-18 11:47 ` Yun Wu (Abel)
2014-11-18 12:43 ` Jiang Liu
2014-11-18 13:16 ` Yun Wu (Abel)
2014-11-18 13:25 ` Jiang Liu
2014-11-18 13:48 ` Yun Wu (Abel)
2014-11-18 13:55 ` Jiang Liu
2014-11-18 14:03 ` Yun Wu (Abel)
2014-11-18 14:06 ` Jiang Liu
2014-11-12 13:42 ` [patch 05/16] genirq: Add IRQ_SET_MASK_OK_DONE " Thomas Gleixner
2014-11-12 13:43 ` [patch 06/16] genirq: Split out flow handler typedefs into seperate header file Thomas Gleixner
2014-11-12 13:43 ` [patch 07/16] genirq: Introduce helper irq_domain_set_info() to reduce duplicated code Thomas Gleixner
2014-11-13 9:57 ` Yingjoe Chen
2014-11-13 10:00 ` Jiang Liu
2014-11-13 10:48 ` Marc Zyngier
2014-11-14 15:31 ` Marc Zyngier
2014-11-14 15:41 ` Jiang Liu
2014-11-14 17:35 ` Marc Zyngier
2014-11-15 1:26 ` Jiang Liu
2014-11-18 9:26 ` Yun Wu (Abel)
2014-11-18 10:03 ` Thomas Gleixner
2014-11-18 11:47 ` Yun Wu (Abel)
2014-11-18 12:38 ` Jiang Liu
2014-11-18 13:28 ` Yun Wu (Abel)
2014-11-18 13:37 ` Jiang Liu
2014-11-12 13:43 ` [patch 08/16] genirq: Introduce callback irq_chip.irq_write_msi_msg Thomas Gleixner
2014-11-18 9:26 ` Yun Wu (Abel)
2014-11-18 10:19 ` Thomas Gleixner
2014-11-18 13:33 ` Yun Wu (Abel)
2014-11-18 13:43 ` Jiang Liu
2014-11-18 13:52 ` Yun Wu (Abel)
2014-11-18 14:03 ` Jiang Liu
2014-11-18 14:15 ` Jiang Liu
2014-11-18 14:22 ` Yun Wu (Abel)
2014-11-18 14:29 ` Jiang Liu
2014-11-18 14:46 ` Yun Wu (Abel)
2014-11-18 17:14 ` Marc Zyngier
2014-11-19 3:38 ` Yun Wu (Abel)
2014-11-19 8:55 ` Marc Zyngier
2014-11-18 14:32 ` Thomas Gleixner
2014-11-19 6:57 ` Yun Wu (Abel)
2014-11-19 8:02 ` Jiang Liu
2014-11-19 9:20 ` Marc Zyngier
2014-12-10 9:26 ` Yun Wu (Abel)
2014-11-18 14:19 ` Thomas Gleixner
2014-11-18 14:34 ` Yun Wu (Abel)
2014-11-18 14:52 ` Jiang Liu
2014-11-19 3:47 ` Yun Wu (Abel)
2014-11-19 11:09 ` Thomas Gleixner
2014-11-18 17:21 ` Marc Zyngier
2014-11-19 3:40 ` Yun Wu (Abel)
2014-11-19 11:11 ` Thomas Gleixner
2014-12-10 9:11 ` Yun Wu (Abel)
2014-12-10 10:25 ` Thomas Gleixner
2014-12-11 3:01 ` Yun Wu (Abel)
2014-11-18 13:51 ` Jiang Liu
2014-11-12 13:43 ` [patch 09/16] genirq: Add generic msi irq domain support Thomas Gleixner
2014-11-18 12:07 ` Yun Wu (Abel) [this message]
2014-11-18 12:49 ` Jiang Liu
2014-11-18 13:55 ` Yun Wu (Abel)
2014-11-18 14:24 ` Thomas Gleixner
2014-11-18 14:39 ` Yun Wu (Abel)
2014-11-20 2:29 ` Jiang Liu
2014-11-12 13:43 ` [patch 10/16] PCI/MSI: Move cached entry functions to irq core Thomas Gleixner
2014-11-12 13:43 ` [patch 11/16] PCI/MSI: Remove unnecessary braces around single statements Thomas Gleixner
2014-11-12 13:43 ` [patch 12/16] PCI/MSI: Simplify PCI MSI code by initializing msi_desc.nvec_used earlier Thomas Gleixner
2014-11-12 13:43 ` [patch 13/16] PCI/MSI: Kill redundant call of irq_set_msi_desc() for MSI-X interrupts Thomas Gleixner
2014-11-12 13:43 ` [patch 14/16] PCI/MSI: Rename __read_msi_msg() to __pci_read_msi_msg() Thomas Gleixner
2014-11-12 13:43 ` [patch 15/16] PCI/MSI: Rename write_msi_msg() to pci_write_msi_msg() Thomas Gleixner
2014-11-12 16:50 ` Jiang Liu
2014-11-12 13:43 ` [patch 16/16] PCI/MSI: Enhance core to support hierarchy irqdomain Thomas Gleixner
2014-11-12 15:29 ` Marc Zyngier
2014-11-12 16:43 ` Thomas Gleixner
2014-11-12 14:13 ` [patch 00/16] genirq: Hierarchical irq domains and generic MSI interrupt code Yingjoe Chen
2014-11-12 14:48 ` Thomas Gleixner
2014-11-18 9:24 ` Yun Wu (Abel)
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=546B3667.9040506@huawei.com \
--to=wuyun.wu@huawei.com \
--cc=bhelgaas@google.com \
--cc=grant.likely@linaro.org \
--cc=jiang.liu@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=tglx@linutronix.de \
--cc=wangyijing@huawei.com \
--cc=yingjoe.chen@mediatek.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: link
Be 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.