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 | ||
