~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/jazz/irq.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 1992 Linus Torvalds
  7  * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
  8  */
  9 #include <linux/clockchips.h>
 10 #include <linux/i8253.h>
 11 #include <linux/init.h>
 12 #include <linux/interrupt.h>
 13 #include <linux/kernel.h>
 14 #include <linux/smp.h>
 15 #include <linux/spinlock.h>
 16 #include <linux/irq.h>
 17 
 18 #include <asm/irq_cpu.h>
 19 #include <asm/i8259.h>
 20 #include <asm/io.h>
 21 #include <asm/jazz.h>
 22 #include <asm/pgtable.h>
 23 #include <asm/tlbmisc.h>
 24 
 25 static DEFINE_RAW_SPINLOCK(r4030_lock);
 26 
 27 static void enable_r4030_irq(struct irq_data *d)
 28 {
 29         unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START);
 30         unsigned long flags;
 31 
 32         raw_spin_lock_irqsave(&r4030_lock, flags);
 33         mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
 34         r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
 35         raw_spin_unlock_irqrestore(&r4030_lock, flags);
 36 }
 37 
 38 void disable_r4030_irq(struct irq_data *d)
 39 {
 40         unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START));
 41         unsigned long flags;
 42 
 43         raw_spin_lock_irqsave(&r4030_lock, flags);
 44         mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
 45         r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
 46         raw_spin_unlock_irqrestore(&r4030_lock, flags);
 47 }
 48 
 49 static struct irq_chip r4030_irq_type = {
 50         .name = "R4030",
 51         .irq_mask = disable_r4030_irq,
 52         .irq_unmask = enable_r4030_irq,
 53 };
 54 
 55 void __init init_r4030_ints(void)
 56 {
 57         int i;
 58 
 59         for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++)
 60                 irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq);
 61 
 62         r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0);
 63         r4030_read_reg16(JAZZ_IO_IRQ_SOURCE);           /* clear pending IRQs */
 64         r4030_read_reg32(JAZZ_R4030_INVAL_ADDR);        /* clear error bits */
 65 }
 66 
 67 /*
 68  * On systems with i8259-style interrupt controllers we assume for
 69  * driver compatibility reasons interrupts 0 - 15 to be the i8259
 70  * interrupts even if the hardware uses a different interrupt numbering.
 71  */
 72 void __init arch_init_irq(void)
 73 {
 74         /*
 75          * this is a hack to get back the still needed wired mapping
 76          * killed by init_mm()
 77          */
 78 
 79         /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */
 80         add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K);
 81         /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */
 82         add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M);
 83         /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */
 84         add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M);
 85 
 86         init_i8259_irqs();                      /* Integrated i8259  */
 87         mips_cpu_irq_init();
 88         init_r4030_ints();
 89 
 90         change_c0_status(ST0_IM, IE_IRQ2 | IE_IRQ1);
 91 }
 92 
 93 asmlinkage void plat_irq_dispatch(void)
 94 {
 95         unsigned int pending = read_c0_cause() & read_c0_status();
 96         unsigned int irq;
 97 
 98         if (pending & IE_IRQ4) {
 99                 r4030_read_reg32(JAZZ_TIMER_REGISTER);
100                 do_IRQ(JAZZ_TIMER_IRQ);
101         } else if (pending & IE_IRQ2) {
102                 irq = *(volatile u8 *)JAZZ_EISA_IRQ_ACK;
103                 do_IRQ(irq);
104         } else if (pending & IE_IRQ1) {
105                 irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2;
106                 if (likely(irq > 0))
107                         do_IRQ(irq + JAZZ_IRQ_START - 1);
108                 else
109                         panic("Unimplemented loc_no_irq handler");
110         }
111 }
112 
113 struct clock_event_device r4030_clockevent = {
114         .name           = "r4030",
115         .features       = CLOCK_EVT_FEAT_PERIODIC,
116         .rating         = 300,
117         .irq            = JAZZ_TIMER_IRQ,
118 };
119 
120 static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
121 {
122         struct clock_event_device *cd = dev_id;
123 
124         cd->event_handler(cd);
125         return IRQ_HANDLED;
126 }
127 
128 static struct irqaction r4030_timer_irqaction = {
129         .handler        = r4030_timer_interrupt,
130         .flags          = IRQF_TIMER,
131         .name           = "R4030 timer",
132 };
133 
134 void __init plat_time_init(void)
135 {
136         struct clock_event_device *cd = &r4030_clockevent;
137         struct irqaction *action = &r4030_timer_irqaction;
138         unsigned int cpu = smp_processor_id();
139 
140         BUG_ON(HZ != 100);
141 
142         cd->cpumask             = cpumask_of(cpu);
143         clockevents_register_device(cd);
144         action->dev_id = cd;
145         setup_irq(JAZZ_TIMER_IRQ, action);
146 
147         /*
148          * Set clock to 100Hz.
149          *
150          * The R4030 timer receives an input clock of 1kHz which is divieded by
151          * a programmable 4-bit divider.  This makes it fairly inflexible.
152          */
153         r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
154         setup_pit_timer();
155 }
156 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp