cregit-Linux how code gets into the kernel

Release 4.8 arch/microblaze/kernel/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/of_address.h>
#include <linux/io.h>
#include <linux/bug.h>


static void __iomem *intc_baseaddr;

/* 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 unsigned int (*read_fn)(void __iomem *);

static void (*write_fn)(u32, void __iomem *);


static void intc_write32(u32 val, void __iomem *addr) { iowrite32(val, addr); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek21100.00%1100.00%
Total21100.00%1100.00%


static unsigned int intc_read32(void __iomem *addr) { return ioread32(addr); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek18100.00%1100.00%
Total18100.00%1100.00%


static void intc_write32_be(u32 val, void __iomem *addr) { iowrite32be(val, addr); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek21100.00%1100.00%
Total21100.00%1100.00%


static unsigned int intc_read32_be(void __iomem *addr) { return ioread32be(addr); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek18100.00%1100.00%
Total18100.00%1100.00%


static void intc_enable_or_unmask(struct irq_data *d) { unsigned long mask = 1 << d->hwirq; pr_debug("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)) write_fn(mask, intc_baseaddr + IAR); write_fn(mask, intc_baseaddr + SIE); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek3053.57%562.50%
steven j. magnanisteven j. magnani1425.00%112.50%
thomas gleixnerthomas gleixner1221.43%225.00%
Total56100.00%8100.00%


static void intc_disable_or_mask(struct irq_data *d) { pr_debug("disable: %ld\n", d->hwirq); write_fn(1 << d->hwirq, intc_baseaddr + CIE); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek2575.76%375.00%
thomas gleixnerthomas gleixner824.24%125.00%
Total33100.00%4100.00%


static void intc_ack(struct irq_data *d) { pr_debug("ack: %ld\n", d->hwirq); write_fn(1 << d->hwirq, intc_baseaddr + IAR); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek2575.76%375.00%
thomas gleixnerthomas gleixner824.24%125.00%
Total33100.00%4100.00%


static void intc_mask_ack(struct irq_data *d) { unsigned long mask = 1 << d->hwirq; pr_debug("disable_and_ack: %ld\n", d->hwirq); write_fn(mask, intc_baseaddr + CIE); write_fn(mask, intc_baseaddr + IAR); }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek4083.33%480.00%
thomas gleixnerthomas gleixner816.67%120.00%
Total48100.00%5100.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, }; static struct irq_domain *root_domain;
unsigned int get_irq(void) { unsigned int hwirq, irq = -1; hwirq = read_fn(intc_baseaddr + IVR); if (hwirq != -1U) irq = irq_find_mapping(root_domain, hwirq); pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq); return irq; }

Contributors

PersonTokensPropCommitsCommitProp
grant likelygrant likely2750.00%125.00%
michal simekmichal simek2750.00%375.00%
Total54100.00%4100.00%


static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { u32 intr_mask = (u32)d->host_data; if (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

PersonTokensPropCommitsCommitProp
grant likelygrant likely8398.81%150.00%
michal simekmichal simek11.19%150.00%
Total84100.00%2100.00%

static const struct irq_domain_ops xintc_irq_domain_ops = { .xlate = irq_domain_xlate_onetwocell, .map = xintc_map, };
static int __init xilinx_intc_of_init(struct device_node *intc, struct device_node *parent) { u32 nr_irq, intr_mask; int ret; intc_baseaddr = of_iomap(intc, 0); BUG_ON(!intc_baseaddr); ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq); if (ret < 0) { pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__); return ret; } ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask); if (ret < 0) { pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__); return ret; } if (intr_mask >> nr_irq) pr_warn("%s: mismatch in kind-of-intr param\n", __func__); pr_info("%s: num_irq=%d, edge=0x%x\n", intc->full_name, nr_irq, intr_mask); write_fn = intc_write32; read_fn = intc_read32; /* * Disable all external interrupts until they are * explicity requested. */ write_fn(0, intc_baseaddr + IER); /* Acknowledge any pending interrupts just in case. */ write_fn(0xffffffff, intc_baseaddr + IAR); /* Turn on the Master Enable. */ write_fn(MER_HIE | MER_ME, intc_baseaddr + MER); if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) { write_fn = intc_write32_be; read_fn = intc_read32_be; write_fn(MER_HIE | MER_ME, intc_baseaddr + MER); } /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm * lazy and Michal can clean it up to something nicer when he tests * and commits this patch. ~~gcl */ root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops, (void *)intr_mask); irq_set_default_host(root_domain); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek20688.79%1062.50%
grant likelygrant likely125.17%16.25%
soren brinkmannsoren brinkmann73.02%318.75%
dan christensendan christensen52.16%16.25%
thomas gleixnerthomas gleixner20.86%16.25%
Total232100.00%16100.00%

IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
michal simekmichal simek56171.56%1458.33%
grant likelygrant likely14919.01%14.17%
thomas gleixnerthomas gleixner425.36%28.33%
steven j. magnanisteven j. magnani141.79%14.17%
soren brinkmannsoren brinkmann70.89%312.50%
dan christensendan christensen50.64%14.17%
joel porquetjoel porquet40.51%14.17%
john a. williamsjohn a. williams20.26%14.17%
Total784100.00%24100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.