diff options
author | Helge Deller <deller@gmx.de> | 2017-07-25 13:26:23 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2017-07-25 13:28:37 -0400 |
commit | 25a9b76597fafbbf688dd4473cb910568deb2b0c (patch) | |
tree | 0e7b0b216bf0ecdd115ec882bf62213f97cf9352 | |
parent | f520e55241e1cf0c10d308ccf47513f28533f60a (diff) |
parisc: Add function to return DIMM slot of physical address
Add a firmware wrapper function, which asks PDC firmware for the DIMM slot of a
physical address. This is needed to show users which DIMM module needs
replacement in case a broken DIMM was encountered.
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | arch/parisc/include/asm/pdcpat.h | 16 | ||||
-rw-r--r-- | arch/parisc/kernel/firmware.c | 25 |
2 files changed, 40 insertions, 1 deletions
diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index 32e105fb8adb..e3c0586260d8 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h | |||
@@ -150,7 +150,7 @@ | |||
150 | #define PDC_PAT_MEM_SETGM 9L /* Set Good Memory value */ | 150 | #define PDC_PAT_MEM_SETGM 9L /* Set Good Memory value */ |
151 | #define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */ | 151 | #define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */ |
152 | #define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From */ | 152 | #define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From */ |
153 | /* Memory Address */ | 153 | /* Memory Address */ |
154 | #define PDC_PAT_MEM_GET_TXT_SIZE 12L /* Get Formatted Text Size */ | 154 | #define PDC_PAT_MEM_GET_TXT_SIZE 12L /* Get Formatted Text Size */ |
155 | #define PDC_PAT_MEM_GET_PD_TXT 13L /* Get PD Formatted Text */ | 155 | #define PDC_PAT_MEM_GET_PD_TXT 13L /* Get PD Formatted Text */ |
156 | #define PDC_PAT_MEM_GET_CELL_TXT 14L /* Get Cell Formatted Text */ | 156 | #define PDC_PAT_MEM_GET_CELL_TXT 14L /* Get Cell Formatted Text */ |
@@ -228,6 +228,17 @@ struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */ | |||
228 | unsigned long pdt_entries; | 228 | unsigned long pdt_entries; |
229 | }; | 229 | }; |
230 | 230 | ||
231 | struct pdc_pat_mem_phys_mem_location { /* PDC_PAT_MEM/PDC_PAT_MEM_ADDRESS */ | ||
232 | u64 cabinet:8; | ||
233 | u64 ign1:8; | ||
234 | u64 ign2:8; | ||
235 | u64 cell_slot:8; | ||
236 | u64 ign3:8; | ||
237 | u64 dimm_slot:8; /* DIMM slot, e.g. 0x1A, 0x2B, show user hex value! */ | ||
238 | u64 ign4:8; | ||
239 | u64 source:4; /* for mem: always 0x07 */ | ||
240 | u64 source_detail:4; /* for mem: always 0x04 (SIMM or DIMM) */ | ||
241 | }; | ||
231 | 242 | ||
232 | struct pdc_pat_pd_addr_map_entry { | 243 | struct pdc_pat_pd_addr_map_entry { |
233 | unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */ | 244 | unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */ |
@@ -319,6 +330,9 @@ extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, | |||
319 | extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, | 330 | extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, |
320 | unsigned long *pdt_entries_ptr, unsigned long count, | 331 | unsigned long *pdt_entries_ptr, unsigned long count, |
321 | unsigned long offset); | 332 | unsigned long offset); |
333 | extern int pdc_pat_mem_get_dimm_phys_location( | ||
334 | struct pdc_pat_mem_phys_mem_location *pret, | ||
335 | unsigned long phys_addr); | ||
322 | 336 | ||
323 | #endif /* __ASSEMBLY__ */ | 337 | #endif /* __ASSEMBLY__ */ |
324 | 338 | ||
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 526ed90ca56f..f622a311d04a 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
@@ -1498,6 +1498,31 @@ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, | |||
1498 | 1498 | ||
1499 | return retval; | 1499 | return retval; |
1500 | } | 1500 | } |
1501 | |||
1502 | /** | ||
1503 | * pdc_pat_mem_get_dimm_phys_location - Get physical DIMM slot via PAT firmware | ||
1504 | * @pret: ptr to hold returned information | ||
1505 | * @phys_addr: physical address to examine | ||
1506 | * | ||
1507 | */ | ||
1508 | int pdc_pat_mem_get_dimm_phys_location( | ||
1509 | struct pdc_pat_mem_phys_mem_location *pret, | ||
1510 | unsigned long phys_addr) | ||
1511 | { | ||
1512 | int retval; | ||
1513 | unsigned long flags; | ||
1514 | |||
1515 | spin_lock_irqsave(&pdc_lock, flags); | ||
1516 | retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_ADDRESS, | ||
1517 | __pa(&pdc_result), phys_addr); | ||
1518 | |||
1519 | if (retval == PDC_OK) | ||
1520 | memcpy(pret, &pdc_result, sizeof(*pret)); | ||
1521 | |||
1522 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
1523 | |||
1524 | return retval; | ||
1525 | } | ||
1501 | #endif /* CONFIG_64BIT */ | 1526 | #endif /* CONFIG_64BIT */ |
1502 | 1527 | ||
1503 | 1528 | ||