All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Jiang Liu <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: bhelgaas@google.com, tglx@linutronix.de, grant.likely@linaro.org,
	matthias.bgg@gmail.com, marc.zyngier@arm.com, hpa@zytor.com,
	wangyijing@huawei.com, yingjoe.chen@mediatek.com,
	tony.luck@intel.com, linux-kernel@vger.kernel.org, bp@alien8.de,
	benh@kernel.crashing.org, jiang.liu@linux.intel.com,
	mingo@kernel.org
Subject: [tip:irq/irqdomain] irqdomain: Implement a method to automatically call parent domains alloc/free
Date: Sun, 23 Nov 2014 10:11:28 -0800	[thread overview]
Message-ID: <tip-36d727310cb9f85efb5ac089ffb1797e7c3538e1@git.kernel.org> (raw)
In-Reply-To: <1416061447-9472-4-git-send-email-jiang.liu@linux.intel.com>

Commit-ID:  36d727310cb9f85efb5ac089ffb1797e7c3538e1
Gitweb:     http://git.kernel.org/tip/36d727310cb9f85efb5ac089ffb1797e7c3538e1
Author:     Jiang Liu <jiang.liu@linux.intel.com>
AuthorDate: Sat, 15 Nov 2014 22:24:01 +0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 23 Nov 2014 13:01:46 +0100

irqdomain: Implement a method to automatically call parent domains alloc/free

