1 /*
2  * FRAM driver for MIMC200 board
3  *
4  * Copyright 2008 Mark Jackson <mpfj@mimc.co.uk>
5  *
6  * This module adds *very* simply support for the system's FRAM device.
7  * At the moment, this is hard-coded to the MIMC200 platform, and only
8  * supports mmap().
9  */
10 
11 #define FRAM_VERSION	"1.0"
12 
13 #include <linux/miscdevice.h>
14 #include <linux/module.h>
15 #include <linux/proc_fs.h>
16 #include <linux/mm.h>
17 #include <linux/io.h>
18 
19 #define FRAM_BASE	0xac000000
20 #define FRAM_SIZE	0x20000
21 
22 /*
23  * The are the file operation function for user access to /dev/fram
24  */
25 
fram_mmap(struct file * filp,struct vm_area_struct * vma)26 static int fram_mmap(struct file *filp, struct vm_area_struct *vma)
27 {
28 	int ret;
29 
30 	ret = remap_pfn_range(vma,
31 		vma->vm_start,
32 		virt_to_phys((void *)((unsigned long)FRAM_BASE)) >> PAGE_SHIFT,
33 		vma->vm_end-vma->vm_start,
34 		PAGE_SHARED);
35 
36 	if (ret != 0)
37 		return -EAGAIN;
38 
39 	return 0;
40 }
41 
42 static const struct file_operations fram_fops = {
43 	.owner			= THIS_MODULE,
44 	.mmap			= fram_mmap,
45 	.llseek			= noop_llseek,
46 };
47 
48 #define FRAM_MINOR	0
49 
50 static struct miscdevice fram_dev = {
51 	FRAM_MINOR,
52 	"fram",
53 	&fram_fops
54 };
55 
56 static int __init
fram_init(void)57 fram_init(void)
58 {
59 	int ret;
60 
61 	ret = misc_register(&fram_dev);
62 	if (ret) {
63 		printk(KERN_ERR "fram: can't misc_register on minor=%d\n",
64 		    FRAM_MINOR);
65 		return ret;
66 	}
67 	printk(KERN_INFO "FRAM memory driver v" FRAM_VERSION "\n");
68 	return 0;
69 }
70 
71 static void __exit
fram_cleanup_module(void)72 fram_cleanup_module(void)
73 {
74 	misc_deregister(&fram_dev);
75 }
76 
77 module_init(fram_init);
78 module_exit(fram_cleanup_module);
79 
80 MODULE_LICENSE("GPL");
81 
82 MODULE_ALIAS_MISCDEV(FRAM_MINOR);
83