Release 4.12 drivers/irqchip/irq-xilinx-intc.c
  
  
  
/*
 * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2012-2013 Xilinx, Inc.
 * Copyright (C) 2007-2009 PetaLogix
 * Copyright (C) 2006 Atmark Techno, Inc.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/jump_label.h>
#include <linux/bug.h>
#include <linux/of_irq.h>
/* No one else should require these constants, so define them locally here. */
#define ISR 0x00			
/* Interrupt Status Register */
#define IPR 0x04			
/* Interrupt Pending Register */
#define IER 0x08			
/* Interrupt Enable Register */
#define IAR 0x0c			
/* Interrupt Acknowledge Register */
#define SIE 0x10			
/* Set Interrupt Enable bits */
#define CIE 0x14			
/* Clear Interrupt Enable bits */
#define IVR 0x18			
/* Interrupt Vector Register */
#define MER 0x1c			
/* Master Enable Register */
#define MER_ME (1<<0)
#define MER_HIE (1<<1)
static DEFINE_STATIC_KEY_FALSE(xintc_is_be);
struct xintc_irq_chip {
	
void		__iomem *base;
	
struct		irq_domain *root_domain;
	
u32		intr_mask;
};
static struct xintc_irq_chip *xintc_irqc;
static void xintc_write(int reg, u32 data)
{
	if (static_branch_unlikely(&xintc_is_be))
		iowrite32be(data, xintc_irqc->base + reg);
	else
		iowrite32(data, xintc_irqc->base + reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Zubair Lutfullah Kakakhel | 31 | 72.09% | 1 | 50.00% | 
| Michal Simek | 12 | 27.91% | 1 | 50.00% | 
| Total | 43 | 100.00% | 2 | 100.00% | 
static unsigned int xintc_read(int reg)
{
	if (static_branch_unlikely(&xintc_is_be))
		return ioread32be(xintc_irqc->base + reg);
	else
		return ioread32(xintc_irqc->base + reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Zubair Lutfullah Kakakhel | 27 | 69.23% | 1 | 50.00% | 
| Michal Simek | 12 | 30.77% | 1 | 50.00% | 
| Total | 39 | 100.00% | 2 | 100.00% | 
static void intc_enable_or_unmask(struct irq_data *d)
{
	unsigned long mask = 1 << d->hwirq;
	pr_debug("irq-xilinx: enable_or_unmask: %ld\n", d->hwirq);
	/* ack level irqs because they can't be acked during
         * ack function since the handle_level_irq function
         * acks the irq before calling the interrupt handler
         */
	if (irqd_is_level_type(d))
		xintc_write(IAR, mask);
	xintc_write(SIE, mask);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Michal Simek | 20 | 38.46% | 3 | 37.50% | 
| Steven J. Magnani | 13 | 25.00% | 1 | 12.50% | 
| Thomas Gleixner | 12 | 23.08% | 2 | 25.00% | 
| Zubair Lutfullah Kakakhel | 7 | 13.46% | 2 | 25.00% | 
| Total | 52 | 100.00% | 8 | 100.00% | 
static void intc_disable_or_mask(struct irq_data *d)
{
	pr_debug("irq-xilinx: disable: %ld\n", d->hwirq);
	xintc_write(CIE, 1 << d->hwirq);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Michal Simek | 19 | 61.29% | 2 | 40.00% | 
| Thomas Gleixner | 8 | 25.81% | 1 | 20.00% | 
| Zubair Lutfullah Kakakhel | 4 | 12.90% | 2 | 40.00% | 
| Total | 31 | 100.00% | 5 | 100.00% | 
static void intc_ack(struct irq_data *d)
{
	pr_debug("irq-xilinx: ack: %ld\n", d->hwirq);
	xintc_write(IAR, 1 << d->hwirq);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Michal Simek | 19 | 61.29% | 2 | 40.00% | 
| Thomas Gleixner | 8 | 25.81% | 1 | 20.00% | 
| Zubair Lutfullah Kakakhel | 4 | 12.90% | 2 | 40.00% | 
| Total | 31 | 100.00% | 5 | 100.00% | 
static void intc_mask_ack(struct irq_data *d)
{
	unsigned long mask = 1 << d->hwirq;
	pr_debug("irq-xilinx: disable_and_ack: %ld\n", d->hwirq);
	xintc_write(CIE, mask);
	xintc_write(IAR, mask);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Michal Simek | 29 | 65.91% | 2 | 40.00% | 
| Thomas Gleixner | 8 | 18.18% | 1 | 20.00% | 
| Zubair Lutfullah Kakakhel | 7 | 15.91% | 2 | 40.00% | 
| Total | 44 | 100.00% | 5 | 100.00% | 
static struct irq_chip intc_dev = {
	.name = "Xilinx INTC",
	.irq_unmask = intc_enable_or_unmask,
	.irq_mask = intc_disable_or_mask,
	.irq_ack = intc_ack,
	.irq_mask_ack = intc_mask_ack,
};
unsigned int xintc_get_irq(void)
{
	unsigned int hwirq, irq = -1;
	hwirq = xintc_read(IVR);
	if (hwirq != -1U)
		irq = irq_find_mapping(xintc_irqc->root_domain, hwirq);
	pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
	return irq;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grant C. Likely | 26 | 48.15% | 1 | 20.00% | 
| Michal Simek | 23 | 42.59% | 1 | 20.00% | 
| Zubair Lutfullah Kakakhel | 5 | 9.26% | 3 | 60.00% | 
| Total | 54 | 100.00% | 5 | 100.00% | 
static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
	if (xintc_irqc->intr_mask & (1 << hw)) {
		irq_set_chip_and_handler_name(irq, &intc_dev,
						handle_edge_irq, "edge");
		irq_clear_status_flags(irq, IRQ_LEVEL);
	} else {
		irq_set_chip_and_handler_name(irq, &intc_dev,
						handle_level_irq, "level");
		irq_set_status_flags(irq, IRQ_LEVEL);
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grant C. Likely | 73 | 96.05% | 1 | 33.33% | 
| Zubair Lutfullah Kakakhel | 2 | 2.63% | 1 | 33.33% | 
| Michal Simek | 1 | 1.32% | 1 | 33.33% | 
| Total | 76 | 100.00% | 3 | 100.00% | 
static const struct irq_domain_ops xintc_irq_domain_ops = {
	.xlate = irq_domain_xlate_onetwocell,
	.map = xintc_map,
};
static void xil_intc_irq_handler(struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	u32 pending;
	chained_irq_enter(chip, desc);
	do {
		pending = xintc_get_irq();
		if (pending == -1U)
			break;
		generic_handle_irq(pending);
	} while (true);
	chained_irq_exit(chip, desc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Zubair Lutfullah Kakakhel | 64 | 100.00% | 1 | 100.00% | 
| Total | 64 | 100.00% | 1 | 100.00% | 
static int __init xilinx_intc_of_init(struct device_node *intc,
					     struct device_node *parent)
{
	u32 nr_irq;
	int ret, irq;
	struct xintc_irq_chip *irqc;
	if (xintc_irqc) {
		pr_err("irq-xilinx: Multiple instances aren't supported\n");
		return -EINVAL;
	}
	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
	if (!irqc)
		return -ENOMEM;
	xintc_irqc = irqc;
	irqc->base = of_iomap(intc, 0);
	BUG_ON(!irqc->base);
	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
	if (ret < 0) {
		pr_err("irq-xilinx: unable to read xlnx,num-intr-inputs\n");
		goto err_alloc;
	}
	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
	if (ret < 0) {
		pr_warn("irq-xilinx: unable to read xlnx,kind-of-intr\n");
		irqc->intr_mask = 0;
	}
	if (irqc->intr_mask >> nr_irq)
		pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
	pr_info("irq-xilinx: %s: num_irq=%d, edge=0x%x\n",
		intc->full_name, nr_irq, irqc->intr_mask);
	/*
         * Disable all external interrupts until they are
         * explicity requested.
         */
	xintc_write(IER, 0);
	/* Acknowledge any pending interrupts just in case. */
	xintc_write(IAR, 0xffffffff);
	/* Turn on the Master Enable. */
	xintc_write(MER, MER_HIE | MER_ME);
	if (!(xintc_read(MER) & (MER_HIE | MER_ME))) {
		static_branch_enable(&xintc_is_be);
		xintc_write(MER, MER_HIE | MER_ME);
	}
	irqc->root_domain = irq_domain_add_linear(intc, nr_irq,
						  &xintc_irq_domain_ops, irqc);
	if (!irqc->root_domain) {
		pr_err("irq-xilinx: Unable to create IRQ domain\n");
		goto err_alloc;
	}
	if (parent) {
		irq = irq_of_parse_and_map(intc, 0);
		if (irq) {
			irq_set_chained_handler_and_data(irq,
							 xil_intc_irq_handler,
							 irqc);
		} else {
			pr_err("irq-xilinx: interrupts property not in DT\n");
			ret = -EINVAL;
			goto err_alloc;
		}
	} else {
		irq_set_default_host(irqc->root_domain);
	}
	return 0;
err_alloc:
	xintc_irqc = NULL;
	kfree(irqc);
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Zubair Lutfullah Kakakhel | 177 | 51.45% | 4 | 21.05% | 
| Michal Simek | 153 | 44.48% | 10 | 52.63% | 
| Grant C. Likely | 6 | 1.74% | 1 | 5.26% | 
| Dan Christensen | 5 | 1.45% | 1 | 5.26% | 
| Sören Brinkmann | 2 | 0.58% | 2 | 10.53% | 
| Thomas Gleixner | 1 | 0.29% | 1 | 5.26% | 
| Total | 344 | 100.00% | 19 | 100.00% | 
IRQCHIP_DECLARE(xilinx_intc_xps, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
IRQCHIP_DECLARE(xilinx_intc_opb, "xlnx,opb-intc-1.00.c", xilinx_intc_of_init);
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Michal Simek | 391 | 41.03% | 13 | 46.43% | 
| Zubair Lutfullah Kakakhel | 370 | 38.82% | 6 | 21.43% | 
| Grant C. Likely | 126 | 13.22% | 1 | 3.57% | 
| Thomas Gleixner | 41 | 4.30% | 2 | 7.14% | 
| Steven J. Magnani | 13 | 1.36% | 1 | 3.57% | 
| Dan Christensen | 5 | 0.52% | 1 | 3.57% | 
| Joël Porquet | 3 | 0.31% | 1 | 3.57% | 
| John A. Williams | 2 | 0.21% | 1 | 3.57% | 
| Sören Brinkmann | 2 | 0.21% | 2 | 7.14% | 
| Total | 953 | 100.00% | 28 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.