aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2017-07-25 13:26:23 -0400
committerHelge Deller <deller@gmx.de>2017-07-25 13:28:37 -0400
commit25a9b76597fafbbf688dd4473cb910568deb2b0c (patch)
tree0e7b0b216bf0ecdd115ec882bf62213f97cf9352
parentf520e55241e1cf0c10d308ccf47513f28533f60a (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.h16
-rw-r--r--arch/parisc/kernel/firmware.c25
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
231struct 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
232struct pdc_pat_pd_addr_map_entry { 243struct 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,
319extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, 330extern 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);
333extern 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 */
1508int 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