Add a flags to irq_domain.flags to control whether the irqdomain core
should automatically call parent irqdomain's alloc/free callbacks. It
help to reduce hierarchy irqdomains users' code size.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Yijing Wang <wangyijing@huawei.com>
Cc: Yingjoe Chen <yingjoe.chen@mediatek.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Link: http://lkml.kernel.org/r/1416061447-9472-4-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irqdomain.h | 24 ++++++--------
 kernel/irq/irqdomain.c    | 82 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 7aca1ad..dd2709b 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -134,6 +134,9 @@ enum {
 	/* Irq domain is hierarchical */
 	IRQ_DOMAIN_FLAG_HIERARCHY	= (1 << 0),
 
+	/* Core calls alloc/free recursive through the domain hierarchy. */
+	IRQ_DOMAIN_FLAG_AUTO_RECURSIVE	= (1 << 1),
+
 	/*
 	 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
 	 * for implementation specific purposes and ignored by the
@@ -285,22 +288,13 @@ extern void irq_domain_free_irqs_common(struct irq_domain *domain,
 extern void irq_domain_free_irqs_top(struct irq_domain *domain,
 				     unsigned int virq, unsigned int nr_irqs);
 
-static inline int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
-					       unsigned int irq_base,
-					       unsigned int nr_irqs, void *arg)
-{
-	if (domain->parent && domain->parent->ops->alloc)
-		return domain->parent->ops->alloc(domain->parent, irq_base,
-						  nr_irqs, arg);
-	return -ENOSYS;
-}
+extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
+					unsigned int irq_base,
+					unsigned int nr_irqs, void *arg);
 
-static inline void irq_domain_free_irqs_parent(struct irq_domain *domain,
-				unsigned int irq_base, unsigned int nr_irqs)
-{
-	if (domain->parent && domain->parent->ops->free)
-		domain->parent->ops->free(domain->parent, irq_base, nr_irqs);
-}
+extern void irq_domain_free_irqs_parent(struct irq_domain *domain,
+					unsigned int irq_base,
+					unsigned int nr_irqs);
 
 static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
 {
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 4e62832..9c88db7 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -960,6 +960,43 @@ void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq,
 	irq_domain_free_irqs_common(domain, virq, nr_irqs);
 }
 
+static bool irq_domain_is_auto_recursive(struct irq_domain *domain)
+{
+	return domain->flags & IRQ_DOMAIN_FLAG_AUTO_RECURSIVE;
+}
+
+static void irq_domain_free_irqs_recursive(struct irq_domain *domain,
+					   unsigned int irq_base,
+					   unsigned int nr_irqs)
+{
+	domain->ops->free(domain, irq_base, nr_irqs);
+	if (irq_domain_is_auto_recursive(domain)) {
+		BUG_ON(!domain->parent);
+		irq_domain_free_irqs_recursive(domain->parent, irq_base,
+					       nr_irqs);
+	}
+}
+
+static int irq_domain_alloc_irqs_recursive(struct irq_domain *domain,
+					   unsigned int irq_base,
+					   unsigned int nr_irqs, void *arg)
+{
+	int ret = 0;
+	struct irq_domain *parent = domain->parent;
+	bool recursive = irq_domain_is_auto_recursive(domain);
+
+	BUG_ON(recursive && !parent);
+	if (recursive)
+		ret = irq_domain_alloc_irqs_recursive(parent, irq_base,
+						      nr_irqs, arg);
+	if (ret >= 0)
+		ret = domain->ops->alloc(domain, irq_base, nr_irqs, arg);
+	if (ret < 0 && recursive)
+		irq_domain_free_irqs_recursive(parent, irq_base, nr_irqs);
+
+	return ret;
+}
+
 /**
  * __irq_domain_alloc_irqs - Allocate IRQs from domain
  * @domain:	domain to allocate from
@@ -1016,7 +1053,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
 	}
 
 	mutex_lock(&irq_domain_mutex);
-	ret = domain->ops->alloc(domain, virq, nr_irqs, arg);
+	ret = irq_domain_alloc_irqs_recursive(domain, virq, nr_irqs, arg);
 	if (ret < 0) {
 		mutex_unlock(&irq_domain_mutex);
 		goto out_free_irq_data;
@@ -1051,7 +1088,7 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)
 	mutex_lock(&irq_domain_mutex);
 	for (i = 0; i < nr_irqs; i++)
 		irq_domain_remove_irq(virq + i);
-	data->domain->ops->free(data->domain, virq, nr_irqs);
+	irq_domain_free_irqs_recursive(data->domain, virq, nr_irqs);
 	mutex_unlock(&irq_domain_mutex);
 
 	irq_domain_free_irq_data(virq, nr_irqs);
@@ -1059,6 +1096,47 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)
 }
 
 /**
+ * irq_domain_alloc_irqs_parent - Allocate interrupts from parent domain
+ * @irq_base:	Base IRQ number
+ * @nr_irqs:	Number of IRQs to allocate
+ * @arg:	Allocation data (arch/domain specific)
+ *
+ * Check whether the domain has been setup recursive. If not allocate
+ * through the parent domain.
+ */
+int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
+				 unsigned int irq_base, unsigned int nr_irqs,
+				 void *arg)
+{
+	/* irq_domain_alloc_irqs_recursive() has called parent's alloc() */
+	if (irq_domain_is_auto_recursive(domain))
+		return 0;
+
+	domain = domain->parent;
+	if (domain)
+		return irq_domain_alloc_irqs_recursive(domain, irq_base,
+						       nr_irqs, arg);
+	return -ENOSYS;
+}
+
+/**
+ * irq_domain_free_irqs_parent - Free interrupts from parent domain
+ * @irq_base:	Base IRQ number
+ * @nr_irqs:	Number of IRQs to free
+ *
+ * Check whether the domain has been setup recursive. If not free
+ * through the parent domain.
+ */
+void irq_domain_free_irqs_parent(struct irq_domain *domain,
+				 unsigned int irq_base, unsigned int nr_irqs)
+{
+	/* irq_domain_free_irqs_recursive() will call parent's free */
+	if (!irq_domain_is_auto_recursive(domain) && domain->parent)
+		irq_domain_free_irqs_recursive(domain->parent, irq_base,
+					       nr_irqs);
+}
+
+/**
  * irq_domain_activate_irq - Call domain_ops->activate recursively to activate
  *			     interrupt
  * @irq_data:	outermost irq_data associated with interrupt

  reply	other threads:[~2014-11-24 20:27 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-15 14:23 [Patch V2 0/9] Refine generic/PCI MSI irqodmian interfaces Jiang Liu
2014-11-15 14:23 ` Jiang Liu
2014-11-15 14:23 ` [Patch V2 1/9] PCI, MSI: Fix errors caused by commit e5f1a59c4e12 Jiang Liu
2014-11-15 14:23   ` Jiang Liu
2014-11-15 14:24 ` [Patch V2 2/9] irqdomain: Use consistent prototype for irq_domain_free_irqs_* Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-15 14:24 ` [Patch V2 3/9] irqdomain: Implement a method to automatically call parent domain's alloc/free Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:11   ` tip-bot for Jiang Liu [this message]
2014-11-15 14:24 ` [Patch V2 4/9] irqdomain: Introduce helper function irq_domain_add_hierarchy() Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:11   ` [tip:irq/irqdomain] " tip-bot for Jiang Liu
2014-11-29 12:53     ` Borislav Petkov
2014-11-29 14:29       ` Jiang Liu
2014-11-29 14:56         ` Borislav Petkov
2014-11-29 15:21           ` Jiang Liu
2014-11-29 15:37             ` Borislav Petkov
2014-11-29 20:42       ` Thomas Gleixner
2014-11-30 12:37         ` [PATCH] irqdomain: Correct early allocation of irq domains with IRQs off Borislav Petkov
2014-11-30 12:37           ` Borislav Petkov
2014-12-01  9:45           ` [tip:x86/apic] " tip-bot for Borislav Petkov
2014-12-01  2:20         ` [tip:irq/irqdomain] irqdomain: Introduce helper function irq_domain_add_hierarchy() Jiang Liu
2014-11-15 14:24 ` [Patch V2 5/9] PCI, MSI: Introduce helpers to hide struct msi_desc implementation details Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:08   ` [tip:irq/irqdomain] PCI/MSI: " tip-bot for Jiang Liu
2014-11-15 14:24 ` [Patch V2 6/9] genirq: Introduce msi_domain_{alloc|free}_irqs() Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:13   ` [tip:irq/irqdomain] genirq: Introduce msi_domain_alloc/free_irqs( ) tip-bot for Jiang Liu
2014-11-15 14:24 ` [Patch V2 7/9] genirq: Provide default callbacks for msi_domain_ops Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:13   ` [tip:irq/irqdomain] " tip-bot for Jiang Liu
2014-11-15 14:24 ` [Patch V2 8/9] PCI, MSI: Refine irqdomain interfaces to simplify its usage Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-15 14:24 ` [Patch V2 9/9] PCI, MSI: Provide mechanism to alloc/free MSI/MSIX interrupt from irqdomain Jiang Liu
2014-11-15 14:24   ` Jiang Liu
2014-11-23 18:14   ` [tip:irq/irqdomain] PCI/MSI: Provide mechanism to alloc/free MSI/ MSIX " tip-bot for Jiang Liu

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=tip-36d727310cb9f85efb5ac089ffb1797e7c3538e1@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=benh@kernel.crashing.org \
    --cc=bhelgaas@google.com \
    --cc=bp@alien8.de \
    --cc=grant.likely@linaro.org \
    --cc=hpa@zytor.com \
    --cc=jiang.liu@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=matthias.bgg@gmail.com \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --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.