• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include <linux/miscdevice.h>
20 #include "securec.h"
21 #include "hi_osal.h"
22 #include "hidev.h"
23 
24 static osal_semaphore g_hidev_pm_sem = {0};
25 static hi_u32 g_hidev_pm_cmd = -1;
26 static hi_s32 g_dbg_flag = 1;
27 #define hidev_dbg(params...) do { \
28         if (g_dbg_flag) {         \
29             osal_printk(params);  \
30         }                         \
31     } while (0)
32 
hidev_open(hi_void * private_data)33 static hi_s32 hidev_open(hi_void *private_data)
34 {
35     hidev_dbg("Enter hidev_open\n");
36     return HI_SUCCESS;
37 }
38 
hidev_release(hi_void * private_data)39 static hi_s32 hidev_release(hi_void *private_data)
40 {
41     hidev_dbg("Enter hidev_release\n");
42     return HI_SUCCESS;
43 }
44 
hidev_get_pm_cmd(unsigned int cmd,hi_void * para,hi_void * private_data)45 static hi_s32 hidev_get_pm_cmd(unsigned int cmd, hi_void *para, hi_void *private_data)
46 {
47     struct hidev_pm_cmd *pm_cmd = para;
48     hi_s32 ret;
49 
50     ret = osal_sem_down_interruptible(&g_hidev_pm_sem);
51     if (ret == 0) {
52         hidev_dbg("hidev get pm cmd %d.\n", g_hidev_pm_cmd);
53     }
54     pm_cmd->cmd = g_hidev_pm_cmd;
55     return ret;
56 }
57 
hidev_free_block_mem(unsigned int cmd,hi_void * para,hi_void * private_data)58 static hi_s32 hidev_free_block_mem(unsigned int cmd, hi_void *para, hi_void *private_data)
59 {
60     struct hidev_block_mem *block_mem = para;
61     hidev_dbg("hidev_free_block_mem physaddr 0x%x, size %u.\n", block_mem->phys_addr, block_mem->size);
62     osal_blockmem_free(block_mem->phys_addr, block_mem->size);
63     return HI_SUCCESS;
64 }
65 
hidev_pm_suspend(hi_void * private_data)66 static hi_s32 hidev_pm_suspend(hi_void *private_data)
67 {
68     /* userspace drv suspend called from userspace directly */
69     return HI_SUCCESS;
70 }
71 
hidev_pm_resume(hi_void * private_data)72 static hi_s32 hidev_pm_resume(hi_void *private_data)
73 {
74     hi_s32 i;
75     g_hidev_pm_cmd = HIDEV_PM_RESUME;
76     hidev_dbg("hidev enter pm cmd %d.\n", g_hidev_pm_cmd);
77     osal_sem_up(&g_hidev_pm_sem);
78     return HI_SUCCESS;
79 }
80 
hidev_pm_lowpower_enter(hi_void * private_data)81 static hi_s32 hidev_pm_lowpower_enter(hi_void *private_data)
82 {
83     g_hidev_pm_cmd = HIDEV_PM_LOWPOWER_ENTER;
84     hidev_dbg("hidev enter pm cmd %d.\n", g_hidev_pm_cmd);
85     osal_sem_up(&g_hidev_pm_sem);
86     return HI_SUCCESS;
87 }
88 
hidev_pm_lowpower_exit(hi_void * private_data)89 static hi_s32 hidev_pm_lowpower_exit(hi_void *private_data)
90 {
91     g_hidev_pm_cmd = HIDEV_PM_LOWPOWER_EXIT;
92     hidev_dbg("hidev enter pm cmd %d.\n", g_hidev_pm_cmd);
93     osal_sem_up(&g_hidev_pm_sem);
94     return HI_SUCCESS;
95 }
96 
hidev_pm_poweroff(hi_void * private_data)97 static hi_s32 hidev_pm_poweroff(hi_void *private_data)
98 {
99     g_hidev_pm_cmd = HIDEV_PM_POWEROFF;
100     hidev_dbg("hidev enter pm cmd %d.\n", g_hidev_pm_cmd);
101     osal_sem_up(&g_hidev_pm_sem);
102     return HI_SUCCESS;
103 }
104 
105 static osal_pmops g_hidev_pmops = {
106     .pm_suspend = hidev_pm_suspend,
107     .pm_resume = hidev_pm_resume,
108     .pm_lowpower_enter = hidev_pm_lowpower_enter,
109     .pm_lowpower_exit = hidev_pm_lowpower_exit,
110     .pm_poweroff = hidev_pm_poweroff,
111 };
112 
113 static osal_ioctl_cmd g_hidev_cmd[] = {
114     {HIDEV_GET_PM_CMD, hidev_get_pm_cmd},
115     {HIDEV_FREE_BLOCK_MEM, hidev_free_block_mem},
116 };
117 
118 static osal_fileops g_hidev_fops = {
119     .open = hidev_open,
120     .release = hidev_release,
121     .cmd_list = g_hidev_cmd,
122     .cmd_cnt = sizeof(g_hidev_cmd) / sizeof(g_hidev_cmd[0]),
123 };
124 
125 static osal_dev g_hidev_dev = {
126     .name = HIDEV_DEVICE_NAME,
127     .minor = MISC_DYNAMIC_MINOR,
128     .fops = &g_hidev_fops,
129     .pmops = &g_hidev_pmops,
130 };
131 
hidev_init(hi_void)132 static hi_s32 hidev_init(hi_void)
133 {
134     if (osal_dev_register(&g_hidev_dev) != 0) {
135         osal_printk("hidev register %s failed.\n", g_hidev_dev.name);
136         return HI_FAILURE;
137     }
138 
139     osal_sem_init(&g_hidev_pm_sem, 0);
140 
141     hidev_dbg("hi_dev init ok.\n");
142     return HI_SUCCESS;
143 }
144 
hidev_deinit(hi_void)145 static hi_void hidev_deinit(hi_void)
146 {
147     osal_dev_unregister(&g_hidev_dev);
148 
149     osal_sem_destory(&g_hidev_pm_sem);
150 
151     hidev_dbg("hi_dev deinit ok.\n");
152 }
153 
hi_dev_module_init(hi_void)154 static hi_s32 hi_dev_module_init(hi_void)
155 {
156     hi_s32 ret;
157     ret = hidev_init();
158     return ret;
159 }
160 
hi_dev_module_exit(hi_void)161 static hi_void hi_dev_module_exit(hi_void)
162 {
163     hidev_deinit();
164     return;
165 }
166 
167 module_init(hi_dev_module_init);
168 module_exit(hi_dev_module_exit);
169