]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
media: staging: atomisp: Remove FSF snail address
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / media / atomisp / pci / atomisp2 / atomisp_drvfs.c
1 /*
2 * Support for atomisp driver sysfs interface
3 *
4 * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 *
16 */
17
18 #include <linux/err.h>
19 #include <linux/kernel.h>
20 #include <linux/pci.h>
21
22 #include "atomisp_compat.h"
23 #include "atomisp_internal.h"
24 #include "atomisp_ioctl.h"
25 #include "hmm/hmm.h"
26
27 /*
28 * _iunit_debug:
29 * dbglvl: iunit css driver trace level
30 * dbgopt: iunit debug option:
31 * bit 0: binary list
32 * bit 1: running binary
33 * bit 2: memory statistic
34 */
35 struct _iunit_debug {
36 struct pci_driver *drv;
37 struct atomisp_device *isp;
38 unsigned int dbglvl;
39 unsigned int dbgfun;
40 unsigned int dbgopt;
41 };
42
43 #define OPTION_BIN_LIST (1<<0)
44 #define OPTION_BIN_RUN (1<<1)
45 #define OPTION_MEM_STAT (1<<2)
46 #define OPTION_VALID (OPTION_BIN_LIST \
47 | OPTION_BIN_RUN \
48 | OPTION_MEM_STAT)
49
50 static struct _iunit_debug iunit_debug = {
51 .dbglvl = 0,
52 .dbgopt = OPTION_BIN_LIST,
53 };
54
55 static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
56 unsigned int opt)
57 {
58 int ret = 0;
59
60 if (opt & OPTION_VALID) {
61 if (opt & OPTION_BIN_LIST) {
62 ret = atomisp_css_dump_blob_infor();
63 if (ret) {
64 dev_err(atomisp_dev, "%s dump blob infor err[ret:%d]\n",
65 __func__, ret);
66 goto opt_err;
67 }
68 }
69
70 if (opt & OPTION_BIN_RUN) {
71 if (atomisp_streaming_count(isp)) {
72 atomisp_css_dump_sp_raw_copy_linecount(true);
73 atomisp_css_debug_dump_isp_binary();
74 } else {
75 ret = -EPERM;
76 dev_err(atomisp_dev, "%s dump running bin err[ret:%d]\n",
77 __func__, ret);
78 goto opt_err;
79 }
80 }
81
82 if (opt & OPTION_MEM_STAT)
83 hmm_show_mem_stat(__func__, __LINE__);
84 } else {
85 ret = -EINVAL;
86 dev_err(atomisp_dev, "%s dump nothing[ret=%d]\n", __func__,
87 ret);
88 }
89
90 opt_err:
91 return ret;
92 }
93
94 static ssize_t iunit_dbglvl_show(struct device_driver *drv, char *buf)
95 {
96 iunit_debug.dbglvl = atomisp_css_debug_get_dtrace_level();
97 return sprintf(buf, "dtrace level:%u\n", iunit_debug.dbglvl);
98 }
99
100 static ssize_t iunit_dbglvl_store(struct device_driver *drv, const char *buf,
101 size_t size)
102 {
103 if (kstrtouint(buf, 10, &iunit_debug.dbglvl)
104 || iunit_debug.dbglvl < 1
105 || iunit_debug.dbglvl > 9) {
106 return -ERANGE;
107 }
108 atomisp_css_debug_set_dtrace_level(iunit_debug.dbglvl);
109
110 return size;
111 }
112
113 static ssize_t iunit_dbgfun_show(struct device_driver *drv, char *buf)
114 {
115 iunit_debug.dbgfun = atomisp_get_css_dbgfunc();
116 return sprintf(buf, "dbgfun opt:%u\n", iunit_debug.dbgfun);
117 }
118
119 static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf,
120 size_t size)
121 {
122 unsigned int opt;
123 int ret;
124
125 ret = kstrtouint(buf, 10, &opt);
126 if (ret)
127 return ret;
128
129 ret = atomisp_set_css_dbgfunc(iunit_debug.isp, opt);
130 if (ret)
131 return ret;
132
133 iunit_debug.dbgfun = opt;
134
135 return size;
136 }
137
138 static ssize_t iunit_dbgopt_show(struct device_driver *drv, char *buf)
139 {
140 return sprintf(buf, "option:0x%x\n", iunit_debug.dbgopt);
141 }
142
143 static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf,
144 size_t size)
145 {
146 unsigned int opt;
147 int ret;
148
149 ret = kstrtouint(buf, 10, &opt);
150 if (ret)
151 return ret;
152
153 iunit_debug.dbgopt = opt;
154 ret = iunit_dump_dbgopt(iunit_debug.isp, iunit_debug.dbgopt);
155 if (ret)
156 return ret;
157
158 return size;
159 }
160
161 static const struct driver_attribute iunit_drvfs_attrs[] = {
162 __ATTR(dbglvl, 0644, iunit_dbglvl_show, iunit_dbglvl_store),
163 __ATTR(dbgfun, 0644, iunit_dbgfun_show, iunit_dbgfun_store),
164 __ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store),
165 };
166
167 static int iunit_drvfs_create_files(struct pci_driver *drv)
168 {
169 int i, ret = 0;
170
171 for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
172 ret |= driver_create_file(&(drv->driver),
173 &iunit_drvfs_attrs[i]);
174
175 return ret;
176 }
177
178 static void iunit_drvfs_remove_files(struct pci_driver *drv)
179 {
180 int i;
181
182 for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
183 driver_remove_file(&(drv->driver), &iunit_drvfs_attrs[i]);
184 }
185
186 int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device *isp)
187 {
188 int ret;
189
190 iunit_debug.isp = isp;
191 iunit_debug.drv = drv;
192
193 ret = iunit_drvfs_create_files(iunit_debug.drv);
194 if (ret) {
195 dev_err(atomisp_dev, "drvfs_create_files error: %d\n", ret);
196 iunit_drvfs_remove_files(drv);
197 }
198
199 return ret;
200 }
201
202 void atomisp_drvfs_exit(void)
203 {
204 iunit_drvfs_remove_files(iunit_debug.drv);
205 }