parisc: Add PDC locking functions for rendezvous code
authorHelge Deller <deller@gmx.de>
Tue, 29 Mar 2022 12:15:29 +0000 (14:15 +0200)
committerHelge Deller <deller@gmx.de>
Tue, 29 Mar 2022 19:37:12 +0000 (21:37 +0200)
Add pdc_cpu_rendezvous_lock() and pdc_cpu_rendezvous_unlock()
to lock PDC while CPU is transitioning into rendezvous state.
This is needed, because the transition phase may take up to 8 seconds.

Add pdc_pat_get_PDC_entrypoint() to get PDC entry point for current CPU.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/asm/pdc.h
arch/parisc/include/asm/pdcpat.h
arch/parisc/kernel/firmware.c

index 18b957a..b643092 100644 (file)
@@ -94,6 +94,9 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
                  unsigned long glob_cfg);
 
 int __pdc_cpu_rendezvous(void);
+void pdc_cpu_rendezvous_lock(void);
+void pdc_cpu_rendezvous_unlock(void);
+
 static inline char * os_id_to_string(u16 os_id) {
        switch(os_id) {
        case OS_ID_NONE:        return "No OS";
index 24355ed..8f16037 100644 (file)
@@ -83,6 +83,7 @@
 #define PDC_PAT_CPU_RENDEZVOUS         6L /* Rendezvous CPU */
 #define PDC_PAT_CPU_GET_CLOCK_INFO     7L /* Return CPU Clock info */
 #define PDC_PAT_CPU_GET_RENDEZVOUS_STATE 8L /* Return Rendezvous State */
+#define PDC_PAT_CPU_GET_PDC_ENTRYPOINT 11L /* Return PDC Entry point */
 #define PDC_PAT_CPU_PLUNGE_FABRIC      128L /* Plunge Fabric */
 #define PDC_PAT_CPU_UPDATE_CACHE_CLEANSING 129L /* Manipulate Cache 
                                                  * Cleansing Mode */
@@ -356,7 +357,7 @@ struct pdc_pat_cell_mod_maddr_block {       /* PDC_PAT_CELL_MODULE */
 
 typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;
 
-
+extern int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry);
 extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
 extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
 extern int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
index c6b11bd..6a7e315 100644 (file)
@@ -329,7 +329,44 @@ int __pdc_cpu_rendezvous(void)
                return mem_pdc_call(PDC_PROC, 1, 0);
 }
 
+/**
+ * pdc_cpu_rendezvous_lock - Lock PDC while transitioning to rendezvous state
+ */
+void pdc_cpu_rendezvous_lock(void)
+{
+       spin_lock(&pdc_lock);
+}
+
+/**
+ * pdc_cpu_rendezvous_unlock - Unlock PDC after reaching rendezvous state
+ */
+void pdc_cpu_rendezvous_unlock(void)
+{
+       spin_unlock(&pdc_lock);
+}
+
+/**
+ * pdc_pat_get_PDC_entrypoint - Get PDC entry point for current CPU
+ * @retval: -1 on error, 0 on success
+ */
+int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry)
+{
+       int retval = 0;
+       unsigned long flags;
+
+       if (!IS_ENABLED(CONFIG_SMP) || !is_pdc_pat()) {
+               *pdc_entry = MEM_PDC;
+               return 0;
+       }
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_PDC_ENTRYPOINT,
+                       __pa(pdc_result));
+       *pdc_entry = pdc_result[0];
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
+       return retval;
+}
 /**
  * pdc_chassis_warn - Fetches chassis warnings
  * @retval: -1 on error, 0 on success