aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-x3proto
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-07-29 08:01:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-29 08:01:19 -0400
commitda2014a2b080e7f3024a4eb6917d47069ad9620b (patch)
treecfde12c6d4b5baa222966b14a676f107992cf786 /arch/sh/boards/mach-x3proto
parent71b8064e7df5698520d73b4c1566a3dbc98eb9ef (diff)
sh: Shuffle the board directories in to mach groups.
This flattens out the board directories in to individual mach groups, we will use this for getting rid of unneeded directories, simplifying the build system, and becoming more coherent with the refactored arch/sh/include topology. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/boards/mach-x3proto')
-rw-r--r--arch/sh/boards/mach-x3proto/Makefile1
-rw-r--r--arch/sh/boards/mach-x3proto/ilsel.c151
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c136
3 files changed, 288 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-x3proto/Makefile b/arch/sh/boards/mach-x3proto/Makefile
new file mode 100644
index 000000000000..983e4551fecf
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/Makefile
@@ -0,0 +1 @@
obj-y += setup.o ilsel.o
diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c
new file mode 100644
index 000000000000..b5c673c39337
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/ilsel.c
@@ -0,0 +1,151 @@
1/*
2 * arch/sh/boards/renesas/x3proto/ilsel.c
3 *
4 * Helper routines for SH-X3 proto board ILSEL.
5 *
6 * Copyright (C) 2007 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/bitmap.h>
16#include <linux/io.h>
17#include <asm/ilsel.h>
18
19/*
20 * ILSEL is split across:
21 *
22 * ILSEL0 - 0xb8100004 [ Levels 1 - 4 ]
23 * ILSEL1 - 0xb8100006 [ Levels 5 - 8 ]
24 * ILSEL2 - 0xb8100008 [ Levels 9 - 12 ]
25 * ILSEL3 - 0xb810000a [ Levels 13 - 15 ]
26 *
27 * With each level being relative to an ilsel_source_t.
28 */
29#define ILSEL_BASE 0xb8100004
30#define ILSEL_LEVELS 15
31
32/*
33 * ILSEL level map, in descending order from the highest level down.
34 *
35 * Supported levels are 1 - 15 spread across ILSEL0 - ILSEL4, mapping
36 * directly to IRLs. As the IRQs are numbered in reverse order relative
37 * to the interrupt level, the level map is carefully managed to ensure a
38 * 1:1 mapping between the bit position and the IRQ number.
39 *
40 * This careful constructions allows ilsel_enable*() to be referenced
41 * directly for hooking up an ILSEL set and getting back an IRQ which can
42 * subsequently be used for internal accounting in the (optional) disable
43 * path.
44 */
45static unsigned long ilsel_level_map;
46
47static inline unsigned int ilsel_offset(unsigned int bit)
48{
49 return ILSEL_LEVELS - bit - 1;
50}
51
52static inline unsigned long mk_ilsel_addr(unsigned int bit)
53{
54 return ILSEL_BASE + ((ilsel_offset(bit) >> 1) & ~0x1);
55}
56
57static inline unsigned int mk_ilsel_shift(unsigned int bit)
58{
59 return (ilsel_offset(bit) & 0x3) << 2;
60}
61
62static void __ilsel_enable(ilsel_source_t set, unsigned int bit)
63{
64 unsigned int tmp, shift;
65 unsigned long addr;
66
67 addr = mk_ilsel_addr(bit);
68 shift = mk_ilsel_shift(bit);
69
70 pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n",
71 __func__, bit, addr, shift, set);
72
73 tmp = ctrl_inw(addr);
74 tmp &= ~(0xf << shift);
75 tmp |= set << shift;
76 ctrl_outw(tmp, addr);
77}
78
79/**
80 * ilsel_enable - Enable an ILSEL set.
81 * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h).
82 *
83 * Enables a given non-aliased ILSEL source (<= ILSEL_KEY) at the highest
84 * available interrupt level. Callers should take care to order callsites
85 * noting descending interrupt levels. Aliasing FPGA and external board
86 * IRQs need to use ilsel_enable_fixed().
87 *
88 * The return value is an IRQ number that can later be taken down with
89 * ilsel_disable().
90 */
91int ilsel_enable(ilsel_source_t set)
92{
93 unsigned int bit;
94
95 /* Aliased sources must use ilsel_enable_fixed() */
96 BUG_ON(set > ILSEL_KEY);
97
98 do {
99 bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS);
100 } while (test_and_set_bit(bit, &ilsel_level_map));
101
102 __ilsel_enable(set, bit);
103
104 return bit;
105}
106EXPORT_SYMBOL_GPL(ilsel_enable);
107
108/**
109 * ilsel_enable_fixed - Enable an ILSEL set at a fixed interrupt level
110 * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h).
111 * @level: Interrupt level (1 - 15)
112 *
113 * Enables a given ILSEL source at a fixed interrupt level. Necessary
114 * both for level reservation as well as for aliased sources that only
115 * exist on special ILSEL#s.
116 *
117 * Returns an IRQ number (as ilsel_enable()).
118 */
119int ilsel_enable_fixed(ilsel_source_t set, unsigned int level)
120{
121 unsigned int bit = ilsel_offset(level - 1);
122
123 if (test_and_set_bit(bit, &ilsel_level_map))
124 return -EBUSY;
125
126 __ilsel_enable(set, bit);
127
128 return bit;
129}
130EXPORT_SYMBOL_GPL(ilsel_enable_fixed);
131
132/**
133 * ilsel_disable - Disable an ILSEL set
134 * @irq: Bit position for ILSEL set value (retval from enable routines)
135 *
136 * Disable a previously enabled ILSEL set.
137 */
138void ilsel_disable(unsigned int irq)
139{
140 unsigned long addr;
141 unsigned int tmp;
142
143 addr = mk_ilsel_addr(irq);
144
145 tmp = ctrl_inw(addr);
146 tmp &= ~(0xf << mk_ilsel_shift(irq));
147 ctrl_outw(tmp, addr);
148
149 clear_bit(irq, &ilsel_level_map);
150}
151EXPORT_SYMBOL_GPL(ilsel_disable);
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
new file mode 100644
index 000000000000..abc5b6d418fe
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -0,0 +1,136 @@
1/*
2 * arch/sh/boards/renesas/x3proto/setup.c
3 *
4 * Renesas SH-X3 Prototype Board Support.
5 *
6 * Copyright (C) 2007 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/kernel.h>
15#include <linux/io.h>
16#include <asm/ilsel.h>
17
18static struct resource heartbeat_resources[] = {
19 [0] = {
20 .start = 0xb8140020,
21 .end = 0xb8140020,
22 .flags = IORESOURCE_MEM,
23 },
24};
25
26static struct platform_device heartbeat_device = {
27 .name = "heartbeat",
28 .id = -1,
29 .num_resources = ARRAY_SIZE(heartbeat_resources),
30 .resource = heartbeat_resources,
31};
32
33static struct resource smc91x_resources[] = {
34 [0] = {
35 .start = 0x18000300,
36 .end = 0x18000300 + 0x10 - 1,
37 .flags = IORESOURCE_MEM,
38 },
39 [1] = {
40 /* Filled in by ilsel */
41 .flags = IORESOURCE_IRQ,
42 },
43};
44
45static struct platform_device smc91x_device = {
46 .name = "smc91x",
47 .id = -1,
48 .resource = smc91x_resources,
49 .num_resources = ARRAY_SIZE(smc91x_resources),
50};
51
52static struct resource r8a66597_usb_host_resources[] = {
53 [0] = {
54 .name = "r8a66597_hcd",
55 .start = 0x18040000,
56 .end = 0x18080000 - 1,
57 .flags = IORESOURCE_MEM,
58 },
59 [1] = {
60 .name = "r8a66597_hcd",
61 /* Filled in by ilsel */
62 .flags = IORESOURCE_IRQ,
63 },
64};
65
66static struct platform_device r8a66597_usb_host_device = {
67 .name = "r8a66597_hcd",
68 .id = -1,
69 .dev = {
70 .dma_mask = NULL, /* don't use dma */
71 .coherent_dma_mask = 0xffffffff,
72 },
73 .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources),
74 .resource = r8a66597_usb_host_resources,
75};
76
77static struct resource m66592_usb_peripheral_resources[] = {
78 [0] = {
79 .name = "m66592_udc",
80 .start = 0x18080000,
81 .end = 0x180c0000 - 1,
82 .flags = IORESOURCE_MEM,
83 },
84 [1] = {
85 .name = "m66592_udc",
86 /* Filled in by ilsel */
87 .flags = IORESOURCE_IRQ,
88 },
89};
90
91static struct platform_device m66592_usb_peripheral_device = {
92 .name = "m66592_udc",
93 .id = -1,
94 .dev = {
95 .dma_mask = NULL, /* don't use dma */
96 .coherent_dma_mask = 0xffffffff,
97 },
98 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
99 .resource = m66592_usb_peripheral_resources,
100};
101
102static struct platform_device *x3proto_devices[] __initdata = {
103 &heartbeat_device,
104 &smc91x_device,
105 &r8a66597_usb_host_device,
106 &m66592_usb_peripheral_device,
107};
108
109static int __init x3proto_devices_setup(void)
110{
111 r8a66597_usb_host_resources[1].start =
112 r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
113
114 m66592_usb_peripheral_resources[1].start =
115 m66592_usb_peripheral_resources[1].end = ilsel_enable(ILSEL_USBP_I);
116
117 smc91x_resources[1].start =
118 smc91x_resources[1].end = ilsel_enable(ILSEL_LAN);
119
120 return platform_add_devices(x3proto_devices,
121 ARRAY_SIZE(x3proto_devices));
122}
123device_initcall(x3proto_devices_setup);
124
125static void __init x3proto_init_irq(void)
126{
127 plat_irq_setup_pins(IRQ_MODE_IRL3210);
128
129 /* Set ICR0.LVLMODE */
130 ctrl_outl(ctrl_inl(0xfe410000) | (1 << 21), 0xfe410000);
131}
132
133static struct sh_machine_vector mv_x3proto __initmv = {
134 .mv_name = "x3proto",
135 .mv_init_irq = x3proto_init_irq,
136};