rm200.c 12 KB

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