#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>

static struct mtd_info *rtk_mtd = NULL;

#define CONFIG_RTK_MTD_MAP_SIZE 0x1000000

static struct map_info rtk_mtd_map = {
	name: "rtkspi",
	size: CONFIG_RTK_MTD_MAP_SIZE,
	bankwidth: 2,
	phys: 0xbd000000,
	virt: 0xb9000000
	
};

static struct mtd_partition rtl867x_parts[] = {	
	{ 
	.name       = "boot",
	.offset     = 0, 
	.size       = 0x10000,  
	.mask_flags = MTD_WRITEABLE 
	},
	{ 
	.name       = "config",	
	.offset     = MTDPART_OFS_APPEND, 
	.size       = 0x10000,  
	.mask_flags = 0 },
	{ 
	.name       = "tr069",	
	.offset     = MTDPART_OFS_APPEND, 
	.size       = 0x20000,  
	.mask_flags = 0 
	},
	{ 
	.name       = "linux",	
	.offset     = MTDPART_OFS_APPEND, 
	.size       = 0x200000,  
	.mask_flags = 0 
	},
	{ 
	.name       = "rootfs",	
	.offset     = MTDPART_OFS_APPEND,
	.size       = MTDPART_SIZ_FULL,
	.mask_flags = 0 
	}	
};


static int __init rtk_map_init(void) {	
	int err;
	const char*part_probes[] = {"cmdlinepart", NULL,};
	
	simple_map_init(&rtk_mtd_map);
		
	rtk_mtd = do_map_probe("rtkspi_probe", &rtk_mtd_map);
	
	if (!rtk_mtd) {
		printk("rtk_map probe fail\n");
		return -EIO;
	}
	
	rtk_mtd->owner = THIS_MODULE;
	
	err = mtd_device_parse_register(rtk_mtd, part_probes, NULL, rtl867x_parts, ARRAY_SIZE(rtl867x_parts));
	if (err)
		printk(KERN_ERR "rtkspi: fail to parse partitions\n");
	
	return err;
}

static void __exit rtk_map_exit(void) {
	if (rtk_mtd) {
		mtd_device_unregister(rtk_mtd);
		map_destroy(rtk_mtd);
	}
}

module_init(rtk_map_init);
module_exit(rtk_map_exit);

MODULE_AUTHOR("Andrew Chang <yachang@realtek.com>");
MODULE_DESCRIPTION("Realtek MTD Maps");