1/* 2 * arch/arm/mach-iop33x/irq.c 3 * 4 * Generic IOP331 IRQ handling functionality 5 * 6 * Author: Dave Jiang <dave.jiang@intel.com> 7 * Copyright (C) 2003 Intel Corp. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14#include <linux/init.h> 15#include <linux/interrupt.h> 16#include <linux/list.h> 17#include <asm/mach/irq.h> 18#include <asm/irq.h> 19#include <mach/hardware.h> 20#include <asm/mach-types.h> 21 22static u32 iop33x_mask0; 23static u32 iop33x_mask1; 24 25static void intctl0_write(u32 val) 26{ 27 asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); 28} 29 30static void intctl1_write(u32 val) 31{ 32 asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); 33} 34 35static void intstr0_write(u32 val) 36{ 37 asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); 38} 39 40static void intstr1_write(u32 val) 41{ 42 asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); 43} 44 45static void intbase_write(u32 val) 46{ 47 asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); 48} 49 50static void intsize_write(u32 val) 51{ 52 asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); 53} 54 55static void 56iop33x_irq_mask1 (struct irq_data *d) 57{ 58 iop33x_mask0 &= ~(1 << d->irq); 59 intctl0_write(iop33x_mask0); 60} 61 62static void 63iop33x_irq_mask2 (struct irq_data *d) 64{ 65 iop33x_mask1 &= ~(1 << (d->irq - 32)); 66 intctl1_write(iop33x_mask1); 67} 68 69static void 70iop33x_irq_unmask1(struct irq_data *d) 71{ 72 iop33x_mask0 |= 1 << d->irq; 73 intctl0_write(iop33x_mask0); 74} 75 76static void 77iop33x_irq_unmask2(struct irq_data *d) 78{ 79 iop33x_mask1 |= (1 << (d->irq - 32)); 80 intctl1_write(iop33x_mask1); 81} 82 83struct irq_chip iop33x_irqchip1 = { 84 .name = "IOP33x-1", 85 .irq_ack = iop33x_irq_mask1, 86 .irq_mask = iop33x_irq_mask1, 87 .irq_unmask = iop33x_irq_unmask1, 88}; 89 90struct irq_chip iop33x_irqchip2 = { 91 .name = "IOP33x-2", 92 .irq_ack = iop33x_irq_mask2, 93 .irq_mask = iop33x_irq_mask2, 94 .irq_unmask = iop33x_irq_unmask2, 95}; 96 97void __init iop33x_init_irq(void) 98{ 99 int i; 100 101 iop_init_cp6_handler(); 102 103 intctl0_write(0); 104 intctl1_write(0); 105 intstr0_write(0); 106 intstr1_write(0); 107 intbase_write(0); 108 intsize_write(1); 109 if (machine_is_iq80331()) 110 *IOP3XX_PCIIRSR = 0x0f; 111 112 for (i = 0; i < NR_IRQS; i++) { 113 irq_set_chip_and_handler(i, 114 (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2, 115 handle_level_irq); 116 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 117 } 118} 119