163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* IO interface mux allocator for ETRAX100LX.
2b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson * Copyright 2004-2007, Axis Communications AB
363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik */
463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
6b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <linux/kernel.h>
963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <linux/slab.h>
1063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <linux/errno.h>
1163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <linux/module.h>
1263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <linux/init.h>
1363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
14556dcee7b829e5c350c3ffdbdb87a8b15aa3c5d3Jesper Nilsson#include <arch/svinto.h>
1563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#include <asm/io.h>
16556dcee7b829e5c350c3ffdbdb87a8b15aa3c5d3Jesper Nilsson#include <arch/io_interface_mux.h>
17b1a154dbf9ddbf396578642299ce75aa73d01763David Howells#include <arch/system.h>
1863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
1963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
2063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#define DBG(s)
2163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
2263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* Macro to access ETRAX 100 registers */
2363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
2463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik					  IO_STATE_(reg##_, field##_, _##val)
2563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
2663245d2cde2be64f172388c2c50862f233c05700Mikael Starvikenum io_if_group {
2763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_a = (1<<0),
2863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_b = (1<<1),
2963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_c = (1<<2),
3063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_d = (1<<3),
3163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_e = (1<<4),
3263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_f = (1<<5)
3363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
3463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
3563245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstruct watcher
3663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
3763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	void (*notify)(const unsigned int gpio_in_available,
3863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       const unsigned int gpio_out_available,
3963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       const unsigned char pa_available,
4063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       const unsigned char pb_available);
4163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct watcher *next;
4263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
4363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
4463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
4563245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstruct if_group
4663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
4763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	enum io_if_group        group;
48b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* name	- the name of the group 'A' to 'F' */
49b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	char                   *name;
50b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* used	- a bit mask of all pins in the group in the order listed
51b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * in the tables in 19.9.1 to 19.9.6.  Note that no
52b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * distinction is made between in, out and in/out pins. */
53b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int            used;
5463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
5563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
5663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
5763245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstruct interface
5863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
5963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	enum cris_io_interface   ioif;
60b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* name - the name of the interface */
61b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	char                    *name;
62b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* groups - OR'ed together io_if_group flags describing what pin groups
63b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * the interface uses pins in. */
6463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned char            groups;
65b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* used - set when the interface is allocated. */
6663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned char            used;
6763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	char                    *owner;
68b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* group_a through group_f - bit masks describing what pins in the
69b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * pin groups the interface uses. */
70b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_a;
71b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_b;
72b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_c;
73b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_d;
74b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_e;
75b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	unsigned int             group_f;
76b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
77b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
78b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * GPIO ports the interface uses.  This could be reconstucted using
79b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * the group_X masks and a table of what pins the GPIO ports use,
80b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * but that would be messy. */
8163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int             gpio_g_in;
8263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int             gpio_g_out;
8363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned char            gpio_b;
8463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
8563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
8663245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic struct if_group if_groups[6] = {
8763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
8863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_a,
89b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "A",
9063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
9163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
9263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
9363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_b,
94b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "B",
9563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
9663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
9763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
9863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_c,
99b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "C",
10063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
10163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
10263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
10363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_d,
104b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "D",
10563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
10663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
10763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
10863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_e,
109b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "E",
11063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
11163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
11263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
11363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.group = group_f,
114b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "F",
11563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.used = 0,
11663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
11763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
11863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
11963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* The order in the array must match the order of enum
12063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik * cris_io_interface in io_interface_mux.h */
12163245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic struct interface interfaces[] = {
12263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* Begin Non-multiplexed interfaces */
12363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
12463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_eth,
125b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "ethernet",
12663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = 0,
127b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
128b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
129b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
130b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
131b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
132b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
133b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
134b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
13563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in = 0,
13663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0,
13763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0
13863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
13963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
14063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_serial_0,
141b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "serial_0",
14263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = 0,
143b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
144b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
145b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
146b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
147b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
148b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
149b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
150b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
15163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in = 0,
15263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0,
15363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0
15463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
15563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* End Non-multiplexed interfaces */
15663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
15763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_serial_1,
158b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "serial_1",
15963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_e,
160b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
161b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
162b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
163b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
164b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
165b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0x0f,
166b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
167b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
16863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
16963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
17063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
17163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
17263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
17363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_serial_2,
174b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "serial_2",
17563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_b,
176b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
177b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
178b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0x0f,
179b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
180b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
181b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
182b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
183b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
18463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x000000c0,
18563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x000000c0,
18663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
18763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
18863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
18963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_serial_3,
190b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "serial_3",
19163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_c,
192b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
193b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
194b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
195b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0x0f,
196b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
197b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
198b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
199b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
20063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0xc0000000,
20163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0xc0000000,
20263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
20363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
20463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
20563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_sync_serial_1,
206b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "sync_serial_1",
207b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.groups = group_e | group_f,
208b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
209b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
210b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
211b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
212b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
213b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0x0f,
214b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x10,
215b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
21663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
21763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
21863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x10
21963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
22063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
22163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_sync_serial_3,
222b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "sync_serial_3",
22363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_c | group_f,
224b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
225b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
226b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
227b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0x0f,
228b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
229b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
230b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x80,
231b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
23263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0xc0000000,
23363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0xc0000000,
23463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x80
23563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
23663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
23763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_shared_ram,
238b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "shared_ram",
23963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a,
240b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
241b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7f8ff,
242b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
243b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
244b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
245b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
246b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
247b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
24863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x0000ff3e,
24963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x0000ff38,
25063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
25163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
25263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
25363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_shared_ram_w,
254b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "shared_ram_w",
25563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a | group_d,
256b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
257b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7f8ff,
258b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
259b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
260b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0xff,
261b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
262b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
263b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
26463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00ffff3e,
26563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00ffff38,
26663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
26763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
26863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
26963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_par_0,
270b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "par_0",
27163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a,
272b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
273b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7fbff,
274b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
275b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
276b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
277b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
278b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
279b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
28063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x0000ff3e,
28163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x0000ff3e,
28263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
28363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
28463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
28563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_par_1,
286b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "par_1",
28763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_d,
288b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
289b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
290b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
291b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
292b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0x7feff,
293b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
294b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
295b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
29663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x3eff0000,
29763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x3eff0000,
29863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
29963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
30063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
30163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_par_w,
302b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "par_w",
30363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a | group_d,
304b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
305b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7fbff,
306b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
307b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
308b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0xff,
309b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
310b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
311b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
31263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00ffff3e,
31363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00ffff3e,
31463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
31563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
31663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
31763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_scsi8_0,
318b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "scsi8_0",
319b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.groups = group_a | group_b | group_f,
320b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
321b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7ffff,
322b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0x0f,
323b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
324b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
325b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
326b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x10,
327b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
32863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x0000ffff,
32963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x0000ffff,
33063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x10
33163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
33263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
33363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_scsi8_1,
334b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "scsi8_1",
335b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.groups = group_c | group_d | group_f,
336b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
337b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
338b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
339b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0x0f,
340b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0x7ffff,
341b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
342b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x80,
343b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
34463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0xffff0000,
34563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0xffff0000,
34663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x80
34763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
34863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
34963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_scsi_w,
350b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "scsi_w",
35163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a | group_b | group_d | group_f,
352b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
353b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7ffff,
354b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0x0f,
355b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
356b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0x601ff,
357b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
358b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x90,
359b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
36063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x01ffffff,
36163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x07ffffff,
36263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x80
36363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
36463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
36563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_ata,
366b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "ata",
36763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a | group_b | group_c | group_d,
368b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
369b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0x7ffff,
370b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0x0f,
371b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0x0f,
372b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0x7cfff,
373b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
374b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
375b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
37663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0xf9ffffff,
37763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0xffffffff,
37863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x80
37963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
38063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
38163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_csp,
382b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "csp",
383b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.groups = group_f,
384b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
385b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
386b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
387b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
388b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
389b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
390b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0xfc,
391b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
39263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
39363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
39463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0xfc
39563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
39663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
39763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_i2c,
398b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "i2c",
399b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.groups = group_f,
400b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
401b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
402b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
403b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
404b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
405b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
406b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x03,
407b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
40863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
40963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
41063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x03
41163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
41263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
41363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_usb_1,
414b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "usb_1",
41563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_e | group_f,
416b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
417b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
418b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
419b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
420b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
421b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0x0f,
422b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0x2c,
423b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
42463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
42563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
42663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x2c
42763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
42863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
42963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_usb_2,
430b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "usb_2",
43163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_d,
432b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
433b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
434b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
435b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
436b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
437b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0x33e00,
438b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
439b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
440b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.gpio_g_in =  0x3e000000,
441b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.gpio_g_out = 0x0c000000,
44263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
44363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
44463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* GPIO pins */
44563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
44663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_a,
447b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_a",
44863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_a,
449b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
450b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
451b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
452b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
453b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
454b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
455b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
456b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
45763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x0000ff3f,
45863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x0000ff3f,
45963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
46063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
46163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
46263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_b,
463b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_b",
46463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_b,
465b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
466b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
467b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
468b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
469b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
470b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
471b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
472b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
47363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x000000c0,
47463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x000000c0,
47563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
47663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
47763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
47863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_c,
479b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_c",
48063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_c,
481b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
482b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
483b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
484b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
485b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
486b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
487b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
488b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
48963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0xc0000000,
49063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0xc0000000,
49163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
49263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
49363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
49463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_d,
495b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_d",
49663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_d,
497b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
498b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
499b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
500b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
501b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
502b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
503b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
504b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
50563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x3fff0000,
50663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x3fff0000,
50763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
50863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
50963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
51063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_e,
511b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_e",
51263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_e,
513b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
514b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
515b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
516b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
517b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
518b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
519b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
520b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
52163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
52263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
52363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0x00
52463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	},
52563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
52663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.ioif = if_gpio_grp_f,
527b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.name = "gpio_f",
52863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.groups = group_f,
529b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
530b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_a = 0,
531b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_b = 0,
532b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_c = 0,
533b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_d = 0,
534b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_e = 0,
535b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		.group_f = 0,
536b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
53763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_in =  0x00000000,
53863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_g_out = 0x00000000,
53963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		.gpio_b = 0xff
54063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
54163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* Array end */
54263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik};
54363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
54463245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic struct watcher *watchers = NULL;
54563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
546b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson/* The pins that are free to use in the GPIO ports. */
54763245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic unsigned int gpio_in_pins =  0xffffffff;
54863245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic unsigned int gpio_out_pins = 0xffffffff;
54963245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic unsigned char gpio_pb_pins = 0xff;
55063245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic unsigned char gpio_pa_pins = 0xff;
55163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
552b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson/* Identifiers for the owners of the GPIO pins. */
55363245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic enum cris_io_interface gpio_pa_owners[8];
55463245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic enum cris_io_interface gpio_pb_owners[8];
55563245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic enum cris_io_interface gpio_pg_owners[32];
55663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
55763245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic int cris_io_interface_init(void);
55863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
55963245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
56063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
56163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return (groups & ~group->group);
56263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
56363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
56463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
56563245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic struct if_group *get_group(const unsigned char groups)
56663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
56763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	int i;
56816ad1b49104684da3ab0fede79f29b01f4c76896Alex Unleashed	for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
56963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if (groups & if_groups[i].group) {
57063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			return &if_groups[i];
57163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
57263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
57363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return NULL;
57463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
57563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
57663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
57763245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic void notify_watchers(void)
57863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
57963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct watcher *w = watchers;
58063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
58163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("io_interface_mux: notifying watchers\n"));
58263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
58363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	while (NULL != w) {
58463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		w->notify((const unsigned int)gpio_in_pins,
58563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			  (const unsigned int)gpio_out_pins,
58663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			  (const unsigned char)gpio_pa_pins,
58763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			  (const unsigned char)gpio_pb_pins);
58863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		w = w->next;
58963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
59063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
59163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
59263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
59363245d2cde2be64f172388c2c50862f233c05700Mikael Starvikint cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
59463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
59563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	int set_gen_config = 0;
59663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	int set_gen_config_ii = 0;
59763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long int gens;
59863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long int gens_ii;
59963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct if_group *grp;
60063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned char group_set;
60163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long flags;
602b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	int res = 0;
60363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
60463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
60563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
60663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
60763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
60863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if ((ioif >= if_max_interfaces) || (ioif < 0)) {
609b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		printk(KERN_CRIT "cris_request_io_interface: Bad interface "
610b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			"%u submitted for %s\n",
61163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       ioif,
61263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       device_id);
61363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -EINVAL;
61463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
61563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
61663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_save(flags);
61763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
61863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (interfaces[ioif].used) {
619b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
620b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			"%s for %s, in use by %s\n",
621b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		       interfaces[ioif].name,
62263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       device_id,
62363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       interfaces[ioif].owner);
624b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		res = -EBUSY;
625b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		goto exit;
62663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
62763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
628b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* Check that all required pins in the used groups are free
629b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	 * before allocating. */
63063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_set = interfaces[ioif].groups;
63163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	while (NULL != (grp = get_group(group_set))) {
632b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		unsigned int if_group_use = 0;
633b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
634b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		switch (grp->group) {
635b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_a:
636b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_a;
637b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
638b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_b:
639b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_b;
640b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
641b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_c:
642b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_c;
643b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
644b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_d:
645b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_d;
646b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
647b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_e:
648b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_e;
649b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
650b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_f:
651b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_f;
652b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
653b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		default:
654b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			BUG_ON(1);
655b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		}
656b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
657b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		if (if_group_use & grp->used) {
658b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			printk(KERN_INFO "cris_request_io_interface: group "
659b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson				"%s needed by %s not available\n",
660b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson				grp->name, interfaces[ioif].name);
661b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			res = -EBUSY;
662b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			goto exit;
66363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
664b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
66563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		group_set = clear_group_from_set(group_set, grp);
66663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
66763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
66863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* Are the required GPIO pins available too? */
669b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
670b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			interfaces[ioif].gpio_g_in) ||
671b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
672b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			interfaces[ioif].gpio_g_out) ||
673b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		((interfaces[ioif].gpio_b & gpio_pb_pins) !=
674b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			interfaces[ioif].gpio_b)) {
675b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		printk(KERN_CRIT "cris_request_io_interface: Could not get "
676b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			"required pins for interface %u\n", ioif);
677b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		res = -EBUSY;
678b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		goto exit;
67963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
68063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
681b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* Check which registers need to be reconfigured. */
68263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gens = genconfig_shadow;
68363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gens_ii = gen_config_ii_shadow;
68463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
68563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	set_gen_config = 1;
68663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	switch (ioif)
68763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	{
68863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* Begin Non-multiplexed interfaces */
68963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_eth:
69063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
69163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_serial_0:
69263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config = 0;
69363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
69463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* End Non-multiplexed interfaces */
69563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_serial_1:
69663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config_ii = 1;
69763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
69863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
69963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_serial_2:
70063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, ser2, select);
70163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
70263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_serial_3:
70363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, ser3, select);
70463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config_ii = 1;
70563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
70663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
70763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_sync_serial_1:
70863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config_ii = 1;
70963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
71063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
71163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_sync_serial_3:
71263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, ser3, select);
71363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config_ii = 1;
71463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
71563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
71663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_shared_ram:
71763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, mio, select);
71863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
71963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_shared_ram_w:
72063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, mio_w, select);
72163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
72263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_par_0:
72363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, par0, select);
72463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
72563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_par_1:
72663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, par1, select);
72763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
72863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_par_w:
72963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, par0, select);
73063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, par_w, select);
73163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
73263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_scsi8_0:
73363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, scsi0, select);
73463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
73563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_scsi8_1:
73663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, scsi1, select);
73763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
73863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_scsi_w:
73963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, scsi0, select);
74063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, scsi0w, select);
74163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
74263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_ata:
74363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, ata, select);
74463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
74563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_csp:
74663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
74763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_i2c:
74863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config = 0;
74963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
75063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_usb_1:
75163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, usb1, select);
75263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
75363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_usb_2:
75463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		SETS(gens, R_GEN_CONFIG, usb2, select);
75563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
75663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_a:
75763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* GPIO groups are only accounted, don't do configuration changes. */
75863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
75963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_b:
76063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
76163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_c:
76263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
76363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_d:
76463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
76563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_e:
76663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* fall through */
76763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case if_gpio_grp_f:
76863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		set_gen_config = 0;
76963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
77063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	default:
771b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		printk(KERN_INFO "cris_request_io_interface: Bad interface "
772b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			"%u submitted for %s\n",
773b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			ioif, device_id);
774b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		res = -EBUSY;
775b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		goto exit;
776b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	}
777b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
778b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	/* All needed I/O pins and pin groups are free, allocate. */
779b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	group_set = interfaces[ioif].groups;
780b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	while (NULL != (grp = get_group(group_set))) {
781b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		unsigned int if_group_use = 0;
782b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
783b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		switch (grp->group) {
784b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_a:
785b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_a;
786b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
787b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_b:
788b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_b;
789b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
790b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_c:
791b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_c;
792b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
793b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_d:
794b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_d;
795b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
796b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_e:
797b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_e;
798b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
799b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_f:
800b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_f;
801b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
802b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		default:
803b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			BUG_ON(1);
804b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		}
805b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		grp->used |= if_group_use;
806b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
807b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		group_set = clear_group_from_set(group_set, grp);
80863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
80963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
81063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	interfaces[ioif].used = 1;
81163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	interfaces[ioif].owner = (char*)device_id;
81263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
81363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (set_gen_config) {
81463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		volatile int i;
81563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		genconfig_shadow = gens;
81663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		*R_GEN_CONFIG = genconfig_shadow;
81763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		/* Wait 12 cycles before doing any DMA command */
81863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		for(i = 6; i > 0; i--)
81963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			nop();
82063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
82163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (set_gen_config_ii) {
82263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gen_config_ii_shadow = gens_ii;
82363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		*R_GEN_CONFIG_II = gen_config_ii_shadow;
82463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
82563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
826b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	DBG(printk(KERN_DEBUG "GPIO pins: available before: "
827b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		"g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
828b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		gpio_in_pins, gpio_out_pins, gpio_pb_pins));
829b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	DBG(printk(KERN_DEBUG
830b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		"grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
831b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		interfaces[ioif].gpio_g_in,
832b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		interfaces[ioif].gpio_g_out,
833b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		interfaces[ioif].gpio_b));
83463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
83563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
83663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
83763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_pb_pins &= ~interfaces[ioif].gpio_b;
83863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
839b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	DBG(printk(KERN_DEBUG "GPIO pins: available after: "
840b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		"g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
841b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		gpio_in_pins, gpio_out_pins, gpio_pb_pins));
84263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
843b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilssonexit:
84463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_restore(flags);
845b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	if (res == 0)
846b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		notify_watchers();
847b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson	return res;
84863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
84963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
85063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
85163245d2cde2be64f172388c2c50862f233c05700Mikael Starvikvoid cris_free_io_interface(enum cris_io_interface ioif)
85263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
85363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct if_group *grp;
85463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned char group_set;
85563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long flags;
85663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
85763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
85863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
85963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if ((ioif >= if_max_interfaces) || (ioif < 0)) {
86063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
86163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       ioif);
86263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return;
86363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
86463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_save(flags);
86563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (!interfaces[ioif].used) {
86663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
86763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		       ioif);
86863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		local_irq_restore(flags);
86963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return;
87063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
87163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	group_set = interfaces[ioif].groups;
87263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	while (NULL != (grp = get_group(group_set))) {
873b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		unsigned int if_group_use = 0;
874b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
875b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		switch (grp->group) {
876b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_a:
877b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_a;
878b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
879b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_b:
880b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_b;
881b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
882b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_c:
883b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_c;
884b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
885b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_d:
886b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_d;
887b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
888b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_e:
889b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_e;
890b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
891b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		case group_f:
892b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			if_group_use = interfaces[ioif].group_f;
893b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			break;
894b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		default:
895b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			BUG_ON(1);
89663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
897b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
898b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		if ((grp->used & if_group_use) != if_group_use)
899b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson			BUG_ON(1);
900b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson		grp->used = grp->used & ~if_group_use;
901b1220e2e7f03a0e86078c82819e802c25047638dJesper Nilsson
90263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		group_set = clear_group_from_set(group_set, grp);
90363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
90463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	interfaces[ioif].used = 0;
90563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	interfaces[ioif].owner = NULL;
90663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
90763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
90863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
90963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
91063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   interfaces[ioif].gpio_g_in,
91163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   interfaces[ioif].gpio_g_out,
91263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   interfaces[ioif].gpio_b));
91363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
91463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_in_pins |= interfaces[ioif].gpio_g_in;
91563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_out_pins |= interfaces[ioif].gpio_g_out;
91663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	gpio_pb_pins |= interfaces[ioif].gpio_b;
91763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
91863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
91963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
92063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
92163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_restore(flags);
92263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
92363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	notify_watchers();
92463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
92563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
92663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* Create a bitmask from bit 0 (inclusive) to bit stop_bit
92763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik   (non-inclusive).  stop_bit == 0 returns 0x0 */
92863245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic inline unsigned int create_mask(const unsigned stop_bit)
92963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
93063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* Avoid overflow */
93163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (stop_bit >= 32) {
93263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return 0xffffffff;
93363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
93463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return (1<<stop_bit)-1;
93563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
93663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
93763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
93863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* port can be 'a', 'b' or 'g' */
93963245d2cde2be64f172388c2c50862f233c05700Mikael Starvikint cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
94063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik				    const char port,
94163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik				    const unsigned start_bit,
94263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik				    const unsigned stop_bit)
94363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
94463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int i;
94563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int mask = 0;
94663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int tmp_mask;
94763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long int flags;
94863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	enum cris_io_interface *owners;
94963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
95063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
95163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
95263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
95363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   ioif, port, start_bit, stop_bit));
95463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
95563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (!((start_bit <= stop_bit) &&
95663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	      ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
95763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	       ((port == 'g') && (stop_bit < 32))))) {
95863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -EINVAL;
95963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
96063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
96163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	mask = create_mask(stop_bit + 1);
96263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	tmp_mask = create_mask(start_bit);
96363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	mask &= ~tmp_mask;
96463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
96563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
96663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   port, start_bit, stop_bit, mask));
96763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
96863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_save(flags);
96963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
97063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	switch (port) {
97163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'a':
97263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if ((gpio_pa_pins & mask) != mask) {
97363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
97463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			return -EBUSY;
97563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
97663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pa_owners;
97763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pa_pins &= ~mask;
97863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
97963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'b':
98063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if ((gpio_pb_pins & mask) != mask) {
98163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
98263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			return -EBUSY;
98363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
98463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pb_owners;
98563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pb_pins &= ~mask;
98663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
98763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'g':
98863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if (((gpio_in_pins & mask) != mask) ||
98963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		    ((gpio_out_pins & mask) != mask)) {
99063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
99163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			return -EBUSY;
99263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
99363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pg_owners;
99463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_in_pins &= ~mask;
99563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_out_pins &= ~mask;
99663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
99763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	default:
99863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		local_irq_restore(flags);
99963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -EINVAL;
100063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
100163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
100263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	for (i = start_bit; i <= stop_bit; i++) {
100363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners[i] = ioif;
100463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
100563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_restore(flags);
100663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
100763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	notify_watchers();
100863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return 0;
100963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
101063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
101163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
101263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik/* port can be 'a', 'b' or 'g' */
101363245d2cde2be64f172388c2c50862f233c05700Mikael Starvikint cris_io_interface_free_pins(const enum cris_io_interface ioif,
101463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                const char port,
101563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                const unsigned start_bit,
101663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                const unsigned stop_bit)
101763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
101863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int i;
101963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int mask = 0;
102063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned int tmp_mask;
102163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	unsigned long int flags;
102263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	enum cris_io_interface *owners;
102363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
102463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
102563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
102663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (!((start_bit <= stop_bit) &&
102763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	      ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
102863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	       ((port == 'g') && (stop_bit < 32))))) {
102963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -EINVAL;
103063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
103163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
103263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	mask = create_mask(stop_bit + 1);
103363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	tmp_mask = create_mask(start_bit);
103463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	mask &= ~tmp_mask;
103563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
103663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
103763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		   port, start_bit, stop_bit, mask));
103863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
103963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_save(flags);
104063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
104163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	switch (port) {
104263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'a':
104363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if ((~gpio_pa_pins & mask) != mask) {
104463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
104563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
104663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
104763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pa_owners;
104863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
104963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'b':
105063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if ((~gpio_pb_pins & mask) != mask) {
105163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
105263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
105363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
105463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pb_owners;
105563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
105663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'g':
105763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if (((~gpio_in_pins & mask) != mask) ||
105863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		    ((~gpio_out_pins & mask) != mask)) {
105963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			local_irq_restore(flags);
106063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
106163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
106263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = gpio_pg_owners;
106363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
106463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	default:
106563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners = NULL; /* Cannot happen. Shut up, gcc! */
106663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
106763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
106863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	for (i = start_bit; i <= stop_bit; i++) {
106963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if (owners[i] != ioif) {
107063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
107163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
107263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
107363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
107463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	/* All was ok, change data. */
107563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	switch (port) {
107663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'a':
107763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pa_pins |= mask;
107863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
107963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'b':
108063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pb_pins |= mask;
108163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
108263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	case 'g':
108363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_in_pins |= mask;
108463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_out_pins |= mask;
108563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		break;
108663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
108763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
108863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	for (i = start_bit; i <= stop_bit; i++) {
108963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		owners[i] = if_unclaimed;
109063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
109163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	local_irq_restore(flags);
109263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	notify_watchers();
109363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
109463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik        return 0;
109563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
109663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
109763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
109863245d2cde2be64f172388c2c50862f233c05700Mikael Starvikint cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
109963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                                      const unsigned int gpio_out_available,
110063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                                      const unsigned char pa_available,
110163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                                      const unsigned char pb_available))
110263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
110363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct watcher *w;
110463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
110563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
110663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
110763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (NULL == notify) {
110863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -EINVAL;
110963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
111063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	w = kmalloc(sizeof(*w), GFP_KERNEL);
111163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (!w) {
111263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return -ENOMEM;
111363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
111463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	w->notify = notify;
111563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	w->next = watchers;
111663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	watchers = w;
111763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
111863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	w->notify((const unsigned int)gpio_in_pins,
111963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		  (const unsigned int)gpio_out_pins,
112063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		  (const unsigned char)gpio_pa_pins,
112163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		  (const unsigned char)gpio_pb_pins);
112263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
112363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return 0;
112463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
112563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
112663245d2cde2be64f172388c2c50862f233c05700Mikael Starvikvoid cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
112763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik						     const unsigned int gpio_out_available,
112863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik                                                     const unsigned char pa_available,
112963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik						     const unsigned char pb_available))
113063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
113163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	struct watcher *w = watchers, *prev = NULL;
113263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
113363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	(void)cris_io_interface_init();
113463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
113563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	while ((NULL != w) && (w->notify != notify)){
113663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		prev = w;
113763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		w = w->next;
113863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
113963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (NULL != w) {
114063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		if (NULL != prev) {
114163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			prev->next = w->next;
114263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		} else {
114363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik			watchers = w->next;
114463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		}
114563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		kfree(w);
114663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return;
114763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
114863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
114963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
115063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
115163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
115263245d2cde2be64f172388c2c50862f233c05700Mikael Starvikstatic int cris_io_interface_init(void)
115363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik{
115463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	static int first = 1;
115563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	int i;
115663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
115763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	if (!first) {
115863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		return 0;
115963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
116063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	first = 0;
116163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
116263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	for (i = 0; i<8; i++) {
116363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pa_owners[i] = if_unclaimed;
116463245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pb_owners[i] = if_unclaimed;
116563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pg_owners[i] = if_unclaimed;
116663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
116763245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	for (; i<32; i++) {
116863245d2cde2be64f172388c2c50862f233c05700Mikael Starvik		gpio_pg_owners[i] = if_unclaimed;
116963245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	}
117063245d2cde2be64f172388c2c50862f233c05700Mikael Starvik	return 0;
117163245d2cde2be64f172388c2c50862f233c05700Mikael Starvik}
117263245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
117363245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
117463245d2cde2be64f172388c2c50862f233c05700Mikael Starvikmodule_init(cris_io_interface_init);
117563245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
117663245d2cde2be64f172388c2c50862f233c05700Mikael Starvik
117763245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_request_io_interface);
117863245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_free_io_interface);
117963245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_io_interface_allocate_pins);
118063245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_io_interface_free_pins);
118163245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_io_interface_register_watcher);
118263245d2cde2be64f172388c2c50862f233c05700Mikael StarvikEXPORT_SYMBOL(cris_io_interface_delete_watcher);
1183