blob: 6651e3285fcf4c591086b434751a5cb414f27a98 [file] [log] [blame]
Johannes Weiner000af2c2009-03-04 16:21:32 +01001/*
2 * s6000 irq crossbar
3 *
4 * Copyright (c) 2009 emlix GmbH
5 * Authors: Johannes Weiner <jw@emlix.com>
6 * Oskar Schirmer <os@emlix.com>
7 */
8#include <linux/io.h>
9#include <asm/irq.h>
10#include <variant/hardware.h>
11
12/* S6_REG_INTC */
13#define INTC_STATUS 0x000
14#define INTC_RAW 0x010
15#define INTC_STATUS_AG 0x100
16#define INTC_CFG(n) (0x200 + 4 * (n))
17
18/*
19 * The s6000 has a crossbar that multiplexes interrupt output lines
20 * from the peripherals to input lines on the xtensa core.
21 *
22 * We leave the mapping decisions to the platform as it depends on the
23 * actually connected peripherals which distribution makes sense.
24 */
25extern const signed char *platform_irq_mappings[NR_IRQS];
26
27static unsigned long scp_to_intc_enable[] = {
28#define TO_INTC_ENABLE(n) (((n) << 1) + 1)
29 TO_INTC_ENABLE(0),
30 TO_INTC_ENABLE(1),
31 TO_INTC_ENABLE(2),
32 TO_INTC_ENABLE(3),
33 TO_INTC_ENABLE(4),
34 TO_INTC_ENABLE(5),
35 TO_INTC_ENABLE(6),
36 TO_INTC_ENABLE(7),
37 TO_INTC_ENABLE(8),
38 TO_INTC_ENABLE(9),
39 TO_INTC_ENABLE(10),
40 TO_INTC_ENABLE(11),
41 TO_INTC_ENABLE(12),
42 -1,
43 -1,
44 TO_INTC_ENABLE(13),
45 -1,
46 TO_INTC_ENABLE(14),
47 -1,
48 TO_INTC_ENABLE(15),
49#undef TO_INTC_ENABLE
50};
51
52static void irq_set(unsigned int irq, int enable)
53{
54 unsigned long en;
55 const signed char *m = platform_irq_mappings[irq];
56
57 if (!m)
58 return;
59 en = enable ? scp_to_intc_enable[irq] : 0;
60 while (*m >= 0) {
61 writel(en, S6_REG_INTC + INTC_CFG(*m));
62 m++;
63 }
64}
65
66void variant_irq_enable(unsigned int irq)
67{
68 irq_set(irq, 1);
69}
70
71void variant_irq_disable(unsigned int irq)
72{
73 irq_set(irq, 0);
74}