0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/init.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/irq.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/serial_8250.h>
0019 #include <linux/io.h>
0020
0021 #include <asm/sni.h>
0022 #include <asm/time.h>
0023 #include <asm/irq_cpu.h>
0024
0025 #define RM200_I8259A_IRQ_BASE 32
0026
0027 #define MEMPORT(_base,_irq) \
0028 { \
0029 .mapbase = _base, \
0030 .irq = _irq, \
0031 .uartclk = 1843200, \
0032 .iotype = UPIO_MEM, \
0033 .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
0034 }
0035
0036 static struct plat_serial8250_port rm200_data[] = {
0037 MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
0038 MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
0039 { },
0040 };
0041
0042 static struct platform_device rm200_serial8250_device = {
0043 .name = "serial8250",
0044 .id = PLAT8250_DEV_PLATFORM,
0045 .dev = {
0046 .platform_data = rm200_data,
0047 },
0048 };
0049
0050 static struct resource rm200_ds1216_rsrc[] = {
0051 {
0052 .start = 0x1cd41ffc,
0053 .end = 0x1cd41fff,
0054 .flags = IORESOURCE_MEM
0055 }
0056 };
0057
0058 static struct platform_device rm200_ds1216_device = {
0059 .name = "rtc-ds1216",
0060 .num_resources = ARRAY_SIZE(rm200_ds1216_rsrc),
0061 .resource = rm200_ds1216_rsrc
0062 };
0063
0064 static struct resource snirm_82596_rm200_rsrc[] = {
0065 {
0066 .start = 0x18000000,
0067 .end = 0x180fffff,
0068 .flags = IORESOURCE_MEM
0069 },
0070 {
0071 .start = 0x1b000000,
0072 .end = 0x1b000004,
0073 .flags = IORESOURCE_MEM
0074 },
0075 {
0076 .start = 0x1ff00000,
0077 .end = 0x1ff00020,
0078 .flags = IORESOURCE_MEM
0079 },
0080 {
0081 .start = 27,
0082 .end = 27,
0083 .flags = IORESOURCE_IRQ
0084 },
0085 {
0086 .flags = 0x00
0087 }
0088 };
0089
0090 static struct platform_device snirm_82596_rm200_pdev = {
0091 .name = "snirm_82596",
0092 .num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc),
0093 .resource = snirm_82596_rm200_rsrc
0094 };
0095
0096 static struct resource snirm_53c710_rm200_rsrc[] = {
0097 {
0098 .start = 0x19000000,
0099 .end = 0x190fffff,
0100 .flags = IORESOURCE_MEM
0101 },
0102 {
0103 .start = 26,
0104 .end = 26,
0105 .flags = IORESOURCE_IRQ
0106 }
0107 };
0108
0109 static struct platform_device snirm_53c710_rm200_pdev = {
0110 .name = "snirm_53c710",
0111 .num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
0112 .resource = snirm_53c710_rm200_rsrc
0113 };
0114
0115 static int __init snirm_setup_devinit(void)
0116 {
0117 if (sni_brd_type == SNI_BRD_RM200) {
0118 platform_device_register(&rm200_serial8250_device);
0119 platform_device_register(&rm200_ds1216_device);
0120 platform_device_register(&snirm_82596_rm200_pdev);
0121 platform_device_register(&snirm_53c710_rm200_pdev);
0122 sni_eisa_root_init();
0123 }
0124 return 0;
0125 }
0126
0127 device_initcall(snirm_setup_devinit);
0128
0129
0130
0131
0132
0133
0134
0135
0136 static DEFINE_RAW_SPINLOCK(sni_rm200_i8259A_lock);
0137 #define PIC_CMD 0x00
0138 #define PIC_IMR 0x01
0139 #define PIC_ISR PIC_CMD
0140 #define PIC_POLL PIC_ISR
0141 #define PIC_OCW3 PIC_ISR
0142
0143
0144 #define PIC_CASCADE_IR 2
0145 #define MASTER_ICW4_DEFAULT 0x01
0146 #define SLAVE_ICW4_DEFAULT 0x01
0147
0148
0149
0150
0151 static unsigned int rm200_cached_irq_mask = 0xffff;
0152 static __iomem u8 *rm200_pic_master;
0153 static __iomem u8 *rm200_pic_slave;
0154
0155 #define cached_master_mask (rm200_cached_irq_mask)
0156 #define cached_slave_mask (rm200_cached_irq_mask >> 8)
0157
0158 static void sni_rm200_disable_8259A_irq(struct irq_data *d)
0159 {
0160 unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
0161 unsigned long flags;
0162
0163 mask = 1 << irq;
0164 raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
0165 rm200_cached_irq_mask |= mask;
0166 if (irq & 8)
0167 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
0168 else
0169 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
0170 raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
0171 }
0172
0173 static void sni_rm200_enable_8259A_irq(struct irq_data *d)
0174 {
0175 unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
0176 unsigned long flags;
0177
0178 mask = ~(1 << irq);
0179 raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
0180 rm200_cached_irq_mask &= mask;
0181 if (irq & 8)
0182 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
0183 else
0184 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
0185 raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
0186 }
0187
0188 static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
0189 {
0190 int value;
0191 int irqmask = 1 << irq;
0192
0193 if (irq < 8) {
0194 writeb(0x0B, rm200_pic_master + PIC_CMD);
0195 value = readb(rm200_pic_master + PIC_CMD) & irqmask;
0196 writeb(0x0A, rm200_pic_master + PIC_CMD);
0197 return value;
0198 }
0199 writeb(0x0B, rm200_pic_slave + PIC_CMD);
0200 value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
0201 writeb(0x0A, rm200_pic_slave + PIC_CMD);
0202 return value;
0203 }
0204
0205
0206
0207
0208
0209
0210
0211 void sni_rm200_mask_and_ack_8259A(struct irq_data *d)
0212 {
0213 unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE;
0214 unsigned long flags;
0215
0216 irqmask = 1 << irq;
0217 raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 if (rm200_cached_irq_mask & irqmask)
0234 goto spurious_8259A_irq;
0235 rm200_cached_irq_mask |= irqmask;
0236
0237 handle_real_irq:
0238 if (irq & 8) {
0239 readb(rm200_pic_slave + PIC_IMR);
0240 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
0241 writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
0242 writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
0243 } else {
0244 readb(rm200_pic_master + PIC_IMR);
0245 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
0246 writeb(0x60+irq, rm200_pic_master + PIC_CMD);
0247 }
0248 raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
0249 return;
0250
0251 spurious_8259A_irq:
0252
0253
0254
0255 if (sni_rm200_i8259A_irq_real(irq))
0256
0257
0258
0259
0260 goto handle_real_irq;
0261
0262 {
0263 static int spurious_irq_mask;
0264
0265
0266
0267
0268 if (!(spurious_irq_mask & irqmask)) {
0269 printk(KERN_DEBUG
0270 "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
0271 spurious_irq_mask |= irqmask;
0272 }
0273 atomic_inc(&irq_err_count);
0274
0275
0276
0277
0278
0279 goto handle_real_irq;
0280 }
0281 }
0282
0283 static struct irq_chip sni_rm200_i8259A_chip = {
0284 .name = "RM200-XT-PIC",
0285 .irq_mask = sni_rm200_disable_8259A_irq,
0286 .irq_unmask = sni_rm200_enable_8259A_irq,
0287 .irq_mask_ack = sni_rm200_mask_and_ack_8259A,
0288 };
0289
0290
0291
0292
0293
0294
0295 static inline int sni_rm200_i8259_irq(void)
0296 {
0297 int irq;
0298
0299 raw_spin_lock(&sni_rm200_i8259A_lock);
0300
0301
0302 writeb(0x0C, rm200_pic_master + PIC_CMD);
0303 irq = readb(rm200_pic_master + PIC_CMD) & 7;
0304 if (irq == PIC_CASCADE_IR) {
0305
0306
0307
0308
0309 writeb(0x0C, rm200_pic_slave + PIC_CMD);
0310 irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
0311 }
0312
0313 if (unlikely(irq == 7)) {
0314
0315
0316
0317
0318
0319
0320
0321 writeb(0x0B, rm200_pic_master + PIC_ISR);
0322 if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
0323 irq = -1;
0324 }
0325
0326 raw_spin_unlock(&sni_rm200_i8259A_lock);
0327
0328 return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
0329 }
0330
0331 void sni_rm200_init_8259A(void)
0332 {
0333 unsigned long flags;
0334
0335 raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
0336
0337 writeb(0xff, rm200_pic_master + PIC_IMR);
0338 writeb(0xff, rm200_pic_slave + PIC_IMR);
0339
0340 writeb(0x11, rm200_pic_master + PIC_CMD);
0341 writeb(0, rm200_pic_master + PIC_IMR);
0342 writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
0343 writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
0344 writeb(0x11, rm200_pic_slave + PIC_CMD);
0345 writeb(8, rm200_pic_slave + PIC_IMR);
0346 writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
0347 writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
0348 udelay(100);
0349
0350 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
0351 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
0352
0353 raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
0354 }
0355
0356
0357
0358
0359
0360 static struct resource sni_rm200_pic1_resource = {
0361 .name = "onboard ISA pic1",
0362 .start = 0x16000020,
0363 .end = 0x16000023,
0364 .flags = IORESOURCE_BUSY
0365 };
0366
0367 static struct resource sni_rm200_pic2_resource = {
0368 .name = "onboard ISA pic2",
0369 .start = 0x160000a0,
0370 .end = 0x160000a3,
0371 .flags = IORESOURCE_BUSY
0372 };
0373
0374
0375 static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
0376 {
0377 int irq;
0378
0379 irq = sni_rm200_i8259_irq();
0380 if (unlikely(irq < 0))
0381 return IRQ_NONE;
0382
0383 do_IRQ(irq);
0384 return IRQ_HANDLED;
0385 }
0386
0387 void __init sni_rm200_i8259_irqs(void)
0388 {
0389 int i;
0390
0391 rm200_pic_master = ioremap(0x16000020, 4);
0392 if (!rm200_pic_master)
0393 return;
0394 rm200_pic_slave = ioremap(0x160000a0, 4);
0395 if (!rm200_pic_slave) {
0396 iounmap(rm200_pic_master);
0397 return;
0398 }
0399
0400 insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
0401 insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
0402
0403 sni_rm200_init_8259A();
0404
0405 for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
0406 irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip,
0407 handle_level_irq);
0408
0409 if (request_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, no_action,
0410 IRQF_NO_THREAD, "cascade", NULL))
0411 pr_err("Failed to register cascade interrupt\n");
0412 }
0413
0414
0415 #define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
0416 #define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
0417
0418 #define SNI_RM200_INT_START 24
0419 #define SNI_RM200_INT_END 28
0420
0421 static void enable_rm200_irq(struct irq_data *d)
0422 {
0423 unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
0424
0425 *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
0426 }
0427
0428 void disable_rm200_irq(struct irq_data *d)
0429 {
0430 unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
0431
0432 *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
0433 }
0434
0435 static struct irq_chip rm200_irq_type = {
0436 .name = "RM200",
0437 .irq_mask = disable_rm200_irq,
0438 .irq_unmask = enable_rm200_irq,
0439 };
0440
0441 static void sni_rm200_hwint(void)
0442 {
0443 u32 pending = read_c0_cause() & read_c0_status();
0444 u8 mask;
0445 u8 stat;
0446 int irq;
0447
0448 if (pending & C_IRQ5)
0449 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0450 else if (pending & C_IRQ0) {
0451 clear_c0_status(IE_IRQ0);
0452 mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
0453 stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
0454 irq = ffs(stat & mask & 0x1f);
0455
0456 if (likely(irq > 0))
0457 do_IRQ(irq + SNI_RM200_INT_START - 1);
0458 set_c0_status(IE_IRQ0);
0459 }
0460 }
0461
0462 void __init sni_rm200_irq_init(void)
0463 {
0464 int i;
0465
0466 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
0467
0468 sni_rm200_i8259_irqs();
0469 mips_cpu_irq_init();
0470
0471 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
0472 irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
0473 sni_hwint = sni_rm200_hwint;
0474 change_c0_status(ST0_IM, IE_IRQ0);
0475 if (request_irq(SNI_RM200_INT_START + 0, sni_rm200_i8259A_irq_handler,
0476 0, "onboard ISA", NULL))
0477 pr_err("Failed to register onboard ISA interrupt\n");
0478 if (request_irq(SNI_RM200_INT_START + 1, sni_isa_irq_handler, 0, "ISA",
0479 NULL))
0480 pr_err("Failed to register ISA interrupt\n");
0481 }
0482
0483 void __init sni_rm200_init(void)
0484 {
0485 }