diff options
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 22 |
3 files changed, 30 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 81720ff59a10..ea8bba7b66bd 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -154,6 +154,7 @@ extern int opal_enter_rtas(struct rtas_args *args, | |||
154 | #define OPAL_LPC_READ 67 | 154 | #define OPAL_LPC_READ 67 |
155 | #define OPAL_LPC_WRITE 68 | 155 | #define OPAL_LPC_WRITE 68 |
156 | #define OPAL_RETURN_CPU 69 | 156 | #define OPAL_RETURN_CPU 69 |
157 | #define OPAL_REINIT_CPUS 70 | ||
157 | #define OPAL_ELOG_READ 71 | 158 | #define OPAL_ELOG_READ 71 |
158 | #define OPAL_ELOG_WRITE 72 | 159 | #define OPAL_ELOG_WRITE 72 |
159 | #define OPAL_ELOG_ACK 73 | 160 | #define OPAL_ELOG_ACK 73 |
@@ -725,6 +726,11 @@ struct OpalIoPhb3ErrorData { | |||
725 | uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; | 726 | uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; |
726 | }; | 727 | }; |
727 | 728 | ||
729 | enum { | ||
730 | OPAL_REINIT_CPUS_HILE_BE = (1 << 0), | ||
731 | OPAL_REINIT_CPUS_HILE_LE = (1 << 1), | ||
732 | }; | ||
733 | |||
728 | typedef struct oppanel_line { | 734 | typedef struct oppanel_line { |
729 | const char * line; | 735 | const char * line; |
730 | uint64_t line_len; | 736 | uint64_t line_len; |
@@ -849,6 +855,7 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, | |||
849 | uint16_t *pci_error_type, uint16_t *severity); | 855 | uint16_t *pci_error_type, uint16_t *severity); |
850 | int64_t opal_pci_poll(uint64_t phb_id); | 856 | int64_t opal_pci_poll(uint64_t phb_id); |
851 | int64_t opal_return_cpu(void); | 857 | int64_t opal_return_cpu(void); |
858 | int64_t opal_reinit_cpus(uint64_t flags); | ||
852 | 859 | ||
853 | int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); | 860 | int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); |
854 | int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); | 861 | int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index b5ebc545a373..4abbff22a61f 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -124,6 +124,7 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); | |||
124 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); | 124 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); |
125 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); | 125 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); |
126 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); | 126 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); |
127 | OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS); | ||
127 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); | 128 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); |
128 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); | 129 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); |
129 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); | 130 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 360ad80c754c..539243e9dc23 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -57,6 +57,21 @@ static DEFINE_SPINLOCK(opal_notifier_lock); | |||
57 | static uint64_t last_notified_mask = 0x0ul; | 57 | static uint64_t last_notified_mask = 0x0ul; |
58 | static atomic_t opal_notifier_hold = ATOMIC_INIT(0); | 58 | static atomic_t opal_notifier_hold = ATOMIC_INIT(0); |
59 | 59 | ||
60 | static void opal_reinit_cores(void) | ||
61 | { | ||
62 | /* Do the actual re-init, This will clobber all FPRs, VRs, etc... | ||
63 | * | ||
64 | * It will preserve non volatile GPRs and HSPRG0/1. It will | ||
65 | * also restore HIDs and other SPRs to their original value | ||
66 | * but it might clobber a bunch. | ||
67 | */ | ||
68 | #ifdef __BIG_ENDIAN__ | ||
69 | opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE); | ||
70 | #else | ||
71 | opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE); | ||
72 | #endif | ||
73 | } | ||
74 | |||
60 | int __init early_init_dt_scan_opal(unsigned long node, | 75 | int __init early_init_dt_scan_opal(unsigned long node, |
61 | const char *uname, int depth, void *data) | 76 | const char *uname, int depth, void *data) |
62 | { | 77 | { |
@@ -96,6 +111,13 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
96 | printk("OPAL V1 detected !\n"); | 111 | printk("OPAL V1 detected !\n"); |
97 | } | 112 | } |
98 | 113 | ||
114 | /* Reinit all cores with the right endian */ | ||
115 | opal_reinit_cores(); | ||
116 | |||
117 | /* Restore some bits */ | ||
118 | if (cur_cpu_spec->cpu_restore) | ||
119 | cur_cpu_spec->cpu_restore(); | ||
120 | |||
99 | return 1; | 121 | return 1; |
100 | } | 122 | } |
101 | 123 | ||