summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2017-08-04 19:12:39 +0200
committerHelge Deller <deller@gmx.de>2017-08-22 16:34:33 +0200
commit8a5aa00e6b9630d36d7681b38062a3d48d8b6ee6 (patch)
treed6500b96947876fc3aaedefc07b0c693bb5fb701 /arch/parisc/kernel
parent24587380f61d20e36662fbd4d938431e33e3eda2 (diff)
parisc: PDT/firmware: Add support to read PDT on older PAT-machines
Older machines with a PAT firmware (e.g. the rp5470) return their Page Deallocation Table (PDT) info per cell via the PDC_PAT_MEM_PD_INFO PDC call. This patch adds the necessary structures and wrappers to call firmware. Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/firmware.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index f622a311d04a..be9a2e89e90f 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -142,8 +142,8 @@ static void convert_to_wide(unsigned long *addr)
int i;
unsigned int *p = (unsigned int *)addr;
- if(unlikely(parisc_narrow_firmware)) {
- for(i = 31; i >= 0; --i)
+ if (unlikely(parisc_narrow_firmware)) {
+ for (i = (NUM_PDC_RESULT-1); i >= 0; --i)
addr[i] = p[i];
}
#endif
@@ -979,16 +979,22 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result),
- __pa(pdc_result2));
+ __pa(pdt_entries_ptr));
if (retval == PDC_OK) {
convert_to_wide(pdc_result);
memcpy(pret, pdc_result, sizeof(*pret));
- convert_to_wide(pdc_result2);
- memcpy(pdt_entries_ptr, pdc_result2,
- pret->pdt_entries * sizeof(*pdt_entries_ptr));
}
spin_unlock_irqrestore(&pdc_lock, flags);
+#ifdef CONFIG_64BIT
+ /*
+ * 64-bit kernels should not call this PDT function in narrow mode.
+ * The pdt_entries_ptr array above will now contain 32-bit values
+ */
+ if (WARN_ON_ONCE((retval == PDC_OK) && parisc_narrow_firmware))
+ return PDC_ERROR;
+#endif
+
return retval;
}
@@ -1440,6 +1446,29 @@ int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo)
}
/**
+ * pdc_pat_mem_pdt_cell_info - Retrieve information about page deallocation
+ * table of a cell
+ * @rinfo: memory pdt information
+ * @cell: cell number
+ *
+ */
+int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo,
+ unsigned long cell)
+{
+ int retval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_lock, flags);
+ retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_INFO,
+ __pa(&pdc_result), cell);
+ if (retval == PDC_OK)
+ memcpy(rinfo, &pdc_result, sizeof(*rinfo));
+ spin_unlock_irqrestore(&pdc_lock, flags);
+
+ return retval;
+}
+
+/**
* pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware
* @pret: array of PDT entries
* @pdt_entries_ptr: ptr to hold number of PDT entries
@@ -1455,14 +1484,14 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
spin_lock_irqsave(&pdc_lock, flags);
/* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */
retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ,
- __pa(&pdc_result), parisc_cell_num, __pa(&pdc_result2));
+ __pa(&pdc_result), parisc_cell_num,
+ __pa(pdt_entries_ptr));
if (retval == PDC_OK) {
/* build up return value as for PDC_PAT_MEM_PD_READ */
entries = min(pdc_result[0], max_entries);
pret->pdt_entries = entries;
pret->actual_count_bytes = entries * sizeof(unsigned long);
- memcpy(pdt_entries_ptr, &pdc_result2, pret->actual_count_bytes);
}
spin_unlock_irqrestore(&pdc_lock, flags);
@@ -1474,6 +1503,8 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
* pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware
* @pret: array of PDT entries
* @pdt_entries_ptr: ptr to hold number of PDT entries
+ * @count: number of bytes to read
+ * @offset: offset to start (in bytes)
*
*/
int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,