aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/powernv/opal.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 778a2793e75b..3697772e3759 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -102,13 +102,13 @@ int __init early_init_dt_scan_opal(unsigned long node,
102int __init early_init_dt_scan_recoverable_ranges(unsigned long node, 102int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
103 const char *uname, int depth, void *data) 103 const char *uname, int depth, void *data)
104{ 104{
105 unsigned long i, size; 105 unsigned long i, psize, size;
106 const __be32 *prop; 106 const __be32 *prop;
107 107
108 if (depth != 1 || strcmp(uname, "ibm,opal") != 0) 108 if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
109 return 0; 109 return 0;
110 110
111 prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &size); 111 prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize);
112 112
113 if (!prop) 113 if (!prop)
114 return 1; 114 return 1;
@@ -116,6 +116,23 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
116 pr_debug("Found machine check recoverable ranges.\n"); 116 pr_debug("Found machine check recoverable ranges.\n");
117 117
118 /* 118 /*
119 * Calculate number of available entries.
120 *
121 * Each recoverable address range entry is (start address, len,
122 * recovery address), 2 cells each for start and recovery address,
123 * 1 cell for len, totalling 5 cells per entry.
124 */
125 mc_recoverable_range_len = psize / (sizeof(*prop) * 5);
126
127 /* Sanity check */
128 if (!mc_recoverable_range_len)
129 return 1;
130
131 /* Size required to hold all the entries. */
132 size = mc_recoverable_range_len *
133 sizeof(struct mcheck_recoverable_range);
134
135 /*
119 * Allocate a buffer to hold the MC recoverable ranges. We would be 136 * Allocate a buffer to hold the MC recoverable ranges. We would be
120 * accessing them in real mode, hence it needs to be within 137 * accessing them in real mode, hence it needs to be within
121 * RMO region. 138 * RMO region.
@@ -124,11 +141,7 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
124 ppc64_rma_size)); 141 ppc64_rma_size));
125 memset(mc_recoverable_range, 0, size); 142 memset(mc_recoverable_range, 0, size);
126 143
127 /* 144 for (i = 0; i < mc_recoverable_range_len; i++) {
128 * Each recoverable address entry is an (start address,len,
129 * recover address) pair, * 2 cells each, totalling 4 cells per entry.
130 */
131 for (i = 0; i < size / (sizeof(*prop) * 5); i++) {
132 mc_recoverable_range[i].start_addr = 145 mc_recoverable_range[i].start_addr =
133 of_read_number(prop + (i * 5) + 0, 2); 146 of_read_number(prop + (i * 5) + 0, 2);
134 mc_recoverable_range[i].end_addr = 147 mc_recoverable_range[i].end_addr =
@@ -142,7 +155,6 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
142 mc_recoverable_range[i].end_addr, 155 mc_recoverable_range[i].end_addr,
143 mc_recoverable_range[i].recover_addr); 156 mc_recoverable_range[i].recover_addr);
144 } 157 }
145 mc_recoverable_range_len = i;
146 return 1; 158 return 1;
147} 159}
148 160