优化预留内存驱动获取唤醒源的方式
This commit is contained in:
parent
5879cea210
commit
5d71fcb5db
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -21,15 +21,48 @@
|
|||
#include <linux/memblock.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#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");
|
||||
|
|
Loading…
Reference in New Issue