From: Grant Likely <grant.likely@linaro.org>
To: linux-kernel@vger.kernel.org, tglx@linutronix.de
Cc: Grant Likely <grant.likely@linaro.org>,
Russell King <linux@arm.linux.org.uk>,
Linus Walleij <linus.walleij@linaro.org>
Subject: [PATCH 3/3] irqchip: Make versatile fpga irq driver a generic chip
Date: Wed, 29 May 2013 03:10:54 +0100 [thread overview]
Message-ID: <1369793454-19197-4-git-send-email-grant.likely@linaro.org> (raw)
In-Reply-To: <1369793454-19197-1-git-send-email-grant.likely@linaro.org>
This is an RFC patch to convert the versatile FPGA irq controller driver
to use generic irq chip. It builds on the series that extends the
generic chip code to allow a linear irq domain to contain one or more
generic irq chips so that each interrupt controller doesn't need to hand
code the generic chip setup.
I've written this as a proof of concept to see if the new generic irq
code does what it needs to. I had to extend it slightly to properly
handle the valid mask used by the versatile FPGA driver.
Tested on QEMU, but not on real hardware.
Signed-off-by: Grant Likely <grant.likely@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/Kconfig | 1 +
drivers/irqchip/irq-versatile-fpga.c | 104 +++++++++++++----------------------
2 files changed, 39 insertions(+), 66 deletions(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 4a33351..8765502 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -14,6 +14,7 @@ config ARM_VIC
bool
select IRQ_DOMAIN
select MULTI_IRQ_HANDLER
+ select GENERIC_IRQ_CHIP
config ARM_VIC_NR
int
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 065b7a3..8c7097b 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -34,37 +34,18 @@
* @used_irqs: number of active IRQs on this controller
*/
struct fpga_irq_data {
- void __iomem *base;
- struct irq_chip chip;
- u32 valid;
struct irq_domain *domain;
- u8 used_irqs;
};
/* we cannot allocate memory when the controllers are initially registered */
static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR];
static int fpga_irq_id;
-static void fpga_irq_mask(struct irq_data *d)
-{
- struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << d->hwirq;
-
- writel(mask, f->base + IRQ_ENABLE_CLEAR);
-}
-
-static void fpga_irq_unmask(struct irq_data *d)
-{
- struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << d->hwirq;
-
- writel(mask, f->base + IRQ_ENABLE_SET);
-}
-
static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
{
- struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
- u32 status = readl(f->base + IRQ_STATUS);
+ struct irq_domain *domain = irq_desc_get_handler_data(desc);
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
+ u32 status = readl(gc->reg_base + IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(irq, desc);
@@ -74,7 +55,7 @@ static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
do {
irq = ffs(status) - 1;
status &= ~(1 << irq);
- generic_handle_irq(irq_find_mapping(f->domain, irq));
+ generic_handle_irq(irq_find_mapping(domain, irq));
} while (status);
}
@@ -85,11 +66,12 @@ static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
*/
static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
{
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(f->domain, 0);
int handled = 0;
int irq;
u32 status;
- while ((status = readl(f->base + IRQ_STATUS))) {
+ while ((status = readl(gc->reg_base + IRQ_STATUS))) {
irq = ffs(status) - 1;
handle_IRQ(irq_find_mapping(f->domain, irq), regs);
handled = 1;
@@ -112,63 +94,53 @@ asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
} while (handled);
}
-static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
-{
- struct fpga_irq_data *f = d->host_data;
-
- /* Skip invalid IRQs, only register handlers for the real ones */
- if (!(f->valid & BIT(hwirq)))
- return -ENOTSUPP;
- irq_set_chip_data(irq, f);
- irq_set_chip_and_handler(irq, &f->chip,
- handle_level_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- return 0;
-}
-
-static struct irq_domain_ops fpga_irqdomain_ops = {
- .map = fpga_irqdomain_map,
- .xlate = irq_domain_xlate_onetwocell,
-};
-
void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
int parent_irq, u32 valid, struct device_node *node)
{
+ struct irq_chip_generic *gc;
struct fpga_irq_data *f;
- int i;
+ int ret;
if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_VERSATILE_FPGA_IRQ_NR\n", __func__);
return;
}
f = &fpga_irq_devices[fpga_irq_id];
- f->base = base;
- f->chip.name = name;
- f->chip.irq_ack = fpga_irq_mask;
- f->chip.irq_mask = fpga_irq_mask;
- f->chip.irq_unmask = fpga_irq_unmask;
- f->valid = valid;
+
+ /* This will also allocate irq descriptors */
+ f->domain = irq_domain_add_linear(node, fls(valid),
+ &irq_generic_chip_ops, f);
+ if (!f->domain) {
+ pr_err("FPGA IRQ setup failed allocation domain\n");
+ return;
+ }
+
+ ret = irq_alloc_domain_generic_chips(f->domain, fls(valid), 1,
+ name, handle_level_irq,
+ IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0, 0);
+ if (ret) {
+ pr_err("FPGA IRQ setup failed allocating generic chip\n");
+ return;
+ }
+
+ gc = irq_get_domain_generic_chip(f->domain, 0);
+ gc->reg_base = base;
+ gc->unused = ~valid;
+ gc->chip_types[0].regs.enable = IRQ_ENABLE_SET;
+ gc->chip_types[0].regs.disable = IRQ_ENABLE_CLEAR;
+ gc->chip_types[0].chip.irq_ack = irq_gc_mask_disable_reg;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
if (parent_irq != -1) {
- irq_set_handler_data(parent_irq, f);
+ irq_set_handler_data(parent_irq, f->domain);
irq_set_chained_handler(parent_irq, fpga_irq_handle);
}
- /* This will also allocate irq descriptors */
- f->domain = irq_domain_add_simple(node, fls(valid), irq_start,
- &fpga_irqdomain_ops, f);
-
- /* This will allocate all valid descriptors in the linear case */
- for (i = 0; i < fls(valid); i++)
- if (valid & BIT(i)) {
- if (!irq_start)
- irq_create_mapping(f->domain, i);
- f->used_irqs++;
- }
-
- pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
- fpga_irq_id, name, base, f->used_irqs);
+ if (irq_start)
+ irq_domain_associate_many(f->domain, irq_start, 0, fls(valid));
+
+ pr_info("FPGA IRQ chip %d \"%s\" @ %p\n", fpga_irq_id, name, base);
fpga_irq_id++;
}
--
1.8.1.2
next prev parent reply other threads:[~2013-05-29 2:11 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-29 2:10 [PATCH 0/3] Try out the irqdomain + generic chip integration series Grant Likely
2013-05-29 2:10 ` [PATCH 1/3] irqchip: Add mask to block out invalid irqs Grant Likely
2013-05-29 9:23 ` [tip:irq/core] genirq: " tip-bot for Grant Likely
2013-05-29 2:10 ` [PATCH 2/3] irqdomain: Relax failure path on setting up mappings Grant Likely
2013-05-29 2:10 ` Grant Likely [this message]
2013-05-29 17:55 ` [PATCH 3/3] irqchip: Make versatile fpga irq driver a generic chip Linus Walleij
2013-05-29 19:56 ` Grant Likely
2013-05-30 21:06 ` Linus Walleij
2013-05-29 8:19 ` [PATCH 0/3] Try out the irqdomain + generic chip integration series Thomas Gleixner
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=1369793454-19197-4-git-send-email-grant.likely@linaro.org \
--to=grant.likely@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®