@@ -204,7 +204,7 @@
(SPR_TFMR_TBST_CORRUPT | SPR_TFMR_TB_MISSING_SYNC | \
SPR_TFMR_TB_MISSING_STEP | SPR_TFMR_FW_CONTROL_ERR | \
SPR_TFMR_TFMR_CORRUPT | SPR_TFMR_TB_RESIDUE_ERR | \
- SPR_TFMR_HDEC_PARITY_ERROR | SPR_TFMR_CHIP_TOD_INTERRUPT)
+ SPR_TFMR_HDEC_PARITY_ERROR)
/* TFMR "thread" errors */
#define SPR_TFMR_THREAD_ERRORS \
@@ -1066,6 +1066,20 @@ static int handle_tfac_errors(uint64_t hmer, struct OpalHMIEvent *hmi_evt,
recover2 = handle_all_core_tfac_error(tfmr, out_flags);
if (recover != 0)
recover = recover2;
+ } else if (tfmr & SPR_TFMR_CHIP_TOD_INTERRUPT) {
+ int recover2;
+
+ /*
+ * There are some TOD errors which do not affect working of
+ * TOD and TB. They stay in valid state. Hence we don't need
+ * rendez vous.
+ *
+ * TOD errors that affects TOD/TB will report a global error
+ * on TFMR alongwith bit 51, and they will go in rendez vous.
+ */
+ recover2 = chiptod_recover_tod_errors();
+ if (recover != 0)
+ recover = recover2;
} else if (this_cpu()->tb_invalid) {
/* This shouldn't happen, TB is invalid and no global error
* was reported. We just return for now assuming one will
@@ -970,7 +970,7 @@ bool chiptod_wakeup_resync(void)
return false;
}
-static int chiptod_recover_tod_errors(void)
+static int __chiptod_recover_tod_errors(void)
{
uint64_t terr;
uint64_t treset = 0;
@@ -1026,6 +1026,16 @@ static int chiptod_recover_tod_errors(void)
return 1;
}
+int chiptod_recover_tod_errors(void)
+{
+ int rc;
+
+ lock(&chiptod_lock);
+ rc = __chiptod_recover_tod_errors();
+ unlock(&chiptod_lock);
+ return rc;
+}
+
static int32_t chiptod_get_active_master(void)
{
if (current_topology < 0)
@@ -1550,7 +1560,7 @@ int chiptod_recover_tb_errors(bool *out_resynced)
* Bit 33 of TOD error register indicates sync check error.
*/
if (tfmr & SPR_TFMR_CHIP_TOD_INTERRUPT)
- rc = chiptod_recover_tod_errors();
+ rc = __chiptod_recover_tod_errors();
/* Check if TB is running. If not then we need to get it running. */
if (!(tfmr & SPR_TFMR_TB_VALID)) {
@@ -38,5 +38,6 @@ extern void chiptod_reset_tb(void);
extern bool chiptod_adjust_topology(enum chiptod_topology topo, bool enable);
extern bool chiptod_capp_timebase_sync(unsigned int chip_id, uint32_t tfmr_addr,
uint32_t tb_addr, uint32_t offset);
+extern int chiptod_recover_tod_errors(void);
#endif /* __CHIPTOD_H */