diff options
Diffstat (limited to 'arch/mips/rb532')
-rw-r--r-- | arch/mips/rb532/devices.c | 57 | ||||
-rw-r--r-- | arch/mips/rb532/gpio.c | 90 | ||||
-rw-r--r-- | arch/mips/rb532/irq.c | 27 | ||||
-rw-r--r-- | arch/mips/rb532/serial.c | 2 |
4 files changed, 93 insertions, 83 deletions
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index c1c29181bd46..4a5f05b662ae 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mtd/partitions.h> | 24 | #include <linux/mtd/partitions.h> |
25 | #include <linux/gpio_keys.h> | 25 | #include <linux/gpio_keys.h> |
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/serial_8250.h> | ||
27 | 28 | ||
28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
29 | 30 | ||
@@ -39,6 +40,29 @@ | |||
39 | #define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET) | 40 | #define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET) |
40 | #define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET) | 41 | #define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET) |
41 | 42 | ||
43 | extern unsigned int idt_cpu_freq; | ||
44 | |||
45 | static struct mpmc_device dev3; | ||
46 | |||
47 | void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | |||
51 | spin_lock_irqsave(&dev3.lock, flags); | ||
52 | |||
53 | dev3.state = (dev3.state | or_mask) & ~nand_mask; | ||
54 | writeb(dev3.state, dev3.base); | ||
55 | |||
56 | spin_unlock_irqrestore(&dev3.lock, flags); | ||
57 | } | ||
58 | EXPORT_SYMBOL(set_latch_u5); | ||
59 | |||
60 | unsigned char get_latch_u5(void) | ||
61 | { | ||
62 | return dev3.state; | ||
63 | } | ||
64 | EXPORT_SYMBOL(get_latch_u5); | ||
65 | |||
42 | static struct resource korina_dev0_res[] = { | 66 | static struct resource korina_dev0_res[] = { |
43 | { | 67 | { |
44 | .name = "korina_regs", | 68 | .name = "korina_regs", |
@@ -86,7 +110,7 @@ static struct korina_device korina_dev0_data = { | |||
86 | static struct platform_device korina_dev0 = { | 110 | static struct platform_device korina_dev0 = { |
87 | .id = -1, | 111 | .id = -1, |
88 | .name = "korina", | 112 | .name = "korina", |
89 | .dev.platform_data = &korina_dev0_data, | 113 | .dev.driver_data = &korina_dev0_data, |
90 | .resource = korina_dev0_res, | 114 | .resource = korina_dev0_res, |
91 | .num_resources = ARRAY_SIZE(korina_dev0_res), | 115 | .num_resources = ARRAY_SIZE(korina_dev0_res), |
92 | }; | 116 | }; |
@@ -214,12 +238,32 @@ static struct platform_device rb532_wdt = { | |||
214 | .num_resources = ARRAY_SIZE(rb532_wdt_res), | 238 | .num_resources = ARRAY_SIZE(rb532_wdt_res), |
215 | }; | 239 | }; |
216 | 240 | ||
241 | static struct plat_serial8250_port rb532_uart_res[] = { | ||
242 | { | ||
243 | .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), | ||
244 | .irq = UART0_IRQ, | ||
245 | .regshift = 2, | ||
246 | .iotype = UPIO_MEM, | ||
247 | .flags = UPF_BOOT_AUTOCONF, | ||
248 | }, | ||
249 | { | ||
250 | .flags = 0, | ||
251 | } | ||
252 | }; | ||
253 | |||
254 | static struct platform_device rb532_uart = { | ||
255 | .name = "serial8250", | ||
256 | .id = PLAT8250_DEV_PLATFORM, | ||
257 | .dev.platform_data = &rb532_uart_res, | ||
258 | }; | ||
259 | |||
217 | static struct platform_device *rb532_devs[] = { | 260 | static struct platform_device *rb532_devs[] = { |
218 | &korina_dev0, | 261 | &korina_dev0, |
219 | &nand_slot0, | 262 | &nand_slot0, |
220 | &cf_slot0, | 263 | &cf_slot0, |
221 | &rb532_led, | 264 | &rb532_led, |
222 | &rb532_button, | 265 | &rb532_button, |
266 | &rb532_uart, | ||
223 | &rb532_wdt | 267 | &rb532_wdt |
224 | }; | 268 | }; |
225 | 269 | ||
@@ -291,9 +335,20 @@ static int __init plat_setup_devices(void) | |||
291 | nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE); | 335 | nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE); |
292 | nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000; | 336 | nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000; |
293 | 337 | ||
338 | /* Read and map device controller 3 */ | ||
339 | dev3.base = ioremap_nocache(readl(IDT434_REG_BASE + DEV3BASE), 1); | ||
340 | |||
341 | if (!dev3.base) { | ||
342 | printk(KERN_ERR "rb532: cannot remap device controller 3\n"); | ||
343 | return -ENXIO; | ||
344 | } | ||
345 | |||
294 | /* Initialise the NAND device */ | 346 | /* Initialise the NAND device */ |
295 | rb532_nand_setup(); | 347 | rb532_nand_setup(); |
296 | 348 | ||
349 | /* set the uart clock to the current cpu frequency */ | ||
350 | rb532_uart_res[0].uartclk = idt_cpu_freq; | ||
351 | |||
297 | return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs)); | 352 | return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs)); |
298 | } | 353 | } |
299 | 354 | ||
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index 0e84c8ab6a39..37de05d595e7 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c | |||
@@ -41,8 +41,6 @@ struct rb532_gpio_chip { | |||
41 | void __iomem *regbase; | 41 | void __iomem *regbase; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct mpmc_device dev3; | ||
45 | |||
46 | static struct resource rb532_gpio_reg0_res[] = { | 44 | static struct resource rb532_gpio_reg0_res[] = { |
47 | { | 45 | { |
48 | .name = "gpio_reg0", | 46 | .name = "gpio_reg0", |
@@ -52,61 +50,6 @@ static struct resource rb532_gpio_reg0_res[] = { | |||
52 | } | 50 | } |
53 | }; | 51 | }; |
54 | 52 | ||
55 | static struct resource rb532_dev3_ctl_res[] = { | ||
56 | { | ||
57 | .name = "dev3_ctl", | ||
58 | .start = REGBASE + DEV3BASE, | ||
59 | .end = REGBASE + DEV3BASE + sizeof(struct dev_reg) - 1, | ||
60 | .flags = IORESOURCE_MEM, | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val) | ||
65 | { | ||
66 | unsigned long flags; | ||
67 | unsigned data; | ||
68 | unsigned i = 0; | ||
69 | |||
70 | spin_lock_irqsave(&dev3.lock, flags); | ||
71 | |||
72 | data = readl(IDT434_REG_BASE + reg_offs); | ||
73 | for (i = 0; i != len; ++i) { | ||
74 | if (val & (1 << i)) | ||
75 | data |= (1 << (i + bit)); | ||
76 | else | ||
77 | data &= ~(1 << (i + bit)); | ||
78 | } | ||
79 | writel(data, (IDT434_REG_BASE + reg_offs)); | ||
80 | |||
81 | spin_unlock_irqrestore(&dev3.lock, flags); | ||
82 | } | ||
83 | EXPORT_SYMBOL(set_434_reg); | ||
84 | |||
85 | unsigned get_434_reg(unsigned reg_offs) | ||
86 | { | ||
87 | return readl(IDT434_REG_BASE + reg_offs); | ||
88 | } | ||
89 | EXPORT_SYMBOL(get_434_reg); | ||
90 | |||
91 | void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) | ||
92 | { | ||
93 | unsigned long flags; | ||
94 | |||
95 | spin_lock_irqsave(&dev3.lock, flags); | ||
96 | |||
97 | dev3.state = (dev3.state | or_mask) & ~nand_mask; | ||
98 | writel(dev3.state, &dev3.base); | ||
99 | |||
100 | spin_unlock_irqrestore(&dev3.lock, flags); | ||
101 | } | ||
102 | EXPORT_SYMBOL(set_latch_u5); | ||
103 | |||
104 | unsigned char get_latch_u5(void) | ||
105 | { | ||
106 | return dev3.state; | ||
107 | } | ||
108 | EXPORT_SYMBOL(get_latch_u5); | ||
109 | |||
110 | /* rb532_set_bit - sanely set a bit | 53 | /* rb532_set_bit - sanely set a bit |
111 | * | 54 | * |
112 | * bitval: new value for the bit | 55 | * bitval: new value for the bit |
@@ -119,13 +62,11 @@ static inline void rb532_set_bit(unsigned bitval, | |||
119 | unsigned long flags; | 62 | unsigned long flags; |
120 | u32 val; | 63 | u32 val; |
121 | 64 | ||
122 | bitval = !!bitval; /* map parameter to {0,1} */ | ||
123 | |||
124 | local_irq_save(flags); | 65 | local_irq_save(flags); |
125 | 66 | ||
126 | val = readl(ioaddr); | 67 | val = readl(ioaddr); |
127 | val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */ | 68 | val &= ~(!bitval << offset); /* unset bit if bitval == 0 */ |
128 | val |= ( bitval << offset ); /* set bit if bitval == 1 */ | 69 | val |= (!!bitval << offset); /* set bit if bitval == 1 */ |
129 | writel(val, ioaddr); | 70 | writel(val, ioaddr); |
130 | 71 | ||
131 | local_irq_restore(flags); | 72 | local_irq_restore(flags); |
@@ -171,8 +112,8 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
171 | 112 | ||
172 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 113 | gpch = container_of(chip, struct rb532_gpio_chip, chip); |
173 | 114 | ||
174 | if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) | 115 | /* disable alternate function in case it's set */ |
175 | return 1; /* alternate function, GPIOCFG is ignored */ | 116 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
176 | 117 | ||
177 | rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); | 118 | rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); |
178 | return 0; | 119 | return 0; |
@@ -188,8 +129,8 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip, | |||
188 | 129 | ||
189 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 130 | gpch = container_of(chip, struct rb532_gpio_chip, chip); |
190 | 131 | ||
191 | if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) | 132 | /* disable alternate function in case it's set */ |
192 | return 1; /* alternate function, GPIOCFG is ignored */ | 133 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
193 | 134 | ||
194 | /* set the initial output value */ | 135 | /* set the initial output value */ |
195 | rb532_set_bit(value, offset, gpch->regbase + GPIOD); | 136 | rb532_set_bit(value, offset, gpch->regbase + GPIOD); |
@@ -233,10 +174,11 @@ EXPORT_SYMBOL(rb532_gpio_set_istat); | |||
233 | /* | 174 | /* |
234 | * Configure GPIO alternate function | 175 | * Configure GPIO alternate function |
235 | */ | 176 | */ |
236 | static void rb532_gpio_set_func(int bit, unsigned gpio) | 177 | void rb532_gpio_set_func(unsigned gpio) |
237 | { | 178 | { |
238 | rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOFUNC); | 179 | rb532_set_bit(1, gpio, rb532_gpio_chip->regbase + GPIOFUNC); |
239 | } | 180 | } |
181 | EXPORT_SYMBOL(rb532_gpio_set_func); | ||
240 | 182 | ||
241 | int __init rb532_gpio_init(void) | 183 | int __init rb532_gpio_init(void) |
242 | { | 184 | { |
@@ -253,20 +195,6 @@ int __init rb532_gpio_init(void) | |||
253 | /* Register our GPIO chip */ | 195 | /* Register our GPIO chip */ |
254 | gpiochip_add(&rb532_gpio_chip->chip); | 196 | gpiochip_add(&rb532_gpio_chip->chip); |
255 | 197 | ||
256 | r = rb532_dev3_ctl_res; | ||
257 | dev3.base = ioremap_nocache(r->start, r->end - r->start); | ||
258 | |||
259 | if (!dev3.base) { | ||
260 | printk(KERN_ERR "rb532: cannot remap device controller 3\n"); | ||
261 | return -ENXIO; | ||
262 | } | ||
263 | |||
264 | /* configure CF_GPIO_NUM as CFRDY IRQ source */ | ||
265 | rb532_gpio_set_func(0, CF_GPIO_NUM); | ||
266 | rb532_gpio_direction_input(&rb532_gpio_chip->chip, CF_GPIO_NUM); | ||
267 | rb532_gpio_set_ilevel(1, CF_GPIO_NUM); | ||
268 | rb532_gpio_set_istat(0, CF_GPIO_NUM); | ||
269 | |||
270 | return 0; | 198 | return 0; |
271 | } | 199 | } |
272 | arch_initcall(rb532_gpio_init); | 200 | arch_initcall(rb532_gpio_init); |
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c index 549b46d2fcee..53eeb5e7bc5b 100644 --- a/arch/mips/rb532/irq.c +++ b/arch/mips/rb532/irq.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | 47 | ||
48 | #include <asm/mach-rc32434/irq.h> | 48 | #include <asm/mach-rc32434/irq.h> |
49 | #include <asm/mach-rc32434/gpio.h> | ||
49 | 50 | ||
50 | struct intr_group { | 51 | struct intr_group { |
51 | u32 mask; /* mask of valid bits in pending/mask registers */ | 52 | u32 mask; /* mask of valid bits in pending/mask registers */ |
@@ -150,6 +151,9 @@ static void rb532_disable_irq(unsigned int irq_nr) | |||
150 | mask |= intr_bit; | 151 | mask |= intr_bit; |
151 | WRITE_MASK(addr, mask); | 152 | WRITE_MASK(addr, mask); |
152 | 153 | ||
154 | if (group == GPIO_MAPPED_IRQ_GROUP) | ||
155 | rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE); | ||
156 | |||
153 | /* | 157 | /* |
154 | * if there are no more interrupts enabled in this | 158 | * if there are no more interrupts enabled in this |
155 | * group, disable corresponding IP | 159 | * group, disable corresponding IP |
@@ -165,12 +169,35 @@ static void rb532_mask_and_ack_irq(unsigned int irq_nr) | |||
165 | ack_local_irq(group_to_ip(irq_to_group(irq_nr))); | 169 | ack_local_irq(group_to_ip(irq_to_group(irq_nr))); |
166 | } | 170 | } |
167 | 171 | ||
172 | static int rb532_set_type(unsigned int irq_nr, unsigned type) | ||
173 | { | ||
174 | int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE; | ||
175 | int group = irq_to_group(irq_nr); | ||
176 | |||
177 | if (group != GPIO_MAPPED_IRQ_GROUP) | ||
178 | return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL; | ||
179 | |||
180 | switch (type) { | ||
181 | case IRQ_TYPE_LEVEL_HIGH: | ||
182 | rb532_gpio_set_ilevel(1, gpio); | ||
183 | break; | ||
184 | case IRQ_TYPE_LEVEL_LOW: | ||
185 | rb532_gpio_set_ilevel(0, gpio); | ||
186 | break; | ||
187 | default: | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
168 | static struct irq_chip rc32434_irq_type = { | 194 | static struct irq_chip rc32434_irq_type = { |
169 | .name = "RB532", | 195 | .name = "RB532", |
170 | .ack = rb532_disable_irq, | 196 | .ack = rb532_disable_irq, |
171 | .mask = rb532_disable_irq, | 197 | .mask = rb532_disable_irq, |
172 | .mask_ack = rb532_mask_and_ack_irq, | 198 | .mask_ack = rb532_mask_and_ack_irq, |
173 | .unmask = rb532_enable_irq, | 199 | .unmask = rb532_enable_irq, |
200 | .set_type = rb532_set_type, | ||
174 | }; | 201 | }; |
175 | 202 | ||
176 | void __init arch_init_irq(void) | 203 | void __init arch_init_irq(void) |
diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c index 3e0d7ec3a579..00ed19f0bdb5 100644 --- a/arch/mips/rb532/serial.c +++ b/arch/mips/rb532/serial.c | |||
@@ -36,7 +36,7 @@ | |||
36 | extern unsigned int idt_cpu_freq; | 36 | extern unsigned int idt_cpu_freq; |
37 | 37 | ||
38 | static struct uart_port rb532_uart = { | 38 | static struct uart_port rb532_uart = { |
39 | .type = PORT_16550A, | 39 | .flags = UPF_BOOT_AUTOCONF, |
40 | .line = 0, | 40 | .line = 0, |
41 | .irq = UART0_IRQ, | 41 | .irq = UART0_IRQ, |
42 | .iotype = UPIO_MEM, | 42 | .iotype = UPIO_MEM, |