cregit-Linux how code gets into the kernel

Release 4.14 arch/powerpc/platforms/85xx/socrates_fpga_pic.c

/*
 *  Copyright (C) 2008 Ilya Yanok, Emcraft Systems
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/irq.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/io.h>

/*
 * The FPGA supports 9 interrupt sources, which can be routed to 3
 * interrupt request lines of the MPIC. The line to be used can be
 * specified through the third cell of FDT property  "interrupts".
 */


#define SOCRATES_FPGA_NUM_IRQS	9


#define FPGA_PIC_IRQCFG		(0x0)

#define FPGA_PIC_IRQMASK(n)	(0x4 + 0x4 * (n))


#define SOCRATES_FPGA_IRQ_MASK	((1 << SOCRATES_FPGA_NUM_IRQS) - 1)


struct socrates_fpga_irq_info {
	
unsigned int irq_line;
	
int type;
};

/*
 * Interrupt routing and type table
 *
 * IRQ_TYPE_NONE means the interrupt type is configurable,
 * otherwise it's fixed to the specified value.
 */

static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
	[0] = {0, IRQ_TYPE_NONE},
	[1] = {0, IRQ_TYPE_LEVEL_HIGH},
	[2] = {0, IRQ_TYPE_LEVEL_LOW},
	[3] = {0, IRQ_TYPE_NONE},
	[4] = {0, IRQ_TYPE_NONE},
	[5] = {0, IRQ_TYPE_NONE},
	[6] = {0, IRQ_TYPE_NONE},
	[7] = {0, IRQ_TYPE_NONE},
	[8] = {0, IRQ_TYPE_LEVEL_HIGH},
};

static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);


static void __iomem *socrates_fpga_pic_iobase;

static struct irq_domain *socrates_fpga_pic_irq_host;

static unsigned int socrates_fpga_irqs[3];


