Hi,
I am writing a framebuffer driver and the kernel seems to hang while accessing the IO re-mapped memory.
Here is what I did: In my platform specific file, I added the platform_device
Code:
#define DK_LCDC_BASE AT91_CHIPSELECT_7
static struct resource lcdc_resources[] = { // Resource 0 is framebuffer [0] = { .start = DK_LCDC_BASE + SZ_2M, .end = DK_LCDC_BASE + SZ_4M - 1, .flags = IORESOURCE_MEM, }, // Resource 1 is register space [1] = { .start = DK_LCDC_BASE, .end = DK_LCDC_BASE + SZ_2M - 1, .flags = IORESOURCE_MEM, }, };
static struct platform_device at91_lcdc_device = { .name = "s1d13513fb", .id = -1, // only one .dev = { .platform_data = NULL, }, .resource = lcdc_resources, .num_resources = ARRAY_SIZE(lcdc_resources), };
And in the framebuffer driver, I added the platform_driver
Code:
static int __devinit s1d13xxxfb_probe(struct platform_device *pdev) { .........
if (!request_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start +1, "s1d13xxxfb mem")) {
dev_dbg(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto bail; }
if (!request_mem_region(pdev->resource[1].start, pdev->resource[1].end - pdev->resource[1].start +1, "s1d13xxxfb regs")) {
dev_dbg(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto bail; }
default_par = info->par; default_par->regs = ioremap_nocache(pdev->resource[1].start, pdev->resource[1].end - pdev->resource[1].start +1); if (!default_par->regs) { printk(KERN_ERR PFX "unable to map registers\n"); ret = -ENOMEM; goto bail; } info->pseudo_palette = default_par->pseudo_palette;
info->screen_base = ioremap_nocache(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start +1);
if (!info->screen_base) { printk(KERN_ERR PFX "unable to map framebuffer\n"); ret = -ENOMEM; goto bail; }
Now, all this succeeds as observed by the debug messages. However, when I access the IO memory using ioread16 or iowrite16 functions or even the old readw or writew functions, the kernel crashes.
Why is it happening even after the success of request_mem_region and ioremap calls?
I have tried the following:
- Disable most of the other peripherals so that they don't interfere with this peripheral.
- Comment out the initialization code that acceses this IO memory and try to access it from user space using cat > /dev/fb0.
But when I access it from a user space, the kernel hangs confirming that indeed the problem is in the access.
Please help me identifying where I am going wrong.