diff options
Diffstat (limited to 'arch/arm/mach-pxa/lubbock.c')
| -rw-r--r-- | arch/arm/mach-pxa/lubbock.c | 145 |
1 files changed, 141 insertions, 4 deletions
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index beccf455f796..b464bc88ff93 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
| @@ -14,21 +14,25 @@ | |||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/sysdev.h> | 18 | #include <linux/sysdev.h> |
| 19 | #include <linux/major.h> | 19 | #include <linux/major.h> |
| 20 | #include <linux/fb.h> | 20 | #include <linux/fb.h> |
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <linux/mtd/mtd.h> | ||
| 23 | #include <linux/mtd/partitions.h> | ||
| 22 | 24 | ||
| 23 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
| 24 | #include <asm/memory.h> | 26 | #include <asm/memory.h> |
| 25 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
| 26 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
| 27 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| 30 | #include <asm/sizes.h> | ||
| 28 | 31 | ||
| 29 | #include <asm/mach/arch.h> | 32 | #include <asm/mach/arch.h> |
| 30 | #include <asm/mach/map.h> | 33 | #include <asm/mach/map.h> |
| 31 | #include <asm/mach/irq.h> | 34 | #include <asm/mach/irq.h> |
| 35 | #include <asm/mach/flash.h> | ||
| 32 | 36 | ||
| 33 | #include <asm/hardware/sa1111.h> | 37 | #include <asm/hardware/sa1111.h> |
| 34 | 38 | ||
| @@ -175,7 +179,7 @@ static struct platform_device sa1111_device = { | |||
| 175 | static struct resource smc91x_resources[] = { | 179 | static struct resource smc91x_resources[] = { |
| 176 | [0] = { | 180 | [0] = { |
| 177 | .name = "smc91x-regs", | 181 | .name = "smc91x-regs", |
| 178 | .start = 0x0c000000, | 182 | .start = 0x0c000c00, |
| 179 | .end = 0x0c0fffff, | 183 | .end = 0x0c0fffff, |
| 180 | .flags = IORESOURCE_MEM, | 184 | .flags = IORESOURCE_MEM, |
| 181 | }, | 185 | }, |
| @@ -199,10 +203,75 @@ static struct platform_device smc91x_device = { | |||
| 199 | .resource = smc91x_resources, | 203 | .resource = smc91x_resources, |
| 200 | }; | 204 | }; |
| 201 | 205 | ||
| 206 | static struct resource flash_resources[] = { | ||
| 207 | [0] = { | ||
| 208 | .start = 0x00000000, | ||
| 209 | .end = SZ_64M - 1, | ||
| 210 | .flags = IORESOURCE_MEM, | ||
| 211 | }, | ||
| 212 | [1] = { | ||
| 213 | .start = 0x04000000, | ||
| 214 | .end = 0x04000000 + SZ_64M - 1, | ||
| 215 | .flags = IORESOURCE_MEM, | ||
| 216 | }, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static struct mtd_partition lubbock_partitions[] = { | ||
| 220 | { | ||
| 221 | .name = "Bootloader", | ||
| 222 | .size = 0x00040000, | ||
| 223 | .offset = 0, | ||
| 224 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
| 225 | },{ | ||
| 226 | .name = "Kernel", | ||
| 227 | .size = 0x00100000, | ||
| 228 | .offset = 0x00040000, | ||
| 229 | },{ | ||
| 230 | .name = "Filesystem", | ||
| 231 | .size = MTDPART_SIZ_FULL, | ||
| 232 | .offset = 0x00140000 | ||
| 233 | } | ||
| 234 | }; | ||
| 235 | |||
| 236 | static struct flash_platform_data lubbock_flash_data[2] = { | ||
| 237 | { | ||
| 238 | .map_name = "cfi_probe", | ||
| 239 | .parts = lubbock_partitions, | ||
| 240 | .nr_parts = ARRAY_SIZE(lubbock_partitions), | ||
| 241 | }, { | ||
| 242 | .map_name = "cfi_probe", | ||
| 243 | .parts = NULL, | ||
| 244 | .nr_parts = 0, | ||
| 245 | } | ||
| 246 | }; | ||
| 247 | |||
| 248 | static struct platform_device lubbock_flash_device[2] = { | ||
| 249 | { | ||
| 250 | .name = "pxa2xx-flash", | ||
| 251 | .id = 0, | ||
| 252 | .dev = { | ||
| 253 | .platform_data = &lubbock_flash_data[0], | ||
| 254 | }, | ||
| 255 | .resource = &flash_resources[0], | ||
| 256 | .num_resources = 1, | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | .name = "pxa2xx-flash", | ||
| 260 | .id = 1, | ||
| 261 | .dev = { | ||
| 262 | .platform_data = &lubbock_flash_data[1], | ||
| 263 | }, | ||
| 264 | .resource = &flash_resources[1], | ||
| 265 | .num_resources = 1, | ||
| 266 | }, | ||
| 267 | }; | ||
| 268 | |||
| 202 | static struct platform_device *devices[] __initdata = { | 269 | static struct platform_device *devices[] __initdata = { |
| 203 | &sa1111_device, | 270 | &sa1111_device, |
| 204 | &lub_audio_device, | 271 | &lub_audio_device, |
| 205 | &smc91x_device, | 272 | &smc91x_device, |
| 273 | &lubbock_flash_device[0], | ||
| 274 | &lubbock_flash_device[1], | ||
| 206 | }; | 275 | }; |
| 207 | 276 | ||
| 208 | static struct pxafb_mach_info sharp_lm8v31 __initdata = { | 277 | static struct pxafb_mach_info sharp_lm8v31 __initdata = { |
| @@ -224,18 +293,75 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = { | |||
| 224 | .lccr3 = LCCR3_PCP | LCCR3_Acb(255), | 293 | .lccr3 = LCCR3_PCP | LCCR3_Acb(255), |
| 225 | }; | 294 | }; |
| 226 | 295 | ||
| 227 | static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) | 296 | #define MMC_POLL_RATE msecs_to_jiffies(1000) |
| 297 | |||
| 298 | static void lubbock_mmc_poll(unsigned long); | ||
| 299 | static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *); | ||
| 300 | |||
| 301 | static struct timer_list mmc_timer = { | ||
| 302 | .function = lubbock_mmc_poll, | ||
| 303 | }; | ||
| 304 | |||
| 305 | static void lubbock_mmc_poll(unsigned long data) | ||
| 306 | { | ||
| 307 | unsigned long flags; | ||
| 308 | |||
| 309 | /* clear any previous irq state, then ... */ | ||
| 310 | local_irq_save(flags); | ||
| 311 | LUB_IRQ_SET_CLR &= ~(1 << 0); | ||
| 312 | local_irq_restore(flags); | ||
| 313 | |||
| 314 | /* poll until mmc/sd card is removed */ | ||
| 315 | if (LUB_IRQ_SET_CLR & (1 << 0)) | ||
| 316 | mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE); | ||
| 317 | else { | ||
| 318 | (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL); | ||
| 319 | enable_irq(LUBBOCK_SD_IRQ); | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs) | ||
| 324 | { | ||
| 325 | /* IRQ is level triggered; disable, and poll for removal */ | ||
| 326 | disable_irq(irq); | ||
| 327 | mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE); | ||
| 328 | |||
| 329 | return mmc_detect_int(irq, data, regs); | ||
| 330 | } | ||
| 331 | |||
| 332 | static int lubbock_mci_init(struct device *dev, | ||
| 333 | irqreturn_t (*detect_int)(int, void *, struct pt_regs *), | ||
| 334 | void *data) | ||
| 228 | { | 335 | { |
| 229 | /* setup GPIO for PXA25x MMC controller */ | 336 | /* setup GPIO for PXA25x MMC controller */ |
| 230 | pxa_gpio_mode(GPIO6_MMCCLK_MD); | 337 | pxa_gpio_mode(GPIO6_MMCCLK_MD); |
| 231 | pxa_gpio_mode(GPIO8_MMCCS0_MD); | 338 | pxa_gpio_mode(GPIO8_MMCCS0_MD); |
| 232 | 339 | ||
| 233 | return 0; | 340 | /* detect card insert/eject */ |
| 341 | mmc_detect_int = detect_int; | ||
| 342 | init_timer(&mmc_timer); | ||
| 343 | mmc_timer.data = (unsigned long) data; | ||
| 344 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, | ||
| 345 | SA_SAMPLE_RANDOM, "lubbock-sd-detect", data); | ||
| 346 | } | ||
| 347 | |||
| 348 | static int lubbock_mci_get_ro(struct device *dev) | ||
| 349 | { | ||
| 350 | return (LUB_MISC_RD & (1 << 2)) != 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | static void lubbock_mci_exit(struct device *dev, void *data) | ||
| 354 | { | ||
| 355 | free_irq(LUBBOCK_SD_IRQ, data); | ||
| 356 | del_timer_sync(&mmc_timer); | ||
| 234 | } | 357 | } |
| 235 | 358 | ||
| 236 | static struct pxamci_platform_data lubbock_mci_platform_data = { | 359 | static struct pxamci_platform_data lubbock_mci_platform_data = { |
| 237 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 360 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 361 | .detect_delay = 1, | ||
| 238 | .init = lubbock_mci_init, | 362 | .init = lubbock_mci_init, |
| 363 | .get_ro = lubbock_mci_get_ro, | ||
| 364 | .exit = lubbock_mci_exit, | ||
| 239 | }; | 365 | }; |
| 240 | 366 | ||
| 241 | static void lubbock_irda_transceiver_mode(struct device *dev, int mode) | 367 | static void lubbock_irda_transceiver_mode(struct device *dev, int mode) |
| @@ -258,10 +384,21 @@ static struct pxaficp_platform_data lubbock_ficp_platform_data = { | |||
| 258 | 384 | ||
| 259 | static void __init lubbock_init(void) | 385 | static void __init lubbock_init(void) |
| 260 | { | 386 | { |
| 387 | int flashboot = (LUB_CONF_SWITCHES & 1); | ||
| 388 | |||
| 261 | pxa_set_udc_info(&udc_info); | 389 | pxa_set_udc_info(&udc_info); |
| 262 | set_pxa_fb_info(&sharp_lm8v31); | 390 | set_pxa_fb_info(&sharp_lm8v31); |
| 263 | pxa_set_mci_info(&lubbock_mci_platform_data); | 391 | pxa_set_mci_info(&lubbock_mci_platform_data); |
| 264 | pxa_set_ficp_info(&lubbock_ficp_platform_data); | 392 | pxa_set_ficp_info(&lubbock_ficp_platform_data); |
| 393 | |||
| 394 | lubbock_flash_data[0].width = lubbock_flash_data[1].width = | ||
| 395 | (BOOT_DEF & 1) ? 2 : 4; | ||
| 396 | /* Compensate for the nROMBT switch which swaps the flash banks */ | ||
| 397 | printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", | ||
| 398 | flashboot?"Flash":"ROM", flashboot); | ||
| 399 | |||
| 400 | lubbock_flash_data[flashboot^1].name = "application-flash"; | ||
| 401 | lubbock_flash_data[flashboot].name = "boot-rom"; | ||
| 265 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 402 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 266 | } | 403 | } |
| 267 | 404 | ||
