diff --git a/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts b/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts index 6c50d5874..20de61b04 100755 --- a/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts +++ b/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts @@ -41,10 +41,6 @@ }; reserved-memory { - wakeup_source: wakeup_source { - reg = <0x0 0x4307F000 0x0 0x00001000>; - no-map; - }; e907_fw: e907_fw { reg = <0x0 0x43080000 0x0 0x00190000>; }; @@ -97,6 +93,11 @@ reg = <0x0 0x4304A000 0x0 0x1000>; no-map; }; + wakeup_source: wakeup_source { + reg = <0x0 0x4304B000 0x0 0x00001000>; + compatible = "wakeup-src"; + no-map; + }; boot_param: boot_param@0x42FFF000 { reg = <0x0 0x42FFF000 0x0 0x1000>; diff --git a/lichee/brandy-2.0/spl/board/sun8iw21p1/commonfastboot_sl100_front.mk b/lichee/brandy-2.0/spl/board/sun8iw21p1/commonfastboot_sl100_front.mk index 441886213..54ca4f41f 100755 --- a/lichee/brandy-2.0/spl/board/sun8iw21p1/commonfastboot_sl100_front.mk +++ b/lichee/brandy-2.0/spl/board/sun8iw21p1/commonfastboot_sl100_front.mk @@ -30,6 +30,6 @@ CFG_MELISELF_LOAD_ADDR=0x43080000 #get wakeup source from M0 CFG_GET_WKSRC=y -CFG_WKSRC_ADDR=0x4307F000 +CFG_WKSRC_ADDR=0x4304B000 #E907 interrupt table info update #CFG_UPDATA_IRQ_TAB=y diff --git a/lichee/linux-4.9/drivers/char/mem_operation/mem_operation_drv.c b/lichee/linux-4.9/drivers/char/mem_operation/mem_operation_drv.c index d06fffad2..0cd11c14a 100755 --- a/lichee/linux-4.9/drivers/char/mem_operation/mem_operation_drv.c +++ b/lichee/linux-4.9/drivers/char/mem_operation/mem_operation_drv.c @@ -21,15 +21,48 @@ #include #include #include +#include +#include -#define WEIGHT_ADDR 0x4307F000 // 权重加载的内存地址处 -#define M_PAGE_SIZE (4 * 1024) // 内存对齐,应该是4K +// #define WEIGHT_ADDR 0x4307F000 // 权重加载的内存地址处 +// #define M_PAGE_SIZE (4 * 1024) // 内存对齐,应该是4K #define MEM_ACCESS_RELEASE_PHYS_ADDR _IOR('M', 0, unsigned int) #define MEM_ACCESS_GET_WKSRC_SRC _IOW('M', 1, unsigned int) #define MEM_ACCESS_SET_WKSRC_SRC _IOR('M', 2, unsigned int) +typedef struct { + unsigned char readData[sizeof(int)]; +} wakeup_src_t; + static int major = 0; static struct class *mem_operation_class; +struct mem_area_info { + atomic_t init_flag; + void __iomem *g_vaddr; + int len; +}; + +static struct mem_area_info g_mem = {.init_flag = ATOMIC_INIT(0), .g_vaddr = NULL}; + +int mem_set_wakeup_source(unsigned char wakeup_src) { + if (atomic_read(&g_mem.init_flag) == 1) + { + writeb(wakeup_src, g_mem.g_vaddr); + return 0; + } + return -1; +} +EXPORT_SYMBOL(mem_set_wakeup_source); + +unsigned char mem_get_wakeup_source(void) { + if (atomic_read(&g_mem.init_flag) == 1) + { + return readb(g_mem.g_vaddr); + } + return 0xFF; +} +EXPORT_SYMBOL(mem_get_wakeup_source); + static int check_page_reserved(unsigned long addr) { @@ -59,9 +92,9 @@ static int mem_operation_drv_close (struct inode *node, struct file *file) static int mem_operation_drv_mmap(struct file *file, struct vm_area_struct *vma) { - unsigned long phy = WEIGHT_ADDR; + unsigned long phy = (unsigned long)g_mem.g_vaddr; - if(check_page_reserved(WEIGHT_ADDR) < 0) + if(check_page_reserved((unsigned long)g_mem.g_vaddr) < 0) return -EINVAL; /* 设置属性: cache, buffer */ @@ -77,9 +110,7 @@ static int mem_operation_drv_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -typedef struct { - unsigned char readData[sizeof(int)]; -} wakeup_src_t; + static long mem_operation_drv_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -93,57 +124,44 @@ static long mem_operation_drv_ioctl(struct file *file, unsigned int cmd, unsigne if (get_user(mem_size, (unsigned long __user *)arg)) return -EFAULT; - if(check_page_reserved(WEIGHT_ADDR) < 0) + if(check_page_reserved((unsigned long)g_mem.g_vaddr) < 0) return -EINVAL; - memblock_free(WEIGHT_ADDR, mem_size); - free_reserved_area(__va(WEIGHT_ADDR), __va(WEIGHT_ADDR + mem_size), -1, "wakeup_source"); - printk("release phy addr: 0x%x, size: %d\n", WEIGHT_ADDR, mem_size); + memblock_free((unsigned int)g_mem.g_vaddr, mem_size); + free_reserved_area(__va(g_mem.g_vaddr), __va(g_mem.g_vaddr + mem_size), -1, "wakeup_source"); + // printk("release phy addr: 0x%x, size: %d\n", (int)g_mem.g_vaddr, mem_size); break; } case MEM_ACCESS_GET_WKSRC_SRC: { - void __iomem *vaddr = NULL; + // void __iomem *vaddr = NULL; // vaddr = ioremap(WEIGHT_ADDR, sizeof(wakeupsrc)); // vaddr = ioremap_nocache(PHYS_ADDR, SIZE); - vaddr = memremap(WEIGHT_ADDR, M_PAGE_SIZE, MEMREMAP_WB); - if (!vaddr) - { - return -EINVAL; - } + wakeupsrc.readData[0] = readb(g_mem.g_vaddr); - wakeupsrc.readData[0] = readb(vaddr); // memcpy_fromio(buffer, vaddr, SIZE); // copy_to_user(arg, vaddr, SIZE) ? // printk(KERN_EMERG "give wake up source:%d\n", wakeupsrc.readData[0]); - if (copy_to_user(arg, &wakeupsrc, sizeof(wakeupsrc))) + if (copy_to_user((void *)arg, &wakeupsrc, sizeof(wakeupsrc))) { // iounmap(vaddr); - memunmap(vaddr); return -EINVAL; } // iounmap(vaddr); - memunmap(vaddr); break; } case MEM_ACCESS_SET_WKSRC_SRC: { - void __iomem *vaddr = NULL; + // void __iomem *vaddr = NULL; if (copy_from_user(&wakeupsrc, (void __user *)arg, sizeof(wakeupsrc))) { return -EFAULT; } - vaddr = memremap(WEIGHT_ADDR, M_PAGE_SIZE, MEMREMAP_WB); - if (!vaddr) - { - return -EINVAL; - } - writeb(wakeupsrc.readData[0], vaddr); - memunmap(vaddr); + writeb(wakeupsrc.readData[0], g_mem.g_vaddr); // printk(KERN_EMERG "set wake up source:%d\n", wakeupsrc.readData[0]); break; @@ -167,8 +185,31 @@ static struct file_operations mem_operation_drv = { static int __init mem_operation_init(void) { int err; + struct device_node *np; + struct resource res; - printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); + np = of_find_compatible_node(NULL, NULL, "wakeup-src"); + if (!np) { + pr_err("mem Reserved memory node not found\n"); + return -ENODEV; + } + if (of_address_to_resource(np, 0, &res)) { + pr_err("mem Failed to parse reg\n"); + of_node_put(np); + return -EFAULT; + } + g_mem.len = resource_size(&res); + g_mem.g_vaddr = memremap(res.start, g_mem.len, MEMREMAP_WB); + if (!g_mem.g_vaddr) + { + return -EINVAL; + } +#ifdef CONFIG_XR806_WLAN + writeb(0, g_mem.g_vaddr); // 如果xr806而非boot0获取唤醒源,需要先设默认值 +#endif + atomic_set(&g_mem.init_flag, 1); + + // printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); major = register_chrdev(0, "mem_operation", &mem_operation_drv); /* /dev/mem_operation */ mem_operation_class = class_create(THIS_MODULE, "mem_operation_class"); @@ -176,6 +217,7 @@ static int __init mem_operation_init(void) if (IS_ERR(mem_operation_class)) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); unregister_chrdev(major, "mem_operation"); + memunmap(g_mem.g_vaddr); return -1; } @@ -190,8 +232,13 @@ static void __exit mem_operation_exit(void) device_destroy(mem_operation_class, MKDEV(major, 0)); class_destroy(mem_operation_class); unregister_chrdev(major, "mem_operation"); + if (atomic_read(&g_mem.init_flag) == 1) + { + memunmap(g_mem.g_vaddr); + } } -module_init(mem_operation_init); +// 注意放在disp之前 +fs_initcall_sync(mem_operation_init); module_exit(mem_operation_exit); MODULE_LICENSE("GPL");