From db2b0d76cdc4e781d32bf26d0c649ca2fe608c4e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 29 Mar 2022 14:15:29 +0200 Subject: parisc: Add PDC locking functions for rendezvous code 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 --- arch/parisc/include/asm/pdc.h | 3 +++ arch/parisc/include/asm/pdcpat.h | 3 ++- arch/parisc/kernel/firmware.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 18b957a8630d..b643092d4b98 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -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"; diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index 24355ed1453a..8f160375b865 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h @@ -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, diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index c6b11bdb8602..6a7e315bcc2e 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -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 -- cgit v1.2.3