1ff3a3e9bSPekka Paalanen /* 2ff3a3e9bSPekka Paalanen * Written by Pekka Paalanen, 2008 <pq@iki.fi> 3ff3a3e9bSPekka Paalanen */ 4ff3a3e9bSPekka Paalanen #include <linux/module.h> 5970e6fa0SPekka Paalanen #include <linux/io.h> 6*9e57fb35SPekka Paalanen #include <linux/mmiotrace.h> 7ff3a3e9bSPekka Paalanen 8ff3a3e9bSPekka Paalanen #define MODULE_NAME "testmmiotrace" 9ff3a3e9bSPekka Paalanen 10ff3a3e9bSPekka Paalanen static unsigned long mmio_address; 11ff3a3e9bSPekka Paalanen module_param(mmio_address, ulong, 0); 12ff3a3e9bSPekka Paalanen MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB."); 13ff3a3e9bSPekka Paalanen 14ff3a3e9bSPekka Paalanen static void do_write_test(void __iomem *p) 15ff3a3e9bSPekka Paalanen { 16ff3a3e9bSPekka Paalanen unsigned int i; 17*9e57fb35SPekka Paalanen mmiotrace_printk("Write test.\n"); 18ff3a3e9bSPekka Paalanen for (i = 0; i < 256; i++) 19ff3a3e9bSPekka Paalanen iowrite8(i, p + i); 20ff3a3e9bSPekka Paalanen for (i = 1024; i < (5 * 1024); i += 2) 21ff3a3e9bSPekka Paalanen iowrite16(i * 12 + 7, p + i); 22ff3a3e9bSPekka Paalanen for (i = (5 * 1024); i < (16 * 1024); i += 4) 23ff3a3e9bSPekka Paalanen iowrite32(i * 212371 + 13, p + i); 24ff3a3e9bSPekka Paalanen } 25ff3a3e9bSPekka Paalanen 26ff3a3e9bSPekka Paalanen static void do_read_test(void __iomem *p) 27ff3a3e9bSPekka Paalanen { 28ff3a3e9bSPekka Paalanen unsigned int i; 29*9e57fb35SPekka Paalanen mmiotrace_printk("Read test.\n"); 30ff3a3e9bSPekka Paalanen for (i = 0; i < 256; i++) 31ff3a3e9bSPekka Paalanen ioread8(p + i); 32ff3a3e9bSPekka Paalanen for (i = 1024; i < (5 * 1024); i += 2) 33ff3a3e9bSPekka Paalanen ioread16(p + i); 34ff3a3e9bSPekka Paalanen for (i = (5 * 1024); i < (16 * 1024); i += 4) 35ff3a3e9bSPekka Paalanen ioread32(p + i); 36ff3a3e9bSPekka Paalanen } 37ff3a3e9bSPekka Paalanen 38ff3a3e9bSPekka Paalanen static void do_test(void) 39ff3a3e9bSPekka Paalanen { 40ff3a3e9bSPekka Paalanen void __iomem *p = ioremap_nocache(mmio_address, 0x4000); 41ff3a3e9bSPekka Paalanen if (!p) { 42ff3a3e9bSPekka Paalanen pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); 43ff3a3e9bSPekka Paalanen return; 44ff3a3e9bSPekka Paalanen } 45*9e57fb35SPekka Paalanen mmiotrace_printk("ioremap returned %p.\n", p); 46ff3a3e9bSPekka Paalanen do_write_test(p); 47ff3a3e9bSPekka Paalanen do_read_test(p); 48ff3a3e9bSPekka Paalanen iounmap(p); 49ff3a3e9bSPekka Paalanen } 50ff3a3e9bSPekka Paalanen 51ff3a3e9bSPekka Paalanen static int __init init(void) 52ff3a3e9bSPekka Paalanen { 53ff3a3e9bSPekka Paalanen if (mmio_address == 0) { 54ff3a3e9bSPekka Paalanen pr_err(MODULE_NAME ": you have to use the module argument " 55ff3a3e9bSPekka Paalanen "mmio_address.\n"); 56ff3a3e9bSPekka Paalanen pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" 57ff3a3e9bSPekka Paalanen " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); 58ff3a3e9bSPekka Paalanen return -ENXIO; 59ff3a3e9bSPekka Paalanen } 60ff3a3e9bSPekka Paalanen 61ff3a3e9bSPekka Paalanen pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx " 62ff3a3e9bSPekka Paalanen "in PCI address space, and writing " 63ff3a3e9bSPekka Paalanen "rubbish in there.\n", mmio_address); 64ff3a3e9bSPekka Paalanen do_test(); 65ff3a3e9bSPekka Paalanen return 0; 66ff3a3e9bSPekka Paalanen } 67ff3a3e9bSPekka Paalanen 68ff3a3e9bSPekka Paalanen static void __exit cleanup(void) 69ff3a3e9bSPekka Paalanen { 70ff3a3e9bSPekka Paalanen pr_debug(MODULE_NAME ": unloaded.\n"); 71ff3a3e9bSPekka Paalanen } 72ff3a3e9bSPekka Paalanen 73ff3a3e9bSPekka Paalanen module_init(init); 74ff3a3e9bSPekka Paalanen module_exit(cleanup); 75ff3a3e9bSPekka Paalanen MODULE_LICENSE("GPL"); 76