static inline uint32_t socrates_fpga_pic_read(int reg) { return in_be32(socrates_fpga_pic_iobase + reg); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger18100.00%1100.00%
Total18100.00%1100.00%


static inline void socrates_fpga_pic_write(int reg, uint32_t val) { out_be32(socrates_fpga_pic_iobase + reg, val); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger22100.00%1100.00%
Total22100.00%1100.00%


static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) { uint32_t cause; unsigned long flags; int i; /* Check irq line routed to the MPIC */ for (i = 0; i < 3; i++) { if (irq == socrates_fpga_irqs[i]) break; } if (i == 3) return 0; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) { if (cause >> (i + 16)) break; } return irq_linear_revmap(socrates_fpga_pic_irq_host, (irq_hw_number_t)i); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger11997.54%133.33%
Anton Vorontsov21.64%133.33%
Michael Ellerman10.82%133.33%
Total122100.00%3100.00%


static void socrates_fpga_pic_cascade(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int irq = irq_desc_get_irq(desc); unsigned int cascade_irq; /* * See if we actually have an interrupt, call generic handling code if * we do. */ cascade_irq = socrates_fpga_pic_get_irq(irq); if (cascade_irq) generic_handle_irq(cascade_irq); chip->irq_eoi(&desc->irq_data); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger3659.02%120.00%
Lennert Buytenhek1422.95%120.00%
Thomas Gleixner1118.03%360.00%
Total61100.00%5100.00%


static void socrates_fpga_pic_ack(struct irq_data *d) { unsigned long flags; unsigned int irq_line, hwirq = irqd_to_hwirq(d); uint32_t mask; irq_line = fpga_irqs[hwirq].irq_line; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger7484.09%125.00%
Grant C. Likely77.95%125.00%
Lennert Buytenhek55.68%125.00%
Anton Vorontsov22.27%125.00%
Total88100.00%4100.00%


static void socrates_fpga_pic_mask(struct irq_data *d) { unsigned long flags; unsigned int hwirq = irqd_to_hwirq(d); int irq_line; u32 mask; irq_line = fpga_irqs[hwirq].irq_line; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask &= ~(1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger7587.21%125.00%
Grant C. Likely55.81%125.00%
Lennert Buytenhek44.65%125.00%
Anton Vorontsov22.33%125.00%
Total86100.00%4100.00%


static void socrates_fpga_pic_mask_ack(struct irq_data *d) { unsigned long flags; unsigned int hwirq = irqd_to_hwirq(d); int irq_line; u32 mask; irq_line = fpga_irqs[hwirq].irq_line; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask &= ~(1 << hwirq); mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger8788.78%125.00%
Grant C. Likely55.10%125.00%
Lennert Buytenhek44.08%125.00%
Anton Vorontsov22.04%125.00%
Total98100.00%4100.00%


static void socrates_fpga_pic_unmask(struct irq_data *d) { unsigned long flags; unsigned int hwirq = irqd_to_hwirq(d); int irq_line; u32 mask; irq_line = fpga_irqs[hwirq].irq_line; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger7487.06%125.00%
Grant C. Likely55.88%125.00%
Lennert Buytenhek44.71%125.00%
Anton Vorontsov22.35%125.00%
Total85100.00%4100.00%


static void socrates_fpga_pic_eoi(struct irq_data *d) { unsigned long flags; unsigned int hwirq = irqd_to_hwirq(d); int irq_line; u32 mask; irq_line = fpga_irqs[hwirq].irq_line; raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger7887.64%125.00%
Grant C. Likely55.62%125.00%
Lennert Buytenhek44.49%125.00%
Anton Vorontsov22.25%125.00%
Total89100.00%4100.00%


static int socrates_fpga_pic_set_type(struct irq_data *d, unsigned int flow_type) { unsigned long flags; unsigned int hwirq = irqd_to_hwirq(d); int polarity; u32 mask; if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE) return -EINVAL; switch (flow_type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_LEVEL_HIGH: polarity = 1; break; case IRQ_TYPE_LEVEL_LOW: polarity = 0; break; default: return -EINVAL; } raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG); if (polarity) mask |= (1 << hwirq); else mask &= ~(1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger12291.73%125.00%
Grant C. Likely53.76%125.00%
Lennert Buytenhek43.01%125.00%
Anton Vorontsov21.50%125.00%
Total133100.00%4100.00%

static struct irq_chip socrates_fpga_pic_chip = { .name = "FPGA-PIC", .irq_ack = socrates_fpga_pic_ack, .irq_mask = socrates_fpga_pic_mask, .irq_mask_ack = socrates_fpga_pic_mask_ack, .irq_unmask = socrates_fpga_pic_unmask, .irq_eoi = socrates_fpga_pic_eoi, .irq_set_type = socrates_fpga_pic_set_type, };
static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &socrates_fpga_pic_chip, handle_fasteoi_irq); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger3487.18%125.00%
Thomas Gleixner410.26%250.00%
Grant C. Likely12.56%125.00%
Total39100.00%4100.00%


static int socrates_fpga_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]]; *out_hwirq = intspec[0]; if (fpga_irq->type == IRQ_TYPE_NONE) { /* type is configurable */ if (intspec[1] != IRQ_TYPE_LEVEL_LOW && intspec[1] != IRQ_TYPE_LEVEL_HIGH) { pr_warning("FPGA PIC: invalid irq type, " "setting default active low\n"); *out_flags = IRQ_TYPE_LEVEL_LOW; } else { *out_flags = intspec[1]; } } else { /* type is fixed */ *out_flags = fpga_irq->type; } /* Use specified interrupt routing */ if (intspec[2] <= 2) fpga_irq->irq_line = intspec[2]; else pr_warning("FPGA PIC: invalid irq routing\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger14498.63%133.33%
Grant C. Likely10.68%133.33%
Roman Fietze10.68%133.33%
Total146100.00%3100.00%

static const struct irq_domain_ops socrates_fpga_pic_host_ops = { .map = socrates_fpga_pic_host_map, .xlate = socrates_fpga_pic_host_xlate, };
void socrates_fpga_pic_init(struct device_node *pic) { unsigned long flags; int i; /* Setup an irq_domain structure */ socrates_fpga_pic_irq_host = irq_domain_add_linear(pic, SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL); if (socrates_fpga_pic_irq_host == NULL) { pr_err("FPGA PIC: Unable to allocate host\n"); return; } for (i = 0; i < 3; i++) { socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i); if (!socrates_fpga_irqs[i]) { pr_warning("FPGA PIC: can't get irq%d.\n", i); continue; } irq_set_chained_handler(socrates_fpga_irqs[i], socrates_fpga_pic_cascade); } socrates_fpga_pic_iobase = of_iomap(pic, 0); raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0), SOCRATES_FPGA_IRQ_MASK << 16); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1), SOCRATES_FPGA_IRQ_MASK << 16); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2), SOCRATES_FPGA_IRQ_MASK << 16); raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n"); }

Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger16095.81%116.67%
Grant C. Likely31.80%233.33%
Anton Vorontsov21.20%116.67%
Michael Ellerman10.60%116.67%
Thomas Gleixner10.60%116.67%
Total167100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Wolfgang Grandegger126090.71%16.25%
Lennert Buytenhek453.24%16.25%
Grant C. Likely402.88%425.00%
Anton Vorontsov171.22%16.25%
Thomas Gleixner171.22%531.25%
Rob Herring60.43%16.25%
Michael Ellerman20.14%16.25%
Anton Blanchard10.07%16.25%
Roman Fietze10.07%16.25%
Total1389100.00%16100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.