diff options
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 28 |
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, | |||
102 | int __init early_init_dt_scan_recoverable_ranges(unsigned long node, | 102 | int __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 | ||