config.c revision b7ce7f0d0efc1a95154fa6872d5d7c970d281c71
1/***************************************************************************/ 2 3/* 4 * linux/arch/m68knommu/platform/528x/config.c 5 * 6 * Sub-architcture dependent initialization code for the Freescale 7 * 5280, 5281 and 5282 CPUs. 8 * 9 * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) 10 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) 11 */ 12 13/***************************************************************************/ 14 15#include <linux/kernel.h> 16#include <linux/param.h> 17#include <linux/init.h> 18#include <linux/platform_device.h> 19#include <linux/io.h> 20#include <linux/spi/spi.h> 21#include <linux/gpio.h> 22#include <asm/machdep.h> 23#include <asm/coldfire.h> 24#include <asm/mcfsim.h> 25#include <asm/mcfuart.h> 26#include <asm/mcfqspi.h> 27 28/***************************************************************************/ 29 30#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 31static struct resource m528x_qspi_resources[] = { 32 { 33 .start = MCFQSPI_IOBASE, 34 .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, 35 .flags = IORESOURCE_MEM, 36 }, 37 { 38 .start = MCFINT_VECBASE + MCFINT_QSPI, 39 .end = MCFINT_VECBASE + MCFINT_QSPI, 40 .flags = IORESOURCE_IRQ, 41 }, 42}; 43 44#define MCFQSPI_CS0 147 45#define MCFQSPI_CS1 148 46#define MCFQSPI_CS2 149 47#define MCFQSPI_CS3 150 48 49static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control) 50{ 51 int status; 52 53 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); 54 if (status) { 55 pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); 56 goto fail0; 57 } 58 status = gpio_direction_output(MCFQSPI_CS0, 1); 59 if (status) { 60 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); 61 goto fail1; 62 } 63 64 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); 65 if (status) { 66 pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); 67 goto fail1; 68 } 69 status = gpio_direction_output(MCFQSPI_CS1, 1); 70 if (status) { 71 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); 72 goto fail2; 73 } 74 75 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); 76 if (status) { 77 pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); 78 goto fail2; 79 } 80 status = gpio_direction_output(MCFQSPI_CS2, 1); 81 if (status) { 82 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); 83 goto fail3; 84 } 85 86 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); 87 if (status) { 88 pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); 89 goto fail3; 90 } 91 status = gpio_direction_output(MCFQSPI_CS3, 1); 92 if (status) { 93 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); 94 goto fail4; 95 } 96 97 return 0; 98 99fail4: 100 gpio_free(MCFQSPI_CS3); 101fail3: 102 gpio_free(MCFQSPI_CS2); 103fail2: 104 gpio_free(MCFQSPI_CS1); 105fail1: 106 gpio_free(MCFQSPI_CS0); 107fail0: 108 return status; 109} 110 111static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control) 112{ 113 gpio_free(MCFQSPI_CS3); 114 gpio_free(MCFQSPI_CS2); 115 gpio_free(MCFQSPI_CS1); 116 gpio_free(MCFQSPI_CS0); 117} 118 119static void m528x_cs_select(struct mcfqspi_cs_control *cs_control, 120 u8 chip_select, bool cs_high) 121{ 122 gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high); 123} 124 125static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control, 126 u8 chip_select, bool cs_high) 127{ 128 gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high); 129} 130 131static struct mcfqspi_cs_control m528x_cs_control = { 132 .setup = m528x_cs_setup, 133 .teardown = m528x_cs_teardown, 134 .select = m528x_cs_select, 135 .deselect = m528x_cs_deselect, 136}; 137 138static struct mcfqspi_platform_data m528x_qspi_data = { 139 .bus_num = 0, 140 .num_chipselect = 4, 141 .cs_control = &m528x_cs_control, 142}; 143 144static struct platform_device m528x_qspi = { 145 .name = "mcfqspi", 146 .id = 0, 147 .num_resources = ARRAY_SIZE(m528x_qspi_resources), 148 .resource = m528x_qspi_resources, 149 .dev.platform_data = &m528x_qspi_data, 150}; 151 152static void __init m528x_qspi_init(void) 153{ 154 /* setup Port QS for QSPI with gpio CS control */ 155 __raw_writeb(0x07, MCFGPIO_PQSPAR); 156} 157#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ 158 159static struct platform_device *m528x_devices[] __initdata = { 160#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 161 &m528x_qspi, 162#endif 163}; 164 165/***************************************************************************/ 166 167static void __init m528x_uarts_init(void) 168{ 169 u8 port; 170 171 /* make sure PUAPAR is set for UART0 and UART1 */ 172 port = readb(MCF5282_GPIO_PUAPAR); 173 port |= 0x03 | (0x03 << 2); 174 writeb(port, MCF5282_GPIO_PUAPAR); 175} 176 177/***************************************************************************/ 178 179static void __init m528x_fec_init(void) 180{ 181 u16 v16; 182 183 /* Set multi-function pins to ethernet mode for fec0 */ 184 v16 = readw(MCF_IPSBAR + 0x100056); 185 writew(v16 | 0xf00, MCF_IPSBAR + 0x100056); 186 writeb(0xc0, MCF_IPSBAR + 0x100058); 187} 188 189/***************************************************************************/ 190 191static void m528x_cpu_reset(void) 192{ 193 local_irq_disable(); 194 __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); 195} 196 197/***************************************************************************/ 198 199#ifdef CONFIG_WILDFIRE 200void wildfire_halt(void) 201{ 202 writeb(0, 0x30000007); 203 writeb(0x2, 0x30000007); 204} 205#endif 206 207#ifdef CONFIG_WILDFIREMOD 208void wildfiremod_halt(void) 209{ 210 printk(KERN_INFO "WildFireMod hibernating...\n"); 211 212 /* Set portE.5 to Digital IO */ 213 MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2)); 214 215 /* Make portE.5 an output */ 216 MCF5282_GPIO_DDRE |= (1 << 5); 217 218 /* Now toggle portE.5 from low to high */ 219 MCF5282_GPIO_PORTE &= ~(1 << 5); 220 MCF5282_GPIO_PORTE |= (1 << 5); 221 222 printk(KERN_EMERG "Failed to hibernate. Halting!\n"); 223} 224#endif 225 226void __init config_BSP(char *commandp, int size) 227{ 228#ifdef CONFIG_WILDFIRE 229 mach_halt = wildfire_halt; 230#endif 231#ifdef CONFIG_WILDFIREMOD 232 mach_halt = wildfiremod_halt; 233#endif 234} 235 236/***************************************************************************/ 237 238static int __init init_BSP(void) 239{ 240 mach_reset = m528x_cpu_reset; 241 mach_sched_init = hw_timer_init; 242 m528x_uarts_init(); 243 m528x_fec_init(); 244#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 245 m528x_qspi_init(); 246#endif 247 platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices)); 248 return 0; 249} 250 251arch_initcall(init_BSP); 252 253/***************************************************************************/ 254