aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_device.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/edac_device.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/edac_device.c')
-rw-r--r--drivers/edac/edac_device.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index 211021dfec7..c3f67437afb 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -23,6 +23,7 @@
23#include <linux/jiffies.h> 23#include <linux/jiffies.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/list.h> 25#include <linux/list.h>
26#include <linux/sysdev.h>
26#include <linux/ctype.h> 27#include <linux/ctype.h>
27#include <linux/workqueue.h> 28#include <linux/workqueue.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
@@ -40,13 +41,12 @@ static LIST_HEAD(edac_device_list);
40#ifdef CONFIG_EDAC_DEBUG 41#ifdef CONFIG_EDAC_DEBUG
41static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev) 42static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
42{ 43{
43 edac_dbg(3, "\tedac_dev = %p dev_idx=%d\n", 44 debugf3("\tedac_dev = %p dev_idx=%d \n", edac_dev, edac_dev->dev_idx);
44 edac_dev, edac_dev->dev_idx); 45 debugf4("\tedac_dev->edac_check = %p\n", edac_dev->edac_check);
45 edac_dbg(4, "\tedac_dev->edac_check = %p\n", edac_dev->edac_check); 46 debugf3("\tdev = %p\n", edac_dev->dev);
46 edac_dbg(3, "\tdev = %p\n", edac_dev->dev); 47 debugf3("\tmod_name:ctl_name = %s:%s\n",
47 edac_dbg(3, "\tmod_name:ctl_name = %s:%s\n", 48 edac_dev->mod_name, edac_dev->ctl_name);
48 edac_dev->mod_name, edac_dev->ctl_name); 49 debugf3("\tpvt_info = %p\n\n", edac_dev->pvt_info);
49 edac_dbg(3, "\tpvt_info = %p\n\n", edac_dev->pvt_info);
50} 50}
51#endif /* CONFIG_EDAC_DEBUG */ 51#endif /* CONFIG_EDAC_DEBUG */
52 52
@@ -57,7 +57,7 @@ static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
57 * 57 *
58 * The control structure is allocated in complete chunk 58 * The control structure is allocated in complete chunk
59 * from the OS. It is in turn sub allocated to the 59 * from the OS. It is in turn sub allocated to the
60 * various objects that compose the structure 60 * various objects that compose the struture
61 * 61 *
62 * The structure has a 'nr_instance' array within itself. 62 * The structure has a 'nr_instance' array within itself.
63 * Each instance represents a major component 63 * Each instance represents a major component
@@ -80,10 +80,11 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
80 unsigned total_size; 80 unsigned total_size;
81 unsigned count; 81 unsigned count;
82 unsigned instance, block, attr; 82 unsigned instance, block, attr;
83 void *pvt, *p; 83 void *pvt;
84 int err; 84 int err;
85 85
86 edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks); 86 debugf4("%s() instances=%d blocks=%d\n",
87 __func__, nr_instances, nr_blocks);
87 88
88 /* Calculate the size of memory we need to allocate AND 89 /* Calculate the size of memory we need to allocate AND
89 * determine the offsets of the various item arrays 90 * determine the offsets of the various item arrays
@@ -92,30 +93,35 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
92 * to be at least as stringent as what the compiler would 93 * to be at least as stringent as what the compiler would
93 * provide if we could simply hardcode everything into a single struct. 94 * provide if we could simply hardcode everything into a single struct.
94 */ 95 */
95 p = NULL; 96 dev_ctl = (struct edac_device_ctl_info *)NULL;
96 dev_ctl = edac_align_ptr(&p, sizeof(*dev_ctl), 1);
97 97
98 /* Calc the 'end' offset past end of ONE ctl_info structure 98 /* Calc the 'end' offset past end of ONE ctl_info structure
99 * which will become the start of the 'instance' array 99 * which will become the start of the 'instance' array
100 */ 100 */
101 dev_inst = edac_align_ptr(&p, sizeof(*dev_inst), nr_instances); 101 dev_inst = edac_align_ptr(&dev_ctl[1], sizeof(*dev_inst));
102 102
103 /* Calc the 'end' offset past the instance array within the ctl_info 103 /* Calc the 'end' offset past the instance array within the ctl_info
104 * which will become the start of the block array 104 * which will become the start of the block array
105 */ 105 */
106 count = nr_instances * nr_blocks; 106 dev_blk = edac_align_ptr(&dev_inst[nr_instances], sizeof(*dev_blk));
107 dev_blk = edac_align_ptr(&p, sizeof(*dev_blk), count);
108 107
109 /* Calc the 'end' offset past the dev_blk array 108 /* Calc the 'end' offset past the dev_blk array
110 * which will become the start of the attrib array, if any. 109 * which will become the start of the attrib array, if any.
111 */ 110 */
112 /* calc how many nr_attrib we need */ 111 count = nr_instances * nr_blocks;
113 if (nr_attrib > 0) 112 dev_attrib = edac_align_ptr(&dev_blk[count], sizeof(*dev_attrib));
113
114 /* Check for case of when an attribute array is specified */
115 if (nr_attrib > 0) {
116 /* calc how many nr_attrib we need */
114 count *= nr_attrib; 117 count *= nr_attrib;
115 dev_attrib = edac_align_ptr(&p, sizeof(*dev_attrib), count);
116 118
117 /* Calc the 'end' offset past the attributes array */ 119 /* Calc the 'end' offset past the attributes array */
118 pvt = edac_align_ptr(&p, sz_private, 1); 120 pvt = edac_align_ptr(&dev_attrib[count], sz_private);
121 } else {
122 /* no attribute array specificed */
123 pvt = edac_align_ptr(dev_attrib, sz_private);
124 }
119 125
120 /* 'pvt' now points to where the private data area is. 126 /* 'pvt' now points to where the private data area is.
121 * At this point 'pvt' (like dev_inst,dev_blk and dev_attrib) 127 * At this point 'pvt' (like dev_inst,dev_blk and dev_attrib)
@@ -156,8 +162,8 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
156 /* Name of this edac device */ 162 /* Name of this edac device */
157 snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name); 163 snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name);
158 164
159 edac_dbg(4, "edac_dev=%p next after end=%p\n", 165 debugf4("%s() edac_dev=%p next after end=%p\n",
160 dev_ctl, pvt + sz_private); 166 __func__, dev_ctl, pvt + sz_private );
161 167
162 /* Initialize every Instance */ 168 /* Initialize every Instance */
163 for (instance = 0; instance < nr_instances; instance++) { 169 for (instance = 0; instance < nr_instances; instance++) {
@@ -178,8 +184,10 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
178 snprintf(blk->name, sizeof(blk->name), 184 snprintf(blk->name, sizeof(blk->name),
179 "%s%d", edac_block_name, block+offset_value); 185 "%s%d", edac_block_name, block+offset_value);
180 186
181 edac_dbg(4, "instance=%d inst_p=%p block=#%d block_p=%p name='%s'\n", 187 debugf4("%s() instance=%d inst_p=%p block=#%d "
182 instance, inst, block, blk, blk->name); 188 "block_p=%p name='%s'\n",
189 __func__, instance, inst, block,
190 blk, blk->name);
183 191
184 /* if there are NO attributes OR no attribute pointer 192 /* if there are NO attributes OR no attribute pointer
185 * then continue on to next block iteration 193 * then continue on to next block iteration
@@ -192,8 +200,8 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
192 attrib_p = &dev_attrib[block*nr_instances*nr_attrib]; 200 attrib_p = &dev_attrib[block*nr_instances*nr_attrib];
193 blk->block_attributes = attrib_p; 201 blk->block_attributes = attrib_p;
194 202
195 edac_dbg(4, "THIS BLOCK_ATTRIB=%p\n", 203 debugf4("%s() THIS BLOCK_ATTRIB=%p\n",
196 blk->block_attributes); 204 __func__, blk->block_attributes);
197 205
198 /* Initialize every user specified attribute in this 206 /* Initialize every user specified attribute in this
199 * block with the data the caller passed in 207 * block with the data the caller passed in
@@ -212,10 +220,11 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
212 220
213 attrib->block = blk; /* up link */ 221 attrib->block = blk; /* up link */
214 222
215 edac_dbg(4, "alloc-attrib=%p attrib_name='%s' attrib-spec=%p spec-name=%s\n", 223 debugf4("%s() alloc-attrib=%p attrib_name='%s' "
216 attrib, attrib->attr.name, 224 "attrib-spec=%p spec-name=%s\n",
217 &attrib_spec[attr], 225 __func__, attrib, attrib->attr.name,
218 attrib_spec[attr].attr.name 226 &attrib_spec[attr],
227 attrib_spec[attr].attr.name
219 ); 228 );
220 } 229 }
221 } 230 }
@@ -270,7 +279,7 @@ static struct edac_device_ctl_info *find_edac_device_by_dev(struct device *dev)
270 struct edac_device_ctl_info *edac_dev; 279 struct edac_device_ctl_info *edac_dev;
271 struct list_head *item; 280 struct list_head *item;
272 281
273 edac_dbg(0, "\n"); 282 debugf0("%s()\n", __func__);
274 283
275 list_for_each(item, &edac_device_list) { 284 list_for_each(item, &edac_device_list) {
276 edac_dev = list_entry(item, struct edac_device_ctl_info, link); 285 edac_dev = list_entry(item, struct edac_device_ctl_info, link);
@@ -386,7 +395,7 @@ static void edac_device_workq_function(struct work_struct *work_req)
386 395
387 /* Reschedule the workq for the next time period to start again 396 /* Reschedule the workq for the next time period to start again
388 * if the number of msec is for 1 sec, then adjust to the next 397 * if the number of msec is for 1 sec, then adjust to the next
389 * whole one second to save timers firing all over the period 398 * whole one second to save timers fireing all over the period
390 * between integral seconds 399 * between integral seconds
391 */ 400 */
392 if (edac_dev->poll_msec == 1000) 401 if (edac_dev->poll_msec == 1000)
@@ -405,7 +414,7 @@ static void edac_device_workq_function(struct work_struct *work_req)
405void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev, 414void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
406 unsigned msec) 415 unsigned msec)
407{ 416{
408 edac_dbg(0, "\n"); 417 debugf0("%s()\n", __func__);
409 418
410 /* take the arg 'msec' and set it into the control structure 419 /* take the arg 'msec' and set it into the control structure
411 * to used in the time period calculation 420 * to used in the time period calculation
@@ -493,7 +502,7 @@ EXPORT_SYMBOL_GPL(edac_device_alloc_index);
493 */ 502 */
494int edac_device_add_device(struct edac_device_ctl_info *edac_dev) 503int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
495{ 504{
496 edac_dbg(0, "\n"); 505 debugf0("%s()\n", __func__);
497 506
498#ifdef CONFIG_EDAC_DEBUG 507#ifdef CONFIG_EDAC_DEBUG
499 if (edac_debug_level >= 3) 508 if (edac_debug_level >= 3)
@@ -555,7 +564,7 @@ EXPORT_SYMBOL_GPL(edac_device_add_device);
555 * Remove sysfs entries for specified edac_device structure and 564 * Remove sysfs entries for specified edac_device structure and
556 * then remove edac_device structure from global list 565 * then remove edac_device structure from global list
557 * 566 *
558 * @dev: 567 * @pdev:
559 * Pointer to 'struct device' representing edac_device 568 * Pointer to 'struct device' representing edac_device
560 * structure to remove. 569 * structure to remove.
561 * 570 *
@@ -567,7 +576,7 @@ struct edac_device_ctl_info *edac_device_del_device(struct device *dev)
567{ 576{
568 struct edac_device_ctl_info *edac_dev; 577 struct edac_device_ctl_info *edac_dev;
569 578
570 edac_dbg(0, "\n"); 579 debugf0("%s()\n", __func__);
571 580
572 mutex_lock(&device_ctls_mutex); 581 mutex_lock(&device_ctls_mutex);
573 582