- we must take care not to conflict with other drivers
- Linux kernel only sees virtual addresses -> we cannot simply
access physical memory.
- we must take that compiler optimization / cpu reordering doesn't bite us, but forget about
volatile
! (Documentation/volatile-considered-harmfull)
- especially powerpc people: beware of big endian registers!
API:
avoid conflicts with other drivers:
struct resource *request_mem_region(unsigned long start, unsigned long len, char *name);
void release_mem_region(unsigned long start, unsigned long len);
this shows up in
/proc/iomem
:
-bash-3.2# cat /proc/iomem
90000000-97ffffff : /plb/pciex@0a0000000
98000000-9fffffff : /plb/pciex@0c0000000
ef600200-ef600207 : serial
ef600300-ef600307 : serial
ef600400-ef600411 : ibm_iic
ef600500-ef600511 : ibm_iic
ef6c0000-ef6cffff : dwc_otg.0
ef6c0000-ef6cffff : dwc_otg
f8000000-f8001fff : ndfc-nand.0
fc000000-ffffffff : fc000000.nor_flash
exclusive variants
request_mem_region_exclusive(start, n, name);
- control with
iomem=relaxed
map physical address into kernel address space:
void *ioremap(unsigned long phys_addr, unsigned long size);
void iounmap(void *addr);
avoid compiler optimization problems:
void barrier();
avoid compiler and hardware reordering problems:
mb(void)
rmb(void)
wmb(void)
be portable and avoid above problems:
void io(write|read)(8|16|32)[be] functions
be
versions for big endian registers!