summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c90
1 files changed, 50 insertions, 40 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c b/drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c
index ee59e5de..0fe1c8d2 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_ecc_sysfs.c
@@ -14,6 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/hashtable.h>
18
17#include <nvgpu/kmem.h> 19#include <nvgpu/kmem.h>
18#include <nvgpu/bug.h> 20#include <nvgpu/bug.h>
19#include <nvgpu/hashtable.h> 21#include <nvgpu/hashtable.h>
@@ -28,10 +30,6 @@
28#include "platform_gp10b_tegra.h" 30#include "platform_gp10b_tegra.h"
29#include "platform_ecc_sysfs.h" 31#include "platform_ecc_sysfs.h"
30 32
31#define ECC_STAT_NAME_MAX_SIZE 100
32
33static DEFINE_HASHTABLE(ecc_hash_table, 5);
34
35static u32 gen_ecc_hash_key(char *str) 33static u32 gen_ecc_hash_key(char *str)
36{ 34{
37 int i = 0; 35 int i = 0;
@@ -57,6 +55,7 @@ static ssize_t ecc_stat_show(struct device *dev,
57 struct gk20a_ecc_stat *ecc_stat; 55 struct gk20a_ecc_stat *ecc_stat;
58 u32 hash_key; 56 u32 hash_key;
59 struct gk20a *g = get_gk20a(dev); 57 struct gk20a *g = get_gk20a(dev);
58 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
60 59
61 if (sscanf(ecc_stat_full_name, "ltc%u_lts%u", &hw_unit, 60 if (sscanf(ecc_stat_full_name, "ltc%u_lts%u", &hw_unit,
62 &subunit) == 2) { 61 &subunit) == 2) {
@@ -78,7 +77,7 @@ static ssize_t ecc_stat_show(struct device *dev,
78 77
79 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name); 78 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name);
80 79
81 hash_for_each_possible(ecc_hash_table, 80 hash_for_each_possible(l->ecc_sysfs_stats_htable,
82 ecc_stat, 81 ecc_stat,
83 hash_node, 82 hash_node,
84 hash_key) { 83 hash_key) {
@@ -91,11 +90,9 @@ static ssize_t ecc_stat_show(struct device *dev,
91 return snprintf(buf, PAGE_SIZE, "Error: No ECC stat found!\n"); 90 return snprintf(buf, PAGE_SIZE, "Error: No ECC stat found!\n");
92} 91}
93 92
94int gr_gp10b_ecc_stat_create(struct device *dev, 93int nvgpu_gr_ecc_stat_create(struct device *dev,
95 int is_l2, 94 int is_l2, char *ecc_stat_name,
96 char *ecc_stat_name, 95 struct gk20a_ecc_stat *ecc_stat)
97 struct gk20a_ecc_stat *ecc_stat,
98 struct device_attribute **dev_attr_array)
99{ 96{
100 struct gk20a *g = get_gk20a(dev); 97 struct gk20a *g = get_gk20a(dev);
101 char *ltc_unit_name = "ltc"; 98 char *ltc_unit_name = "ltc";
@@ -113,32 +110,29 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
113 num_hw_units = g->gr.tpc_count; 110 num_hw_units = g->gr.tpc_count;
114 111
115 112
116 return gp10b_ecc_stat_create(dev, num_hw_units, num_subunits, 113 return nvgpu_ecc_stat_create(dev, num_hw_units, num_subunits,
117 is_l2 ? ltc_unit_name : gr_unit_name, 114 is_l2 ? ltc_unit_name : gr_unit_name,
118 num_subunits ? lts_unit_name: NULL, 115 num_subunits ? lts_unit_name: NULL,
119 ecc_stat_name, 116 ecc_stat_name,
120 ecc_stat, 117 ecc_stat);
121 dev_attr_array);
122} 118}
123 119
124int gp10b_ecc_stat_create(struct device *dev, 120int nvgpu_ecc_stat_create(struct device *dev,
125 int num_hw_units, 121 int num_hw_units, int num_subunits,
126 int num_subunits, 122 char *ecc_unit_name, char *ecc_subunit_name,
127 char *ecc_unit_name, 123 char *ecc_stat_name,
128 char *ecc_subunit_name, 124 struct gk20a_ecc_stat *ecc_stat)
129 char *ecc_stat_name,
130 struct gk20a_ecc_stat *ecc_stat,
131 struct device_attribute **__dev_attr_array)
132{ 125{
133 int error = 0; 126 int error = 0;
134 struct gk20a *g = get_gk20a(dev); 127 struct gk20a *g = get_gk20a(dev);
128 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
135 int hw_unit = 0; 129 int hw_unit = 0;
136 int subunit = 0; 130 int subunit = 0;
137 int element = 0; 131 int element = 0;
138 u32 hash_key = 0; 132 u32 hash_key = 0;
139 struct device_attribute *dev_attr_array; 133 struct device_attribute *dev_attr_array;
140 134
141 int num_elements = num_subunits ? num_subunits*num_hw_units : 135 int num_elements = num_subunits ? num_subunits * num_hw_units :
142 num_hw_units; 136 num_hw_units;
143 137
144 /* Allocate arrays */ 138 /* Allocate arrays */
@@ -146,6 +140,7 @@ int gp10b_ecc_stat_create(struct device *dev,
146 num_elements); 140 num_elements);
147 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_elements); 141 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_elements);
148 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_elements); 142 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_elements);
143
149 for (hw_unit = 0; hw_unit < num_elements; hw_unit++) { 144 for (hw_unit = 0; hw_unit < num_elements; hw_unit++) {
150 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) * 145 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) *
151 ECC_STAT_NAME_MAX_SIZE); 146 ECC_STAT_NAME_MAX_SIZE);
@@ -206,44 +201,58 @@ int gp10b_ecc_stat_create(struct device *dev,
206 201
207 /* Add hash table entry */ 202 /* Add hash table entry */
208 hash_key = gen_ecc_hash_key(ecc_stat_name); 203 hash_key = gen_ecc_hash_key(ecc_stat_name);
209 hash_add(ecc_hash_table, 204 hash_add(l->ecc_sysfs_stats_htable,
210 &ecc_stat->hash_node, 205 &ecc_stat->hash_node,
211 hash_key); 206 hash_key);
212 207
213 *__dev_attr_array = dev_attr_array; 208 ecc_stat->attr_array = dev_attr_array;
214 209
215 return error; 210 return error;
216} 211}
217 212
218void gr_gp10b_ecc_stat_remove(struct device *dev, 213void nvgpu_gr_ecc_stat_remove(struct device *dev,
219 int is_l2, 214 int is_l2, struct gk20a_ecc_stat *ecc_stat)
220 struct gk20a_ecc_stat *ecc_stat,
221 struct device_attribute *dev_attr_array)
222{ 215{
223 struct gk20a *g = get_gk20a(dev); 216 struct gk20a *g = get_gk20a(dev);
224 int num_hw_units = 0; 217 int num_hw_units = 0;
218 int num_subunits = 0;
225 219
226 if (is_l2 == 1) 220 if (is_l2 == 1)
227 num_hw_units = g->ltc_count; 221 num_hw_units = g->ltc_count;
228 else if (is_l2 == 2) 222 else if (is_l2 == 2) {
229 num_hw_units = g->ltc_count * g->gr.slices_per_ltc; 223 num_hw_units = g->ltc_count;
230 else 224 num_subunits = g->gr.slices_per_ltc;
225 } else
231 num_hw_units = g->gr.tpc_count; 226 num_hw_units = g->gr.tpc_count;
232 227
233 gp10b_ecc_stat_remove(dev, num_hw_units, ecc_stat, dev_attr_array); 228 nvgpu_ecc_stat_remove(dev, num_hw_units, num_subunits, ecc_stat);
234} 229}
235 230
236void gp10b_ecc_stat_remove(struct device *dev, 231void nvgpu_ecc_stat_remove(struct device *dev,
237 int num_hw_units, 232 int num_hw_units, int num_subunits,
238 struct gk20a_ecc_stat *ecc_stat, 233 struct gk20a_ecc_stat *ecc_stat)
239 struct device_attribute *dev_attr_array)
240{ 234{
241 struct gk20a *g = get_gk20a(dev); 235 struct gk20a *g = get_gk20a(dev);
236 struct device_attribute *dev_attr_array = ecc_stat->attr_array;
242 int hw_unit = 0; 237 int hw_unit = 0;
238 int subunit = 0;
239 int element = 0;
240 int num_elements = num_subunits ? num_subunits * num_hw_units :
241 num_hw_units;
243 242
244 /* Remove sysfs files */ 243 /* Remove sysfs files */
245 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { 244 if (num_subunits) {
246 device_remove_file(dev, &dev_attr_array[hw_unit]); 245 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
246 for (subunit = 0; subunit < num_subunits; subunit++) {
247 element = hw_unit * num_subunits + subunit;
248
249 device_remove_file(dev,
250 &dev_attr_array[element]);
251 }
252 }
253 } else {
254 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++)
255 device_remove_file(dev, &dev_attr_array[hw_unit]);
247 } 256 }
248 257
249 /* Remove hash table entry */ 258 /* Remove hash table entry */
@@ -251,9 +260,10 @@ void gp10b_ecc_stat_remove(struct device *dev,
251 260
252 /* Free arrays */ 261 /* Free arrays */
253 nvgpu_kfree(g, ecc_stat->counters); 262 nvgpu_kfree(g, ecc_stat->counters);
254 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { 263
264 for (hw_unit = 0; hw_unit < num_elements; hw_unit++)
255 nvgpu_kfree(g, ecc_stat->names[hw_unit]); 265 nvgpu_kfree(g, ecc_stat->names[hw_unit]);
256 } 266
257 nvgpu_kfree(g, ecc_stat->names); 267 nvgpu_kfree(g, ecc_stat->names);
258 nvgpu_kfree(g, dev_attr_array); 268 nvgpu_kfree(g, dev_attr_array);
259} 269}