All,
I met an oops under DA850 with SPI support, the follow are oops information:
RFH0-0>insmod davinci_spi.ko [ 112.442562] Unable to handle kernel NULL pointer dereference at virtual address 0000005c[ 112.450666] pgd = c38fc000[ 112.453382] [0000005c] *pgd=c1113831, *pte=00000000, *ppte=00000000[ 112.459668] Internal error: Oops: 17 [#1] PREEMPT[ 112.464363] last sysfs file: [ 112.467327] Modules linked in: davinci_spi(+) spi_bitbang [last unloaded: spi_bitbang][ 112.475267] CPU: 0 Not tainted (2.6.39.3 #2)[ 112.479909] PC is at _clear_bit+0x20/0x38[ 112.483954] LR is at prepare_unused_channel_list+0x50/0x70[ 112.489442] pc : [<c022d248>] lr : [<c015fcfc>] psr: 60000093[ 112.489462] sp : c38e7da0 ip : 60000013 fp : 00000000[ 112.500906] r10: 00000012 r9 : c112e2f0 r8 : c112e200[ 112.506125] r7 : c037c144 r6 : c036ed88 r5 : 00000002 r4 : 00000038[ 112.512643] r3 : 00040000 r2 : 00000012 r1 : 0000005c r0 : 00000000[ 112.519164] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user[ 112.526379] Control: 0005317f Table: c38fc000 DAC: 00000015[ 112.532120] Process insmod (pid: 144, stack limit = 0xc38e6270)[ 112.538033] Stack: (0xc38e7da0 to 0xc38e8000)[ 112.542409] 7da0: c015fcac 00000000 c38e7db8 c015fcac 00000000 c0258cbc c381a0f8 c3837510[ 112.550594] 7dc0: 00000000 bf00c1a0 00000012 00000013 c037c144 c01600a8 00000012 bf00c1a0[ 112.558779] 7de0: c112e2f0 c112e2f0 c036ec30 00000013 c036ec94 c112e200 c036ed90 00000012[ 112.566966] 7e00: 00000000 bf00c458 c38408a0 c112e2f0 c036ed90 c036ed90 bf00d01c bf00d01c[ 112.575151] 7e20: 00000000 0000001e 0000001c c025a9b4 c025a9a0 c025999c 00000000 c036ed90[ 112.583336] 7e40: c036edc4 bf00d01c 00000000 c0259ab0 bf00d01c c38e7e60 c0259a50 c0258cbc[ 112.591523] 7e60: c381a0f8 c3837510 bf00d01c bf00d01c c38e2660 c0378d20 00000000 c0259334[ 112.599708] 7e80: bf00cfd6 bf00cfd6 00000000 bf00d01c 00000000 00000001 bf010000 00000000[ 112.607892] 7ea0: 0000001c c0259f8c 00000000 bf00d008 00000000 00000001 bf010000 00000000[ 112.616076] 7ec0: 0000001c c025adb8 bf00d058 00000000 00000001 c0155518 c0370c64 00000001[ 112.624259] 7ee0: bf00d058 bf00d058 bf00d0a0 bf00d058 00000000 00000001 c1122400 00000001[ 112.632446] 7f00: 0000001c c018fb00 bf00d064 c0155310 c018d808 c02e4c60 bf00d17c 00070e42[ 112.640631] 7f20: 00000350 c406d000 000028b0 c406e3ec c406e2af c406f3c4 c38f0480 000011a4[ 112.648812] 7f40: 00001364 00000000 00000000 0000001c 0000001d 00000014 00000000 00000010[ 112.656993] 7f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000[ 112.665178] 7f80: c38f0540 fffffe00 00000069 bef35e74 00000080 c0156144 c38e6000 00000000[ 112.673364] 7fa0: 00000000 c0155fc0 fffffe00 00000069 00080040 000028b0 00070e42 7fffffff[ 112.681548] 7fc0: fffffe00 00000069 bef35e74 00000080 bef35e78 00070e42 bef35e78 00000000[ 112.689729] 7fe0: 00000001 bef35b34 00013d3c 4024bfc4 60000010 00080040 00000000 00000000[ 112.697917] Code: e3a03001 e1a03213 e10fc000 e321f093 (e7912100) [ 112.704171] ---[ end trace f9fac7a4e3a0840b ]---Segmentation fault
Under board's kernel specific file:
static struct spi_board_info da850_spi_board_info[] __initdata = { { .modalias = "ks8851", .mode = SPI_MODE_0, .bus_num = 1, .chip_select = 0, .max_speed_hz = 24000000, .irq = ETH_KS8851_IRQ, },};
static struct gpio da850_eth_gpios[] __initdata = {#if 0 { ETH_KS8851_POWER_ON, GPIOF_OUT_INIT_HIGH, "eth_power" }, { ETH_KS8851_QUART, GPIOF_OUT_INIT_HIGH, "quart" },#endif { ETH_KS8851_IRQ, GPIOF_IN, "eth_irq" },};
static int __init da850_ethernet_init(void){ int status; /* Request of GPIO lines */ status = gpio_request_array(da850_eth_gpios, ARRAY_SIZE(da850_eth_gpios)); if (status) { pr_err("Cannot request ETH GPIOs\n"); } return status;}
static __init void da850_rru_init(void){ int ret = 0; u32 cfgchip2 = 0; ret = davinci_cfg_reg_list(da850_i2c0_pins); if (ret) pr_warning("da850_rru_init: i2c0 mux setup failed: %d\n", ret); ret = da8xx_register_i2c(0, &da850_rru_i2c_0_pdata); if (ret) pr_warning("da850_rru_init: i2c0 registration failed: %d\n", ret); ret = da8xx_register_watchdog(); if (ret) pr_warning("da830_rru_init: watchdog registration failed: %d\n", ret); davinci_serial_init(&da850_rru_uart_config); i2c_register_board_info(1, da850_rru_i2c_devices, ARRAY_SIZE(da850_rru_i2c_devices)); /* * shut down uart 0 and 1; they are not used on the board and * accessing them causes endless "too much work in irq53" messages * with arago fs */ __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);// __raw_writel(0, IO_ADDRESS(DA8XX_UART2_BASE) + 0x30); ret = da8xx_register_rtc(); if (ret) pr_warning("da850_rru_init: rtc setup failed: %d\n", ret); ret = da8xx_register_cpuidle(); if (ret) pr_warning("da850_rru_init: cpuidle registration failed: %d\n", ret); ret = da850_register_pm(&da850_pm_device); if (ret) pr_warning("da850_rru_init: suspend registration failed: %d\n", ret); pr_err("pinmux0: %x\n", __raw_readl(DA8XX_SYSCFG0_VIRT(0x120))); pr_err("cfgchip2: %x\n", __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)));#if 0 init_ks8851_resource(); platform_add_devices(da850_rru_devices, ARRAY_SIZE(da850_rru_devices));#endif ret = da850_ethernet_init(); if( ret != 0 ) { pr_err("Failed to do da850 ethernet initialization\n"); } else { da850_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ); ret = da8xx_register_spi(1, da850_spi_board_info, ARRAY_SIZE(da850_spi_board_info)); if (ret) { printk("fduan001: failed to do initilize the spi register\n"); # never runned here } }}
CONFIG FILE:
CONFIG_SPI=y
CONFIG_SPI_DAVINCI=m
CONFIG_SPI_BITBANG=m
CONFIG_KS8851=y # i changed this option to n, oops happen the same
I don't know why the standard driver could meet such problem.
BR
Fei Xia Duan
/* * DA8XX/OMAP L1XX platform device data * * Copyright (c) 2007-2009, MontaVista Software, Inc. <source@mvista.com> * Derived from code that was: * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <linux/init.h>#include <linux/platform_device.h>#include <linux/dma-mapping.h>#include <linux/serial_8250.h>#include <mach/cputype.h>#include <mach/common.h>#include <mach/time.h>#include <mach/da8xx.h>#include <mach/cpuidle.h>#include "clock.h"#define DA8XX_TPCC_BASE 0x01c00000#define DA850_MMCSD1_BASE 0x01e1b000#define DA850_TPCC1_BASE 0x01e30000#define DA8XX_TPTC0_BASE 0x01c08000#define DA8XX_TPTC1_BASE 0x01c08400#define DA850_TPTC2_BASE 0x01e38000#define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */#define DA8XX_I2C0_BASE 0x01c22000#define DA8XX_RTC_BASE 0x01C23000#define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000#define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000#define DA8XX_EMAC_CPGMAC_BASE 0x01e23000#define DA8XX_EMAC_MDIO_BASE 0x01e24000#define DA8XX_GPIO_BASE 0x01e26000#define DA8XX_I2C1_BASE 0x01e28000#define DA8XX_SPI0_BASE 0x01c41000#define DA830_SPI1_BASE 0x01e12000#define DA850_SPI1_BASE 0x01f0e000#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000#define DA8XX_EMAC_RAM_OFFSET 0x0000#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K#define DA8XX_DMA_SPI0_RX EDMA_CTLR_CHAN(0, 14)#define DA8XX_DMA_SPI0_TX EDMA_CTLR_CHAN(0, 15)#define DA8XX_DMA_MMCSD0_RX EDMA_CTLR_CHAN(0, 16)#define DA8XX_DMA_MMCSD0_TX EDMA_CTLR_CHAN(0, 17)#define DA8XX_DMA_SPI1_RX EDMA_CTLR_CHAN(0, 18)#define DA8XX_DMA_SPI1_TX EDMA_CTLR_CHAN(0, 19)#define DA850_DMA_MMCSD1_RX EDMA_CTLR_CHAN(1, 28)#define DA850_DMA_MMCSD1_TX EDMA_CTLR_CHAN(1, 29)void __iomem *da8xx_syscfg0_base;void __iomem *da8xx_syscfg1_base;static struct plat_serial8250_port da8xx_serial_pdata[] = { { .mapbase = DA8XX_UART0_BASE, .irq = IRQ_DA8XX_UARTINT0, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 2, }, { .mapbase = DA8XX_UART1_BASE, .irq = IRQ_DA8XX_UARTINT1, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 2, }, { .mapbase = DA8XX_UART2_BASE, .irq = IRQ_DA8XX_UARTINT2, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 2, }, { .flags = 0, },};struct platform_device da8xx_serial_device = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, .dev = { .platform_data = da8xx_serial_pdata, },};static const s8 da8xx_queue_tc_mapping[][2] = { /* {event queue no, TC no} */ {0, 0}, {1, 1}, {-1, -1}};static const s8 da8xx_queue_priority_mapping[][2] = { /* {event queue no, Priority} */ {0, 3}, {1, 7}, {-1, -1}};static const s8 da850_queue_tc_mapping[][2] = { /* {event queue no, TC no} */ {0, 0}, {-1, -1}};static const s8 da850_queue_priority_mapping[][2] = { /* {event queue no, Priority} */ {0, 3}, {-1, -1}};static struct edma_soc_info da830_edma_cc0_info = { .n_channel = 32, .n_region = 4, .n_slot = 128, .n_tc = 2, .n_cc = 1, .queue_tc_mapping = da8xx_queue_tc_mapping, .queue_priority_mapping = da8xx_queue_priority_mapping,};static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = { &da830_edma_cc0_info,};static struct edma_soc_info da850_edma_cc_info[] = { { .n_channel = 32, .n_region = 4, .n_slot = 128, .n_tc = 2, .n_cc = 1, .queue_tc_mapping = da8xx_queue_tc_mapping, .queue_priority_mapping = da8xx_queue_priority_mapping, }, { .n_channel = 32, .n_region = 4, .n_slot = 128, .n_tc = 1, .n_cc = 1, .queue_tc_mapping = da850_queue_tc_mapping, .queue_priority_mapping = da850_queue_priority_mapping, },};static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = { &da850_edma_cc_info[0], &da850_edma_cc_info[1],};static struct resource da830_edma_resources[] = { { .name = "edma_cc0", .start = DA8XX_TPCC_BASE, .end = DA8XX_TPCC_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_tc0", .start = DA8XX_TPTC0_BASE, .end = DA8XX_TPTC0_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_tc1", .start = DA8XX_TPTC1_BASE, .end = DA8XX_TPTC1_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma0", .start = IRQ_DA8XX_CCINT0, .flags = IORESOURCE_IRQ, }, { .name = "edma0_err", .start = IRQ_DA8XX_CCERRINT, .flags = IORESOURCE_IRQ, },};static struct resource da850_edma_resources[] = { { .name = "edma_cc0", .start = DA8XX_TPCC_BASE, .end = DA8XX_TPCC_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_tc0", .start = DA8XX_TPTC0_BASE, .end = DA8XX_TPTC0_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_tc1", .start = DA8XX_TPTC1_BASE, .end = DA8XX_TPTC1_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_cc1", .start = DA850_TPCC1_BASE, .end = DA850_TPCC1_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma_tc2", .start = DA850_TPTC2_BASE, .end = DA850_TPTC2_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .name = "edma0", .start = IRQ_DA8XX_CCINT0, .flags = IORESOURCE_IRQ, }, { .name = "edma0_err", .start = IRQ_DA8XX_CCERRINT, .flags = IORESOURCE_IRQ, }, { .name = "edma1", .start = IRQ_DA850_CCINT1, .flags = IORESOURCE_IRQ, }, { .name = "edma1_err", .start = IRQ_DA850_CCERRINT1, .flags = IORESOURCE_IRQ, },};static struct platform_device da830_edma_device = { .name = "edma", .id = -1, .dev = { .platform_data = da830_edma_info, }, .num_resources = ARRAY_SIZE(da830_edma_resources), .resource = da830_edma_resources,};static struct platform_device da850_edma_device = { .name = "edma", .id = -1, .dev = { .platform_data = da850_edma_info, }, .num_resources = ARRAY_SIZE(da850_edma_resources), .resource = da850_edma_resources,};int __init da830_register_edma(struct edma_rsv_info *rsv){ da830_edma_cc0_info.rsv = rsv; return platform_device_register(&da830_edma_device);}int __init da850_register_edma(struct edma_rsv_info *rsv[2]){ if (rsv) { da850_edma_cc_info[0].rsv = rsv[0]; da850_edma_cc_info[1].rsv = rsv[1]; } return platform_device_register(&da850_edma_device);}static struct resource da8xx_i2c_resources0[] = { { .start = DA8XX_I2C0_BASE, .end = DA8XX_I2C0_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { .start = IRQ_DA8XX_I2CINT0, .end = IRQ_DA8XX_I2CINT0, .flags = IORESOURCE_IRQ, },};static struct platform_device da8xx_i2c_device0 = { .name = "i2c_davinci", .id = 1, .num_resources = ARRAY_SIZE(da8xx_i2c_resources0), .resource = da8xx_i2c_resources0,};static struct resource da8xx_i2c_resources1[] = { { .start = DA8XX_I2C1_BASE, .end = DA8XX_I2C1_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { .start = IRQ_DA8XX_I2CINT1, .end = IRQ_DA8XX_I2CINT1, .flags = IORESOURCE_IRQ, },};static struct platform_device da8xx_i2c_device1 = { .name = "i2c_davinci", .id = 2, .num_resources = ARRAY_SIZE(da8xx_i2c_resources1), .resource = da8xx_i2c_resources1,};int __init da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata){ struct platform_device *pdev; if (instance == 0) pdev = &da8xx_i2c_device0; else if (instance == 1) pdev = &da8xx_i2c_device1; else return -EINVAL; pdev->dev.platform_data = pdata; return platform_device_register(pdev);}static struct resource da8xx_watchdog_resources[] = { { .start = DA8XX_WDOG_BASE, .end = DA8XX_WDOG_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, },};struct platform_device da8xx_wdt_device = { .name = "watchdog", .id = -1, .num_resources = ARRAY_SIZE(da8xx_watchdog_resources), .resource = da8xx_watchdog_resources,};int __init da8xx_register_watchdog(void){ return platform_device_register(&da8xx_wdt_device);}static struct resource da8xx_emac_resources[] = { { .start = DA8XX_EMAC_CPPI_PORT_BASE, .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { .start = IRQ_DA8XX_C0_RX_THRESH_PULSE, .end = IRQ_DA8XX_C0_RX_THRESH_PULSE, .flags = IORESOURCE_IRQ, }, { .start = IRQ_DA8XX_C0_RX_PULSE, .end = IRQ_DA8XX_C0_RX_PULSE, .flags = IORESOURCE_IRQ, }, { .start = IRQ_DA8XX_C0_TX_PULSE, .end = IRQ_DA8XX_C0_TX_PULSE, .flags = IORESOURCE_IRQ, }, { .start = IRQ_DA8XX_C0_MISC_PULSE, .end = IRQ_DA8XX_C0_MISC_PULSE, .flags = IORESOURCE_IRQ, },};struct emac_platform_data da8xx_emac_pdata = { .ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET, .ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET, .ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET, .ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE, .version = EMAC_VERSION_2,};static struct platform_device da8xx_emac_device = { .name = "davinci_emac", .id = 1, .dev = { .platform_data = &da8xx_emac_pdata, }, .num_resources = ARRAY_SIZE(da8xx_emac_resources), .resource = da8xx_emac_resources,};static struct resource da8xx_mdio_resources[] = { { .start = DA8XX_EMAC_MDIO_BASE, .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, },};static struct platform_device da8xx_mdio_device = { .name = "davinci_mdio", .id = 0, .num_resources = ARRAY_SIZE(da8xx_mdio_resources), .resource = da8xx_mdio_resources,};int __init da8xx_register_emac(void){ int ret; ret = platform_device_register(&da8xx_mdio_device); if (ret < 0) return ret; ret = platform_device_register(&da8xx_emac_device); if (ret < 0) return ret; ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev), NULL, &da8xx_emac_device.dev); return ret;}static struct resource da830_mcasp1_resources[] = { { .name = "mcasp1", .start = DAVINCI_DA830_MCASP1_REG_BASE, .end = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1, .flags = IORESOURCE_MEM, }, /* TX event */ { .start = DAVINCI_DA830_DMA_MCASP1_AXEVT, .end = DAVINCI_DA830_DMA_MCASP1_AXEVT, .flags = IORESOURCE_DMA, }, /* RX event */ { .start = DAVINCI_DA830_DMA_MCASP1_AREVT, .end = DAVINCI_DA830_DMA_MCASP1_AREVT, .flags = IORESOURCE_DMA, },};static struct platform_device da830_mcasp1_device = { .name = "davinci-mcasp", .id = 1, .num_resources = ARRAY_SIZE(da830_mcasp1_resources), .resource = da830_mcasp1_resources,};static struct resource da850_mcasp_resources[] = { { .name = "mcasp", .start = DAVINCI_DA8XX_MCASP0_REG_BASE, .end = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1, .flags = IORESOURCE_MEM, }, /* TX event */ { .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, .flags = IORESOURCE_DMA, }, /* RX event */ { .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT, .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT, .flags = IORESOURCE_DMA, },};static struct platform_device da850_mcasp_device = { .name = "davinci-mcasp", .id = 0, .num_resources = ARRAY_SIZE(da850_mcasp_resources), .resource = da850_mcasp_resources,};struct platform_device davinci_pcm_device = { .name = "davinci-pcm-audio", .id = -1,};void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata){ platform_device_register(&davinci_pcm_device); /* DA830/OMAP-L137 has 3 instances of McASP */ if (cpu_is_davinci_da830() && id == 1) { da830_mcasp1_device.dev.platform_data = pdata; platform_device_register(&da830_mcasp1_device); } else if (cpu_is_davinci_da850()) { da850_mcasp_device.dev.platform_data = pdata; platform_device_register(&da850_mcasp_device); }}static const struct display_panel disp_panel = { QVGA, 16, 16, COLOR_ACTIVE,};static struct lcd_ctrl_config lcd_cfg = { &disp_panel, .ac_bias = 255, .ac_bias_intrpt = 0, .dma_burst_sz = 16, .bpp = 16, .fdd = 255, .tft_alt_mode = 0, .stn_565_mode = 0, .mono_8bit_mode = 0, .invert_line_clock = 1, .invert_frm_clock = 1, .sync_edge = 0, .sync_ctrl = 1, .raster_order = 0,};struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { .manu_name = "sharp", .controller_data = &lcd_cfg, .type = "Sharp_LCD035Q3DG01",};struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = { .manu_name = "sharp", .controller_data = &lcd_cfg, .type = "Sharp_LK043T1DG01",};static struct resource da8xx_lcdc_resources[] = { [0] = { /* registers */ .start = DA8XX_LCD_CNTRL_BASE, .end = DA8XX_LCD_CNTRL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { /* interrupt */ .start = IRQ_DA8XX_LCDINT, .end = IRQ_DA8XX_LCDINT, .flags = IORESOURCE_IRQ, },};static struct platform_device da8xx_lcdc_device = { .name = "da8xx_lcdc", .id = 0, .num_resources = ARRAY_SIZE(da8xx_lcdc_resources), .resource = da8xx_lcdc_resources,};int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata){ da8xx_lcdc_device.dev.platform_data = pdata; return platform_device_register(&da8xx_lcdc_device);}static struct resource da8xx_mmcsd0_resources[] = { { /* registers */ .start = DA8XX_MMCSD0_BASE, .end = DA8XX_MMCSD0_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { /* interrupt */ .start = IRQ_DA8XX_MMCSDINT0, .end = IRQ_DA8XX_MMCSDINT0, .flags = IORESOURCE_IRQ, }, { /* DMA RX */ .start = DA8XX_DMA_MMCSD0_RX, .end = DA8XX_DMA_MMCSD0_RX, .flags = IORESOURCE_DMA, }, { /* DMA TX */ .start = DA8XX_DMA_MMCSD0_TX, .end = DA8XX_DMA_MMCSD0_TX, .flags = IORESOURCE_DMA, },};static struct platform_device da8xx_mmcsd0_device = { .name = "davinci_mmc", .id = 0, .num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources), .resource = da8xx_mmcsd0_resources,};int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config){ da8xx_mmcsd0_device.dev.platform_data = config; return platform_device_register(&da8xx_mmcsd0_device);}#ifdef CONFIG_ARCH_DAVINCI_DA850static struct resource da850_mmcsd1_resources[] = { { /* registers */ .start = DA850_MMCSD1_BASE, .end = DA850_MMCSD1_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { /* interrupt */ .start = IRQ_DA850_MMCSDINT0_1, .end = IRQ_DA850_MMCSDINT0_1, .flags = IORESOURCE_IRQ, }, { /* DMA RX */ .start = DA850_DMA_MMCSD1_RX, .end = DA850_DMA_MMCSD1_RX, .flags = IORESOURCE_DMA, }, { /* DMA TX */ .start = DA850_DMA_MMCSD1_TX, .end = DA850_DMA_MMCSD1_TX, .flags = IORESOURCE_DMA, },};static struct platform_device da850_mmcsd1_device = { .name = "davinci_mmc", .id = 1, .num_resources = ARRAY_SIZE(da850_mmcsd1_resources), .resource = da850_mmcsd1_resources,};int __init da850_register_mmcsd1(struct davinci_mmc_config *config){ da850_mmcsd1_device.dev.platform_data = config; return platform_device_register(&da850_mmcsd1_device);}#endifstatic struct resource da8xx_rtc_resources[] = { { .start = DA8XX_RTC_BASE, .end = DA8XX_RTC_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { /* timer irq */ .start = IRQ_DA8XX_RTC, .end = IRQ_DA8XX_RTC, .flags = IORESOURCE_IRQ, }, { /* alarm irq */ .start = IRQ_DA8XX_RTC, .end = IRQ_DA8XX_RTC, .flags = IORESOURCE_IRQ, },};static struct platform_device da8xx_rtc_device = { .name = "omap_rtc", .id = -1, .num_resources = ARRAY_SIZE(da8xx_rtc_resources), .resource = da8xx_rtc_resources,};int da8xx_register_rtc(void){ int ret; void __iomem *base; base = ioremap(DA8XX_RTC_BASE, SZ_4K); if (WARN_ON(!base)) return -ENOMEM; /* Unlock the rtc's registers */ __raw_writel(0x83e70b13, base + 0x6c); __raw_writel(0x95a4f1e0, base + 0x70); iounmap(base); ret = platform_device_register(&da8xx_rtc_device); if (!ret) /* Atleast on DA850, RTC is a wakeup source */ device_init_wakeup(&da8xx_rtc_device.dev, true); return ret;}static void __iomem *da8xx_ddr2_ctlr_base;void __iomem * __init da8xx_get_mem_ctlr(void){ if (da8xx_ddr2_ctlr_base) return da8xx_ddr2_ctlr_base; da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K); if (!da8xx_ddr2_ctlr_base) pr_warning("%s: Unable to map DDR2 controller", __func__); return da8xx_ddr2_ctlr_base;}static struct resource da8xx_cpuidle_resources[] = { { .start = DA8XX_DDR2_CTL_BASE, .end = DA8XX_DDR2_CTL_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, },};/* DA8XX devices support DDR2 power down */static struct davinci_cpuidle_config da8xx_cpuidle_pdata = { .ddr2_pdown = 1,};static struct platform_device da8xx_cpuidle_device = { .name = "cpuidle-davinci", .num_resources = ARRAY_SIZE(da8xx_cpuidle_resources), .resource = da8xx_cpuidle_resources, .dev = { .platform_data = &da8xx_cpuidle_pdata, },};int __init da8xx_register_cpuidle(void){ da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr(); return platform_device_register(&da8xx_cpuidle_device);}static struct resource da8xx_spi0_resources[] = { [0] = { .start = DA8XX_SPI0_BASE, .end = DA8XX_SPI0_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_DA8XX_SPINT0, .end = IRQ_DA8XX_SPINT0, .flags = IORESOURCE_IRQ, }, [2] = { .start = DA8XX_DMA_SPI0_RX, .end = DA8XX_DMA_SPI0_RX, .flags = IORESOURCE_DMA, }, [3] = { .start = DA8XX_DMA_SPI0_TX, .end = DA8XX_DMA_SPI0_TX, .flags = IORESOURCE_DMA, },};static struct resource da8xx_spi1_resources[] = { [0] = { .start = DA830_SPI1_BASE, .end = DA830_SPI1_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_DA8XX_SPINT1, .end = IRQ_DA8XX_SPINT1, .flags = IORESOURCE_IRQ, }, [2] = { .start = DA8XX_DMA_SPI1_RX, .end = DA8XX_DMA_SPI1_RX, .flags = IORESOURCE_DMA, }, [3] = { .start = DA8XX_DMA_SPI1_TX, .end = DA8XX_DMA_SPI1_TX, .flags = IORESOURCE_DMA, },};struct davinci_spi_platform_data da8xx_spi_pdata[] = { [0] = { .version = SPI_VERSION_2, .intr_line = 1, .dma_event_q = EVENTQ_0, }, [1] = { .version = SPI_VERSION_2, .intr_line = 1, .dma_event_q = EVENTQ_0, },};static struct platform_device da8xx_spi_device[] = { [0] = { .name = "spi_davinci", .id = 0, .num_resources = ARRAY_SIZE(da8xx_spi0_resources), .resource = da8xx_spi0_resources, .dev = { .platform_data = &da8xx_spi_pdata[0], }, }, [1] = { .name = "spi_davinci", .id = 1, .num_resources = ARRAY_SIZE(da8xx_spi1_resources), .resource = da8xx_spi1_resources, .dev = { .platform_data = &da8xx_spi_pdata[1], }, },};int __init da8xx_register_spi(int instance, struct spi_board_info *info, unsigned len){ int ret; if (instance < 0 || instance > 1) return -EINVAL; ret = spi_register_board_info(info, len); if (ret) pr_warning("%s: failed to register board info for spi %d :" " %d\n", __func__, instance, ret); da8xx_spi_pdata[instance].num_chipselect = len; if (instance == 1 && cpu_is_davinci_da850()) { da8xx_spi1_resources[0].start = DA850_SPI1_BASE; da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1; } return platform_device_register(&da8xx_spi_device[instance]);}