rm200.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /*
  2. * RM200 specific code
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  9. *
  10. * i8259 parts ripped out of arch/mips/kernel/i8259.c
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/irq.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/serial_8250.h>
  18. #include <linux/io.h>
  19. #include <asm/sni.h>
  20. #include <asm/time.h>
  21. #include <asm/irq_cpu.h>
  22. #define RM200_I8259A_IRQ_BASE 32
  23. #define MEMPORT(_base,_irq) \
  24. { \
  25. .mapbase = _base, \
  26. .irq = _irq, \
  27. .uartclk = 1843200, \
  28. .iotype = UPIO_MEM, \
  29. .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
  30. }
  31. static struct plat_serial8250_port rm200_data[] = {
  32. MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
  33. MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
  34. { },
  35. };
  36. static struct platform_device rm200_serial8250_device = {
  37. .name = "serial8250",
  38. .id = PLAT8250_DEV_PLATFORM,
  39. .dev = {
  40. .platform_data = rm200_data,
  41. },
  42. };
  43. static struct resource rm200_ds1216_rsrc[] = {
  44. {
  45. .start = 0x1cd41ffc,
  46. .end = 0x1cd41fff,
  47. .flags = IORESOURCE_MEM
  48. }
  49. };
  50. static struct platform_device rm200_ds1216_device = {
  51. .name = "rtc-ds1216",
  52. .num_resources = ARRAY_SIZE(rm200_ds1216_rsrc),
  53. .resource = rm200_ds1216_rsrc
  54. };
  55. static struct resource snirm_82596_rm200_rsrc[] = {
  56. {
  57. .start = 0x18000000,
  58. .end = 0x180fffff,
  59. .flags = IORESOURCE_MEM
  60. },
  61. {
  62. .start = 0x1b000000,
  63. .end = 0x1b000004,
  64. .flags = IORESOURCE_MEM
  65. },
  66. {
  67. .start = 0x1ff00000,
  68. .end = 0x1ff00020,
  69. .flags = IORESOURCE_MEM
  70. },
  71. {
  72. .start = 27,
  73. .end = 27,
  74. .flags = IORESOURCE_IRQ
  75. },
  76. {
  77. .flags = 0x00
  78. }
  79. };
  80. static struct platform_device snirm_82596_rm200_pdev = {
  81. .name = "snirm_82596",
  82. .num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc),
  83. .resource = snirm_82596_rm200_rsrc
  84. };
  85. static struct resource snirm_53c710_rm200_rsrc[] = {
  86. {
  87. .start = 0x19000000,
  88. .end = 0x190fffff,
  89. .flags = IORESOURCE_MEM
  90. },
  91. {
  92. .start = 26,
  93. .end = 26,
  94. .flags = IORESOURCE_IRQ
  95. }
  96. };
  97. static struct platform_device snirm_53c710_rm200_pdev = {
  98. .name = "snirm_53c710",
  99. .num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
  100. .resource = snirm_53c710_rm200_rsrc
  101. };
  102. static int __init snirm_setup_devinit(void)
  103. {
  104. if (sni_brd_type == SNI_BRD_RM200) {
  105. platform_device_register(&rm200_serial8250_device);
  106. platform_device_register(&rm200_ds1216_device);
  107. platform_device_register(&snirm_82596_rm200_pdev);
  108. platform_device_register(&snirm_53c710_rm200_pdev);
  109. sni_eisa_root_init();
  110. }
  111. return 0;
  112. }
  113. device_initcall(snirm_setup_devinit);
  114. /*
  115. * RM200 has an ISA and an EISA bus. The iSA bus is only used
  116. * for onboard devices and also has twi i8259 PICs. Since these
  117. * PICs are no accessible via inb/outb the following code uses
  118. * readb/writeb to access them
  119. */
  120. static DEFINE_RAW_SPINLOCK(sni_rm200_i8259A_lock);
  121. #define PIC_CMD 0x00
  122. #define PIC_IMR 0x01
  123. #define PIC_ISR PIC_CMD
  124. #define PIC_POLL PIC_ISR
  125. #define PIC_OCW3 PIC_ISR
  126. /* i8259A PIC related value */
  127. #define PIC_CASCADE_IR 2
  128. #define MASTER_ICW4_DEFAULT 0x01
  129. #define SLAVE_ICW4_DEFAULT 0x01
  130. /*
  131. * This contains the irq mask for both 8259A irq controllers,
  132. */
  133. static unsigned int rm200_cached_irq_mask = 0xffff;
  134. static __iomem u8 *rm200_pic_master;
  135. static __iomem u8 *rm200_pic_slave;
  136. #define cached_master_mask (rm200_cached_irq_mask)
  137. #define cached_slave_mask (rm200_cached_irq_mask >> 8)
  138. static void sni_rm200_disable_8259A_irq(struct irq_data *d)
  139. {
  140. unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
  141. unsigned long flags;
  142. mask = 1 << irq;
  143. raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
  144. rm200_cached_irq_mask |= mask;
  145. if (irq & 8)
  146. writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
  147. else
  148. writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
  149. raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
  150. }
  151. static void sni_rm200_enable_8259A_irq(struct irq_data *d)
  152. {
  153. unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
  154. unsigned long flags;
  155. mask = ~(1 << irq);
  156. raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
  157. rm200_cached_irq_mask &= mask;
  158. if (irq & 8)
  159. writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
  160. else
  161. writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
  162. raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
  163. }
  164. static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
  165. {
  166. int value;
  167. int irqmask = 1 << irq;
  168. if (irq < 8) {
  169. writeb(0x0B, rm200_pic_master + PIC_CMD);
  170. value = readb(rm200_pic_master + PIC_CMD) & irqmask;
  171. writeb(0x0A, rm200_pic_master + PIC_CMD);
  172. return value;
  173. }
  174. writeb(0x0B, rm200_pic_slave + PIC_CMD); /* ISR register */
  175. value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
  176. writeb(0x0A, rm200_pic_slave + PIC_CMD);
  177. return value;
  178. }
  179. /*
  180. * Careful! The 8259A is a fragile beast, it pretty
  181. * much _has_ to be done exactly like this (mask it
  182. * first, _then_ send the EOI, and the order of EOI
  183. * to the two 8259s is important!
  184. */
  185. void sni_rm200_mask_and_ack_8259A(struct irq_data *d)
  186. {
  187. unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE;
  188. unsigned long flags;
  189. irqmask = 1 << irq;
  190. raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
  191. /*
  192. * Lightweight spurious IRQ detection. We do not want
  193. * to overdo spurious IRQ handling - it's usually a sign
  194. * of hardware problems, so we only do the checks we can
  195. * do without slowing down good hardware unnecessarily.
  196. *
  197. * Note that IRQ7 and IRQ15 (the two spurious IRQs
  198. * usually resulting from the 8259A-1|2 PICs) occur
  199. * even if the IRQ is masked in the 8259A. Thus we
  200. * can check spurious 8259A IRQs without doing the
  201. * quite slow i8259A_irq_real() call for every IRQ.
  202. * This does not cover 100% of spurious interrupts,
  203. * but should be enough to warn the user that there
  204. * is something bad going on ...
  205. */
  206. if (rm200_cached_irq_mask & irqmask)
  207. goto spurious_8259A_irq;
  208. rm200_cached_irq_mask |= irqmask;
  209. handle_real_irq:
  210. if (irq & 8) {
  211. readb(rm200_pic_slave + PIC_IMR);
  212. writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
  213. writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
  214. writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
  215. } else {
  216. readb(rm200_pic_master + PIC_IMR);
  217. writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
  218. writeb(0x60+irq, rm200_pic_master + PIC_CMD);
  219. }
  220. raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
  221. return;
  222. spurious_8259A_irq:
  223. /*
  224. * this is the slow path - should happen rarely.
  225. */
  226. if (sni_rm200_i8259A_irq_real(irq))
  227. /*
  228. * oops, the IRQ _is_ in service according to the
  229. * 8259A - not spurious, go handle it.
  230. */
  231. goto handle_real_irq;
  232. {
  233. static int spurious_irq_mask;
  234. /*
  235. * At this point we can be sure the IRQ is spurious,
  236. * let's ACK and report it. [once per IRQ]
  237. */
  238. if (!(spurious_irq_mask & irqmask)) {
  239. printk(KERN_DEBUG
  240. "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
  241. spurious_irq_mask |= irqmask;
  242. }
  243. atomic_inc(&irq_err_count);
  244. /*
  245. * Theoretically we do not have to handle this IRQ,
  246. * but in Linux this does not cause problems and is
  247. * simpler for us.
  248. */
  249. goto handle_real_irq;
  250. }
  251. }
  252. static struct irq_chip sni_rm200_i8259A_chip = {
  253. .name = "RM200-XT-PIC",
  254. .irq_mask = sni_rm200_disable_8259A_irq,
  255. .irq_unmask = sni_rm200_enable_8259A_irq,
  256. .irq_mask_ack = sni_rm200_mask_and_ack_8259A,
  257. };
  258. /*
  259. * Do the traditional i8259 interrupt polling thing. This is for the few
  260. * cases where no better interrupt acknowledge method is available and we
  261. * absolutely must touch the i8259.
  262. */
  263. static inline int sni_rm200_i8259_irq(void)
  264. {
  265. int irq;
  266. raw_spin_lock(&sni_rm200_i8259A_lock);
  267. /* Perform an interrupt acknowledge cycle on controller 1. */
  268. writeb(0x0C, rm200_pic_master + PIC_CMD); /* prepare for poll */
  269. irq = readb(rm200_pic_master + PIC_CMD) & 7;
  270. if (irq == PIC_CASCADE_IR) {
  271. /*
  272. * Interrupt is cascaded so perform interrupt
  273. * acknowledge on controller 2.
  274. */
  275. writeb(0x0C, rm200_pic_slave + PIC_CMD); /* prepare for poll */
  276. irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
  277. }
  278. if (unlikely(irq == 7)) {
  279. /*
  280. * This may be a spurious interrupt.
  281. *
  282. * Read the interrupt status register (ISR). If the most
  283. * significant bit is not set then there is no valid
  284. * interrupt.
  285. */
  286. writeb(0x0B, rm200_pic_master + PIC_ISR); /* ISR register */
  287. if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
  288. irq = -1;
  289. }
  290. raw_spin_unlock(&sni_rm200_i8259A_lock);
  291. return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
  292. }
  293. void sni_rm200_init_8259A(void)
  294. {
  295. unsigned long flags;
  296. raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
  297. writeb(0xff, rm200_pic_master + PIC_IMR);
  298. writeb(0xff, rm200_pic_slave + PIC_IMR);
  299. writeb(0x11, rm200_pic_master + PIC_CMD);
  300. writeb(0, rm200_pic_master + PIC_IMR);
  301. writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
  302. writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
  303. writeb(0x11, rm200_pic_slave + PIC_CMD);
  304. writeb(8, rm200_pic_slave + PIC_IMR);
  305. writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
  306. writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
  307. udelay(100); /* wait for 8259A to initialize */
  308. writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
  309. writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
  310. raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
  311. }
  312. /*
  313. * IRQ2 is cascade interrupt to second interrupt controller
  314. */
  315. static struct irqaction sni_rm200_irq2 = {
  316. .handler = no_action,
  317. .name = "cascade",
  318. .flags = IRQF_NO_THREAD,
  319. };
  320. static struct resource sni_rm200_pic1_resource = {
  321. .name = "onboard ISA pic1",
  322. .start = 0x16000020,
  323. .end = 0x16000023,
  324. .flags = IORESOURCE_BUSY
  325. };
  326. static struct resource sni_rm200_pic2_resource = {
  327. .name = "onboard ISA pic2",
  328. .start = 0x160000a0,
  329. .end = 0x160000a3,
  330. .flags = IORESOURCE_BUSY
  331. };
  332. /* ISA irq handler */
  333. static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
  334. {
  335. int irq;
  336. irq = sni_rm200_i8259_irq();
  337. if (unlikely(irq < 0))
  338. return IRQ_NONE;
  339. do_IRQ(irq);
  340. return IRQ_HANDLED;
  341. }
  342. struct irqaction sni_rm200_i8259A_irq = {
  343. .handler = sni_rm200_i8259A_irq_handler,
  344. .name = "onboard ISA",
  345. .flags = IRQF_SHARED
  346. };
  347. void __init sni_rm200_i8259_irqs(void)
  348. {
  349. int i;
  350. rm200_pic_master = ioremap_nocache(0x16000020, 4);
  351. if (!rm200_pic_master)
  352. return;
  353. rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
  354. if (!rm200_pic_slave) {
  355. iounmap(rm200_pic_master);
  356. return;
  357. }
  358. insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
  359. insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
  360. sni_rm200_init_8259A();
  361. for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
  362. irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip,
  363. handle_level_irq);
  364. setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
  365. }
  366. #define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
  367. #define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
  368. #define SNI_RM200_INT_START 24
  369. #define SNI_RM200_INT_END 28
  370. static void enable_rm200_irq(struct irq_data *d)
  371. {
  372. unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
  373. *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
  374. }
  375. void disable_rm200_irq(struct irq_data *d)
  376. {
  377. unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
  378. *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
  379. }
  380. static struct irq_chip rm200_irq_type = {
  381. .name = "RM200",
  382. .irq_mask = disable_rm200_irq,
  383. .irq_unmask = enable_rm200_irq,
  384. };
  385. static void sni_rm200_hwint(void)
  386. {
  387. u32 pending = read_c0_cause() & read_c0_status();
  388. u8 mask;
  389. u8 stat;
  390. int irq;
  391. if (pending & C_IRQ5)
  392. do_IRQ(MIPS_CPU_IRQ_BASE + 7);
  393. else if (pending & C_IRQ0) {
  394. clear_c0_status(IE_IRQ0);
  395. mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
  396. stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
  397. irq = ffs(stat & mask & 0x1f);
  398. if (likely(irq > 0))
  399. do_IRQ(irq + SNI_RM200_INT_START - 1);
  400. set_c0_status(IE_IRQ0);
  401. }
  402. }
  403. void __init sni_rm200_irq_init(void)
  404. {
  405. int i;
  406. * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
  407. sni_rm200_i8259_irqs();
  408. mips_cpu_irq_init();
  409. /* Actually we've got more interrupts to handle ... */
  410. for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
  411. irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
  412. sni_hwint = sni_rm200_hwint;
  413. change_c0_status(ST0_IM, IE_IRQ0);
  414. setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
  415. setup_irq(SNI_RM200_INT_START + 1, &sni_isa_irq);
  416. }
  417. void __init sni_rm200_init(void)
  418. {
  419. }