I'm working on a device driver for a 2.4 kernel and I'm having a heck of a hard time.... I've never written a kernel module before, so it's an uphill struggle. By way of background, I am working with Linux Device Drivers, 2nd ed.... And I have a similar driver written for x86 architecture that I am using as a guide.
The hardware is controlled via memory mapped registers at 0x11e0104 -
0x11e0107. From what I've ben able to gather, I need to ioremap this and use the handle returned by ioremap for readb and readw...But... I am thoroughly confused by the kernel mode memory addressing and how it pertains to the ARM architecture.
My init function is this:
#define TSDIO24region 0x11e00104 #define TSDIO24length 4
static char *mem_virt_addr;
int init_TSgpio(void) { int result;
printk("Hello world.\n");
if (check_mem_region(TSDIO24region, TSDIO24length)) { printk("TSgpio: memory already in use\n"); return -EBUSY; } request_mem_region(TSDIO24region, TSDIO24length, "TSDIO24gpio");
if( (result = register_chrdev(TSDIO24major, "TSDIO24", &tsdio24_fops)) < 0) { printk(KERN_WARNING "tsdio24: can't get major %d\n",TSDIO24major); return result; } mem_virt_addr = ioremap(TSDIO24region, TSDIO24length); return 0; }
and my read function is this:
static ssize_t tsdio24_read(struct file *file, char *buf, size_t, length, loff_t *ppos) { printk("0x%02x %02x %02x %02x\n", readb(mem_virt_addr), readb(mem_virt_addr+1), readb(mem_virt_addr+2), readb(mem_virt_addr+3)); return 0; }
While the read function does in fact spit out 4 bytes on `cat /dev/mydev`, they appear to be unrelated to the memory location I want. I did try this with page-aligned ioremap; AFAICT I got the same (wrong) memory area.
I am completely confused by the various 'adjustments' to the memory addresses that I read about... Should I subtract 0x80000000 from the above before I ioremap? Does ioremap have to be page aligned? What *are* the arguments to ioremap? It doesn't seem to be documented anywhere in any detail.
So... How does one do memory mapped IO on an ARM platform in kernel mode?
The driver, BTW, is fairly simple - it will implement IRQs for GPIO pins. I was expecting a struggle over the IRQ code, but this has stumped me early.... :-(
TIA,
--Yan