Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright 2015-2016 Vladimir Zapolskiy <vz@mleia.com>
0004  */
0005 
0006 #define pr_fmt(fmt) "%s: " fmt, __func__
0007 
0008 #include <linux/io.h>
0009 #include <linux/irqchip.h>
0010 #include <linux/irqchip/chained_irq.h>
0011 #include <linux/of_address.h>
0012 #include <linux/of_irq.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/seq_file.h>
0015 #include <linux/slab.h>
0016 #include <asm/exception.h>
0017 
0018 #define LPC32XX_INTC_MASK       0x00
0019 #define LPC32XX_INTC_RAW        0x04
0020 #define LPC32XX_INTC_STAT       0x08
0021 #define LPC32XX_INTC_POL        0x0C
0022 #define LPC32XX_INTC_TYPE       0x10
0023 #define LPC32XX_INTC_FIQ        0x14
0024 
0025 #define NR_LPC32XX_IC_IRQS      32
0026 
0027 struct lpc32xx_irq_chip {
0028     void __iomem *base;
0029     phys_addr_t addr;
0030     struct irq_domain *domain;
0031 };
0032 
0033 static struct lpc32xx_irq_chip *lpc32xx_mic_irqc;
0034 
0035 static inline u32 lpc32xx_ic_read(struct lpc32xx_irq_chip *ic, u32 reg)
0036 {
0037     return readl_relaxed(ic->base + reg);
0038 }
0039 
0040 static inline void lpc32xx_ic_write(struct lpc32xx_irq_chip *ic,
0041                     u32 reg, u32 val)
0042 {
0043     writel_relaxed(val, ic->base + reg);
0044 }
0045 
0046 static void lpc32xx_irq_mask(struct irq_data *d)
0047 {
0048     struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
0049     u32 val, mask = BIT(d->hwirq);
0050 
0051     val = lpc32xx_ic_read(ic, LPC32XX_INTC_MASK) & ~mask;
0052     lpc32xx_ic_write(ic, LPC32XX_INTC_MASK, val);
0053 }
0054 
0055 static void lpc32xx_irq_unmask(struct irq_data *d)
0056 {
0057     struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
0058     u32 val, mask = BIT(d->hwirq);
0059 
0060     val = lpc32xx_ic_read(ic, LPC32XX_INTC_MASK) | mask;
0061     lpc32xx_ic_write(ic, LPC32XX_INTC_MASK, val);
0062 }
0063 
0064 static void lpc32xx_irq_ack(struct irq_data *d)
0065 {
0066     struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
0067     u32 mask = BIT(d->hwirq);
0068 
0069     lpc32xx_ic_write(ic, LPC32XX_INTC_RAW, mask);
0070 }
0071 
0072 static int lpc32xx_irq_set_type(struct irq_data *d, unsigned int type)
0073 {
0074     struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
0075     u32 val, mask = BIT(d->hwirq);
0076     bool high, edge;
0077 
0078     switch (type) {
0079     case IRQ_TYPE_EDGE_RISING:
0080         edge = true;
0081         high = true;
0082         break;
0083     case IRQ_TYPE_EDGE_FALLING:
0084         edge = true;
0085         high = false;
0086         break;
0087     case IRQ_TYPE_LEVEL_HIGH:
0088         edge = false;
0089         high = true;
0090         break;
0091     case IRQ_TYPE_LEVEL_LOW:
0092         edge = false;
0093         high = false;
0094         break;
0095     default:
0096         pr_info("unsupported irq type %d\n", type);
0097         return -EINVAL;
0098     }
0099 
0100     irqd_set_trigger_type(d, type);
0101 
0102     val = lpc32xx_ic_read(ic, LPC32XX_INTC_POL);
0103     if (high)
0104         val |= mask;
0105     else
0106         val &= ~mask;
0107     lpc32xx_ic_write(ic, LPC32XX_INTC_POL, val);
0108 
0109     val = lpc32xx_ic_read(ic, LPC32XX_INTC_TYPE);
0110     if (edge) {
0111         val |= mask;
0112         irq_set_handler_locked(d, handle_edge_irq);
0113     } else {
0114         val &= ~mask;
0115         irq_set_handler_locked(d, handle_level_irq);
0116     }
0117     lpc32xx_ic_write(ic, LPC32XX_INTC_TYPE, val);
0118 
0119     return 0;
0120 }
0121 
0122 static void lpc32xx_irq_print_chip(struct irq_data *d, struct seq_file *p)
0123 {
0124     struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
0125 
0126     if (ic == lpc32xx_mic_irqc)
0127         seq_printf(p, "%08x.mic", ic->addr);
0128     else
0129         seq_printf(p, "%08x.sic", ic->addr);
0130 }
0131 
0132 static const struct irq_chip lpc32xx_chip = {
0133     .irq_ack    = lpc32xx_irq_ack,
0134     .irq_mask   = lpc32xx_irq_mask,
0135     .irq_unmask = lpc32xx_irq_unmask,
0136     .irq_set_type   = lpc32xx_irq_set_type,
0137     .irq_print_chip = lpc32xx_irq_print_chip,
0138 };
0139 
0140 static void __exception_irq_entry lpc32xx_handle_irq(struct pt_regs *regs)
0141 {
0142     struct lpc32xx_irq_chip *ic = lpc32xx_mic_irqc;
0143     u32 hwirq = lpc32xx_ic_read(ic, LPC32XX_INTC_STAT), irq;
0144 
0145     while (hwirq) {
0146         irq = __ffs(hwirq);
0147         hwirq &= ~BIT(irq);
0148         generic_handle_domain_irq(lpc32xx_mic_irqc->domain, irq);
0149     }
0150 }
0151 
0152 static void lpc32xx_sic_handler(struct irq_desc *desc)
0153 {
0154     struct lpc32xx_irq_chip *ic = irq_desc_get_handler_data(desc);
0155     struct irq_chip *chip = irq_desc_get_chip(desc);
0156     u32 hwirq = lpc32xx_ic_read(ic, LPC32XX_INTC_STAT), irq;
0157 
0158     chained_irq_enter(chip, desc);
0159 
0160     while (hwirq) {
0161         irq = __ffs(hwirq);
0162         hwirq &= ~BIT(irq);
0163         generic_handle_domain_irq(ic->domain, irq);
0164     }
0165 
0166     chained_irq_exit(chip, desc);
0167 }
0168 
0169 static int lpc32xx_irq_domain_map(struct irq_domain *id, unsigned int virq,
0170                   irq_hw_number_t hw)
0171 {
0172     struct lpc32xx_irq_chip *ic = id->host_data;
0173 
0174     irq_set_chip_data(virq, ic);
0175     irq_set_chip_and_handler(virq, &lpc32xx_chip, handle_level_irq);
0176     irq_set_status_flags(virq, IRQ_LEVEL);
0177     irq_set_noprobe(virq);
0178 
0179     return 0;
0180 }
0181 
0182 static void lpc32xx_irq_domain_unmap(struct irq_domain *id, unsigned int virq)
0183 {
0184     irq_set_chip_and_handler(virq, NULL, NULL);
0185 }
0186 
0187 static const struct irq_domain_ops lpc32xx_irq_domain_ops = {
0188     .map    = lpc32xx_irq_domain_map,
0189     .unmap  = lpc32xx_irq_domain_unmap,
0190     .xlate  = irq_domain_xlate_twocell,
0191 };
0192 
0193 static int __init lpc32xx_of_ic_init(struct device_node *node,
0194                      struct device_node *parent)
0195 {
0196     struct lpc32xx_irq_chip *irqc;
0197     bool is_mic = of_device_is_compatible(node, "nxp,lpc3220-mic");
0198     const __be32 *reg = of_get_property(node, "reg", NULL);
0199     u32 parent_irq, i, addr = reg ? be32_to_cpu(*reg) : 0;
0200 
0201     irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
0202     if (!irqc)
0203         return -ENOMEM;
0204 
0205     irqc->addr = addr;
0206     irqc->base = of_iomap(node, 0);
0207     if (!irqc->base) {
0208         pr_err("%pOF: unable to map registers\n", node);
0209         kfree(irqc);
0210         return -EINVAL;
0211     }
0212 
0213     irqc->domain = irq_domain_add_linear(node, NR_LPC32XX_IC_IRQS,
0214                          &lpc32xx_irq_domain_ops, irqc);
0215     if (!irqc->domain) {
0216         pr_err("unable to add irq domain\n");
0217         iounmap(irqc->base);
0218         kfree(irqc);
0219         return -ENODEV;
0220     }
0221 
0222     if (is_mic) {
0223         lpc32xx_mic_irqc = irqc;
0224         set_handle_irq(lpc32xx_handle_irq);
0225     } else {
0226         for (i = 0; i < of_irq_count(node); i++) {
0227             parent_irq = irq_of_parse_and_map(node, i);
0228             if (parent_irq)
0229                 irq_set_chained_handler_and_data(parent_irq,
0230                          lpc32xx_sic_handler, irqc);
0231         }
0232     }
0233 
0234     lpc32xx_ic_write(irqc, LPC32XX_INTC_MASK, 0x00);
0235     lpc32xx_ic_write(irqc, LPC32XX_INTC_POL,  0x00);
0236     lpc32xx_ic_write(irqc, LPC32XX_INTC_TYPE, 0x00);
0237 
0238     return 0;
0239 }
0240 
0241 IRQCHIP_DECLARE(nxp_lpc32xx_mic, "nxp,lpc3220-mic", lpc32xx_of_ic_init);
0242 IRQCHIP_DECLARE(nxp_lpc32xx_sic, "nxp,lpc3220-sic", lpc32xx_of_ic_init);