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 | |
Dan Williams | 588ef76 | 2007-02-13 17:12:04 +0100 | [diff] [blame^] | 113 | iop_init_cp6_handler(); |
| 114 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame] | 115 | intctl0_write(0); |
| 116 | intctl1_write(0); |
| 117 | intstr0_write(0); |
| 118 | intstr1_write(0); |
Lennert Buytenhek | 7412b10 | 2006-09-18 23:24:10 +0100 | [diff] [blame] | 119 | intbase_write(0); |
| 120 | intsize_write(1); |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame] | 121 | if (machine_is_iq80331()) |
Lennert Buytenhek | 7e9740b | 2006-09-18 23:17:36 +0100 | [diff] [blame] | 122 | *IOP3XX_PCIIRSR = 0x0f; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 | |
Lennert Buytenhek | c852ac8 | 2006-09-18 23:26:25 +0100 | [diff] [blame] | 124 | for (i = 0; i < NR_IRQS; i++) { |
| 125 | set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); |
Russell King | 10dd5ce | 2006-11-23 11:41:32 +0000 | [diff] [blame] | 126 | set_irq_handler(i, handle_level_irq); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 127 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
| 128 | } |
| 129 | } |