Merge "hikey960: Fix race condition between hotplug and idles" into integration
This commit is contained in:
commit
5c92aeab4f
|
@ -147,13 +147,19 @@ void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hisi_test_ap_suspend_flag(unsigned int cluster)
|
int hisi_test_ap_suspend_flag(void)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val1;
|
||||||
|
unsigned int val2;
|
||||||
|
|
||||||
val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
|
val1 = mmio_read_32(CPUIDLE_FLAG_REG(0));
|
||||||
val &= AP_SUSPEND_FLAG;
|
val1 &= AP_SUSPEND_FLAG;
|
||||||
return !!val;
|
|
||||||
|
val2 = mmio_read_32(CPUIDLE_FLAG_REG(1));
|
||||||
|
val2 &= AP_SUSPEND_FLAG;
|
||||||
|
|
||||||
|
val1 |= val2;
|
||||||
|
return (val1 != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hisi_set_cluster_pwdn_flag(unsigned int cluster,
|
void hisi_set_cluster_pwdn_flag(unsigned int cluster,
|
||||||
|
@ -164,7 +170,8 @@ void hisi_set_cluster_pwdn_flag(unsigned int cluster,
|
||||||
hisi_cpuhotplug_lock(cluster, core);
|
hisi_cpuhotplug_lock(cluster, core);
|
||||||
|
|
||||||
val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
||||||
val = (value << (cluster << 1)) | (val & 0xFFFFFFF);
|
val &= ~(0x3U << ((2 * cluster) + 28));
|
||||||
|
val |= (value << (2 * cluster));
|
||||||
mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
|
mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
|
||||||
|
|
||||||
hisi_cpuhotplug_unlock(cluster, core);
|
hisi_cpuhotplug_unlock(cluster, core);
|
||||||
|
@ -258,6 +265,17 @@ static unsigned int hisi_get_pdc_stat(unsigned int cluster)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_hotplug(unsigned int cluster, unsigned int boot_flag)
|
||||||
|
{
|
||||||
|
unsigned int mask = 0xF;
|
||||||
|
|
||||||
|
if (hisi_test_ap_suspend_flag() ||
|
||||||
|
((boot_flag & mask) == mask))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
|
int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
|
||||||
{
|
{
|
||||||
unsigned int mask = 0xf << (core * 4);
|
unsigned int mask = 0xf << (core * 4);
|
||||||
|
@ -268,7 +286,8 @@ int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
|
||||||
mask = (PDC_COREPWRSTAT_MASK & (~mask));
|
mask = (PDC_COREPWRSTAT_MASK & (~mask));
|
||||||
pdc_stat &= mask;
|
pdc_stat &= mask;
|
||||||
|
|
||||||
if ((boot_flag ^ cpuidle_flag) || pdc_stat)
|
if ((boot_flag ^ cpuidle_flag) || pdc_stat ||
|
||||||
|
check_hotplug(cluster, boot_flag))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -39,7 +39,7 @@ void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core);
|
||||||
int cluster_is_powered_on(unsigned int cluster);
|
int cluster_is_powered_on(unsigned int cluster);
|
||||||
void hisi_enter_core_idle(unsigned int cluster, unsigned int core);
|
void hisi_enter_core_idle(unsigned int cluster, unsigned int core);
|
||||||
void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core);
|
void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core);
|
||||||
int hisi_test_ap_suspend_flag(unsigned int cluster);
|
int hisi_test_ap_suspend_flag(void);
|
||||||
void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core);
|
void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ static void hikey960_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||||
/* check the SR flag bit to determine
|
/* check the SR flag bit to determine
|
||||||
* CLUSTER_IDLE_IPC or AP_SR_IPC to send
|
* CLUSTER_IDLE_IPC or AP_SR_IPC to send
|
||||||
*/
|
*/
|
||||||
if (hisi_test_ap_suspend_flag(cluster))
|
if (hisi_test_ap_suspend_flag())
|
||||||
hisi_enter_ap_suspend(cluster, core);
|
hisi_enter_ap_suspend(cluster, core);
|
||||||
else
|
else
|
||||||
hisi_enter_cluster_idle(cluster, core);
|
hisi_enter_cluster_idle(cluster, core);
|
||||||
|
@ -268,7 +268,7 @@ hikey960_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
|
||||||
hisi_clear_cpuidle_flag(cluster, core);
|
hisi_clear_cpuidle_flag(cluster, core);
|
||||||
hisi_cpuidle_unlock(cluster, core);
|
hisi_cpuidle_unlock(cluster, core);
|
||||||
|
|
||||||
if (hisi_test_ap_suspend_flag(cluster)) {
|
if (hisi_test_ap_suspend_flag()) {
|
||||||
hikey960_sr_dma_reinit();
|
hikey960_sr_dma_reinit();
|
||||||
gicv2_cpuif_enable();
|
gicv2_cpuif_enable();
|
||||||
console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ,
|
console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ,
|
||||||
|
|
Loading…
Reference in New Issue