Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 2 | * arch/arm/mach-iop33x/irq.c |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | */ |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 13 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | #include <linux/init.h> |
| 15 | #include <linux/interrupt.h> |
| 16 | #include <linux/list.h> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | #include <asm/mach/irq.h> |
| 18 | #include <asm/irq.h> |
| 19 | #include <asm/hardware.h> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | #include <asm/mach-types.h> |
| 21 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 22 | static u32 iop33x_mask0; |
| 23 | static u32 iop33x_mask1; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 24 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 25 | static inline void intctl0_write(u32 val) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | { |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 27 | iop3xx_cp6_enable(); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 28 | asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 29 | iop3xx_cp6_disable(); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 30 | } |
| 31 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 32 | static inline void intctl1_write(u32 val) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 33 | { |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 34 | iop3xx_cp6_enable(); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 35 | asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 36 | iop3xx_cp6_disable(); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 39 | static inline void intstr0_write(u32 val) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 | { |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 41 | iop3xx_cp6_enable(); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 42 | asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 43 | iop3xx_cp6_disable(); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | } |
| 45 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 46 | static inline void intstr1_write(u32 val) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 | { |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 48 | iop3xx_cp6_enable(); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 49 | asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); |
Lennert Buytenhek | 38ce73e | 2006-09-18 23:21:38 +0100 | [diff] [blame] | 50 | iop3xx_cp6_disable(); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 | } |
| 52 | |
Lennert Buytenhek | 7412b10 | 2006-09-18 23:24:10 +0100 | [diff] [blame] | 53 | static inline void intbase_write(u32 val) |
| 54 | { |
| 55 | iop3xx_cp6_enable(); |
| 56 | asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); |
| 57 | iop3xx_cp6_disable(); |
| 58 | } |
| 59 | |
| 60 | static inline void intsize_write(u32 val) |
| 61 | { |
| 62 | iop3xx_cp6_enable(); |
| 63 | asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); |
| 64 | iop3xx_cp6_disable(); |
| 65 | } |
| 66 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | static void |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 68 | iop33x_irq_mask1 (unsigned int irq) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | { |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 70 | iop33x_mask0 &= ~(1 << irq); |
| 71 | intctl0_write(iop33x_mask0); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | static void |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 75 | iop33x_irq_mask2 (unsigned int irq) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 | { |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 77 | iop33x_mask1 &= ~(1 << (irq - 32)); |
| 78 | intctl1_write(iop33x_mask1); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | static void |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 82 | iop33x_irq_unmask1(unsigned int irq) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 83 | { |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 84 | iop33x_mask0 |= 1 << irq; |
| 85 | intctl0_write(iop33x_mask0); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | static void |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 89 | iop33x_irq_unmask2(unsigned int irq) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 90 | { |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 91 | iop33x_mask1 |= (1 << (irq - 32)); |
| 92 | intctl1_write(iop33x_mask1); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 | } |
| 94 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 95 | struct irq_chip iop33x_irqchip1 = { |
| 96 | .name = "IOP33x-1", |
| 97 | .ack = iop33x_irq_mask1, |
| 98 | .mask = iop33x_irq_mask1, |
| 99 | .unmask = iop33x_irq_unmask1, |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 100 | }; |
| 101 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 102 | struct irq_chip iop33x_irqchip2 = { |
| 103 | .name = "IOP33x-2", |
| 104 | .ack = iop33x_irq_mask2, |
| 105 | .mask = iop33x_irq_mask2, |
| 106 | .unmask = iop33x_irq_unmask2, |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 107 | }; |
| 108 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 109 | void __init iop33x_init_irq(void) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 110 | { |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 111 | int i; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 112 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 113 | intctl0_write(0); |
| 114 | intctl1_write(0); |
| 115 | intstr0_write(0); |
| 116 | intstr1_write(0); |
Lennert Buytenhek | 7412b10 | 2006-09-18 23:24:10 +0100 | [diff] [blame] | 117 | intbase_write(0); |
| 118 | intsize_write(1); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 119 | if (machine_is_iq80331()) |
Lennert Buytenhek | 7e9740b | 2006-09-18 23:17:36 +0100 | [diff] [blame] | 120 | *IOP3XX_PCIIRSR = 0x0f; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame^] | 122 | for (i = 0; i < NR_IRQS; i++) { |
| 123 | set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 124 | set_irq_handler(i, do_level_IRQ); |
| 125 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
| 126 | } |
| 127 | } |