Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  arch/arm/mach-vt8500/irq.c
0004  *
0005  *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
0006  *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
0007  */
0008 
0009 /*
0010  * This file is copied and modified from the original irq.c provided by
0011  * Alexey Charkov. Minor changes have been made for Device Tree Support.
0012  */
0013 
0014 #include <linux/slab.h>
0015 #include <linux/io.h>
0016 #include <linux/irq.h>
0017 #include <linux/irqchip.h>
0018 #include <linux/irqdomain.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/bitops.h>
0021 
0022 #include <linux/of.h>
0023 #include <linux/of_irq.h>
0024 #include <linux/of_address.h>
0025 
0026 #include <asm/irq.h>
0027 #include <asm/exception.h>
0028 #include <asm/mach/irq.h>
0029 
0030 #define VT8500_ICPC_IRQ     0x20
0031 #define VT8500_ICPC_FIQ     0x24
0032 #define VT8500_ICDC     0x40        /* Destination Control 64*u32 */
0033 #define VT8500_ICIS     0x80        /* Interrupt status, 16*u32 */
0034 
0035 /* ICPC */
0036 #define ICPC_MASK       0x3F
0037 #define ICPC_ROTATE     BIT(6)
0038 
0039 /* IC_DCTR */
0040 #define ICDC_IRQ        0x00
0041 #define ICDC_FIQ        0x01
0042 #define ICDC_DSS0       0x02
0043 #define ICDC_DSS1       0x03
0044 #define ICDC_DSS2       0x04
0045 #define ICDC_DSS3       0x05
0046 #define ICDC_DSS4       0x06
0047 #define ICDC_DSS5       0x07
0048 
0049 #define VT8500_INT_DISABLE  0
0050 #define VT8500_INT_ENABLE   BIT(3)
0051 
0052 #define VT8500_TRIGGER_HIGH 0
0053 #define VT8500_TRIGGER_RISING   BIT(5)
0054 #define VT8500_TRIGGER_FALLING  BIT(6)
0055 #define VT8500_EDGE     ( VT8500_TRIGGER_RISING \
0056                 | VT8500_TRIGGER_FALLING)
0057 
0058 /* vt8500 has 1 intc, wm8505 and wm8650 have 2 */
0059 #define VT8500_INTC_MAX     2
0060 
0061 struct vt8500_irq_data {
0062     void __iomem        *base;      /* IO Memory base address */
0063     struct irq_domain   *domain;    /* Domain for this controller */
0064 };
0065 
0066 /* Global variable for accessing io-mem addresses */
0067 static struct vt8500_irq_data intc[VT8500_INTC_MAX];
0068 static u32 active_cnt = 0;
0069 
0070 static void vt8500_irq_mask(struct irq_data *d)
0071 {
0072     struct vt8500_irq_data *priv = d->domain->host_data;
0073     void __iomem *base = priv->base;
0074     void __iomem *stat_reg = base + VT8500_ICIS + (d->hwirq < 32 ? 0 : 4);
0075     u8 edge, dctr;
0076     u32 status;
0077 
0078     edge = readb(base + VT8500_ICDC + d->hwirq) & VT8500_EDGE;
0079     if (edge) {
0080         status = readl(stat_reg);
0081 
0082         status |= (1 << (d->hwirq & 0x1f));
0083         writel(status, stat_reg);
0084     } else {
0085         dctr = readb(base + VT8500_ICDC + d->hwirq);
0086         dctr &= ~VT8500_INT_ENABLE;
0087         writeb(dctr, base + VT8500_ICDC + d->hwirq);
0088     }
0089 }
0090 
0091 static void vt8500_irq_unmask(struct irq_data *d)
0092 {
0093     struct vt8500_irq_data *priv = d->domain->host_data;
0094     void __iomem *base = priv->base;
0095     u8 dctr;
0096 
0097     dctr = readb(base + VT8500_ICDC + d->hwirq);
0098     dctr |= VT8500_INT_ENABLE;
0099     writeb(dctr, base + VT8500_ICDC + d->hwirq);
0100 }
0101 
0102 static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
0103 {
0104     struct vt8500_irq_data *priv = d->domain->host_data;
0105     void __iomem *base = priv->base;
0106     u8 dctr;
0107 
0108     dctr = readb(base + VT8500_ICDC + d->hwirq);
0109     dctr &= ~VT8500_EDGE;
0110 
0111     switch (flow_type) {
0112     case IRQF_TRIGGER_LOW:
0113         return -EINVAL;
0114     case IRQF_TRIGGER_HIGH:
0115         dctr |= VT8500_TRIGGER_HIGH;
0116         irq_set_handler_locked(d, handle_level_irq);
0117         break;
0118     case IRQF_TRIGGER_FALLING:
0119         dctr |= VT8500_TRIGGER_FALLING;
0120         irq_set_handler_locked(d, handle_edge_irq);
0121         break;
0122     case IRQF_TRIGGER_RISING:
0123         dctr |= VT8500_TRIGGER_RISING;
0124         irq_set_handler_locked(d, handle_edge_irq);
0125         break;
0126     }
0127     writeb(dctr, base + VT8500_ICDC + d->hwirq);
0128 
0129     return 0;
0130 }
0131 
0132 static struct irq_chip vt8500_irq_chip = {
0133     .name = "vt8500",
0134     .irq_ack = vt8500_irq_mask,
0135     .irq_mask = vt8500_irq_mask,
0136     .irq_unmask = vt8500_irq_unmask,
0137     .irq_set_type = vt8500_irq_set_type,
0138 };
0139 
0140 static void __init vt8500_init_irq_hw(void __iomem *base)
0141 {
0142     u32 i;
0143 
0144     /* Enable rotating priority for IRQ */
0145     writel(ICPC_ROTATE, base + VT8500_ICPC_IRQ);
0146     writel(0x00, base + VT8500_ICPC_FIQ);
0147 
0148     /* Disable all interrupts and route them to IRQ */
0149     for (i = 0; i < 64; i++)
0150         writeb(VT8500_INT_DISABLE | ICDC_IRQ, base + VT8500_ICDC + i);
0151 }
0152 
0153 static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
0154                             irq_hw_number_t hw)
0155 {
0156     irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq);
0157 
0158     return 0;
0159 }
0160 
0161 static const struct irq_domain_ops vt8500_irq_domain_ops = {
0162     .map = vt8500_irq_map,
0163     .xlate = irq_domain_xlate_onecell,
0164 };
0165 
0166 static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
0167 {
0168     u32 stat, i;
0169     int irqnr;
0170     void __iomem *base;
0171 
0172     /* Loop through each active controller */
0173     for (i=0; i<active_cnt; i++) {
0174         base = intc[i].base;
0175         irqnr = readl_relaxed(base) & 0x3F;
0176         /*
0177           Highest Priority register default = 63, so check that this
0178           is a real interrupt by checking the status register
0179         */
0180         if (irqnr == 63) {
0181             stat = readl_relaxed(base + VT8500_ICIS + 4);
0182             if (!(stat & BIT(31)))
0183                 continue;
0184         }
0185 
0186         generic_handle_domain_irq(intc[i].domain, irqnr);
0187     }
0188 }
0189 
0190 static int __init vt8500_irq_init(struct device_node *node,
0191                   struct device_node *parent)
0192 {
0193     int irq, i;
0194     struct device_node *np = node;
0195 
0196     if (active_cnt == VT8500_INTC_MAX) {
0197         pr_err("%s: Interrupt controllers > VT8500_INTC_MAX\n",
0198                                 __func__);
0199         goto out;
0200     }
0201 
0202     intc[active_cnt].base = of_iomap(np, 0);
0203     intc[active_cnt].domain = irq_domain_add_linear(node, 64,
0204             &vt8500_irq_domain_ops, &intc[active_cnt]);
0205 
0206     if (!intc[active_cnt].base) {
0207         pr_err("%s: Unable to map IO memory\n", __func__);
0208         goto out;
0209     }
0210 
0211     if (!intc[active_cnt].domain) {
0212         pr_err("%s: Unable to add irq domain!\n", __func__);
0213         goto out;
0214     }
0215 
0216     set_handle_irq(vt8500_handle_irq);
0217 
0218     vt8500_init_irq_hw(intc[active_cnt].base);
0219 
0220     pr_info("vt8500-irq: Added interrupt controller\n");
0221 
0222     active_cnt++;
0223 
0224     /* check if this is a slaved controller */
0225     if (of_irq_count(np) != 0) {
0226         /* check that we have the correct number of interrupts */
0227         if (of_irq_count(np) != 8) {
0228             pr_err("%s: Incorrect IRQ map for slaved controller\n",
0229                     __func__);
0230             return -EINVAL;
0231         }
0232 
0233         for (i = 0; i < 8; i++) {
0234             irq = irq_of_parse_and_map(np, i);
0235             enable_irq(irq);
0236         }
0237 
0238         pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
0239     }
0240 out:
0241     return 0;
0242 }
0243 
0244 IRQCHIP_DECLARE(vt8500_irq, "via,vt8500-intc", vt8500_irq_init);