Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // Copyright 2003-2005 Simtec Electronics
0004 //   Ben Dooks <ben@simtec.co.uk>
0005 //
0006 // http://www.simtec.co.uk/products/EB2410ITX/
0007 
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/ioport.h>
0011 #include <linux/device.h>
0012 #include <linux/io.h>
0013 
0014 #include <asm/irq.h>
0015 #include <asm/mach-types.h>
0016 #include <asm/mach/irq.h>
0017 
0018 #include "regs-irq.h"
0019 #include "irqs.h"
0020 
0021 #include "bast.h"
0022 
0023 #define irqdbf(x...)
0024 #define irqdbf2(x...)
0025 
0026 /* handle PC104 ISA interrupts from the system CPLD */
0027 
0028 /* table of ISA irq nos to the relevant mask... zero means
0029  * the irq is not implemented
0030 */
0031 static const unsigned char bast_pc104_irqmasks[] = {
0032     0,   /* 0 */
0033     0,   /* 1 */
0034     0,   /* 2 */
0035     1,   /* 3 */
0036     0,   /* 4 */
0037     2,   /* 5 */
0038     0,   /* 6 */
0039     4,   /* 7 */
0040     0,   /* 8 */
0041     0,   /* 9 */
0042     8,   /* 10 */
0043     0,   /* 11 */
0044     0,   /* 12 */
0045     0,   /* 13 */
0046     0,   /* 14 */
0047     0,   /* 15 */
0048 };
0049 
0050 static const unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
0051 
0052 static void
0053 bast_pc104_mask(struct irq_data *data)
0054 {
0055     unsigned long temp;
0056 
0057     temp = __raw_readb(BAST_VA_PC104_IRQMASK);
0058     temp &= ~bast_pc104_irqmasks[data->irq];
0059     __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
0060 }
0061 
0062 static void
0063 bast_pc104_maskack(struct irq_data *data)
0064 {
0065     struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA);
0066 
0067     bast_pc104_mask(data);
0068     desc->irq_data.chip->irq_ack(&desc->irq_data);
0069 }
0070 
0071 static void
0072 bast_pc104_unmask(struct irq_data *data)
0073 {
0074     unsigned long temp;
0075 
0076     temp = __raw_readb(BAST_VA_PC104_IRQMASK);
0077     temp |= bast_pc104_irqmasks[data->irq];
0078     __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
0079 }
0080 
0081 static struct irq_chip  bast_pc104_chip = {
0082     .irq_mask   = bast_pc104_mask,
0083     .irq_unmask = bast_pc104_unmask,
0084     .irq_ack    = bast_pc104_maskack
0085 };
0086 
0087 static void bast_irq_pc104_demux(struct irq_desc *desc)
0088 {
0089     unsigned int stat;
0090     unsigned int irqno;
0091     int i;
0092 
0093     stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
0094 
0095     if (unlikely(stat == 0)) {
0096         /* ack if we get an irq with nothing (ie, startup) */
0097         desc->irq_data.chip->irq_ack(&desc->irq_data);
0098     } else {
0099         /* handle the IRQ */
0100 
0101         for (i = 0; stat != 0; i++, stat >>= 1) {
0102             if (stat & 1) {
0103                 irqno = bast_pc104_irqs[i];
0104                 generic_handle_irq(irqno);
0105             }
0106         }
0107     }
0108 }
0109 
0110 static __init int bast_irq_init(void)
0111 {
0112     unsigned int i;
0113 
0114     if (machine_is_bast()) {
0115         printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
0116 
0117         /* zap all the IRQs */
0118 
0119         __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
0120 
0121         irq_set_chained_handler(BAST_IRQ_ISA, bast_irq_pc104_demux);
0122 
0123         /* register our IRQs */
0124 
0125         for (i = 0; i < 4; i++) {
0126             unsigned int irqno = bast_pc104_irqs[i];
0127 
0128             irq_set_chip_and_handler(irqno, &bast_pc104_chip,
0129                          handle_level_irq);
0130             irq_clear_status_flags(irqno, IRQ_NOREQUEST);
0131         }
0132     }
0133 
0134     return 0;
0135 }
0136 
0137 arch_initcall(bast_irq_init);