Ejemplo n.º 1
0
Archivo: main.c Proyecto: jeez/qmsi
int main(void)
{
	QM_PUTS("Starting: IRQ lock / unlock");

	int key = 0;

	/* Disable interrupts unconditionally. */
	qm_irq_disable();

	/*
	 * Lock interrupts and check if the Interrupt Flag bit from EFLAGS
	 * was cleared.
	 */
	key = qm_irq_lock();
	if (key & X86_FLAGS_IF) {
		QM_PUTS("Error: IF was set");
		return -EIO;
	}

	/* Try to unlock, lock again, but check that IF was still cleared. */
	qm_irq_unlock(key);
	key = 0;
	key = qm_irq_lock();
	if (key & X86_FLAGS_IF) {
		QM_PUTS("Error: IF was set");
		return -EIO;
	}

	/* Enable interrupts unconditionally. */
	qm_irq_enable();

	/* Lock them and check if IF was set. */
	key = qm_irq_lock();
	if (!(key & X86_FLAGS_IF)) {
		QM_PUTS("Error: IF was cleared");
		return -EIO;
	}

	/* Try to unlock, lock again, and check that IF is still set. */
	qm_irq_unlock(key);
	key = 0;
	key = qm_irq_lock();
	if (!(key & X86_FLAGS_IF)) {
		QM_PUTS("Error: IF was cleared");
		return -EIO;
	}

	QM_PUTS("Finished: IRQ lock / unlock");
	return 0;
}
Ejemplo n.º 2
0
void soc_sleep_requested(bool ready_to_sleep)
{
	unsigned int key;

	QM_PUTS("SoC sleep requested");

	if (!ready_to_sleep) {
		QM_PUTS("Sleep NAK'd");
		send_msg(SLEEP_NAK);
	} else {
		key = qm_irq_lock();
		send_msg(SLEEP_ACK);
		soc_sleep(CORE_SLEEP);
		qm_irq_unlock(key);
	}

	return;
}
Ejemplo n.º 3
0
void request_soc_sleep(void)
{
	unsigned int key;
	qm_mbox_ch_status_t stat;

	QM_PUTS("Request SoC sleep");

	key = qm_irq_lock();

	/* Send sleep request. */
	send_msg(SLEEP_REQ);

	/* Wait for the answer from other core. */
	do {
		if (qm_mbox_ch_get_status(mbox_rx, &stat) != 0) {
			QM_PUTS("Unable to get mailbox status");
		}
	} while (stat == QM_MBOX_CH_IDLE);

	qm_mbox_ch_read(mbox_rx, &rx_data);

	switch (rx_data.ctrl) {
	case SLEEP_NAK:
		QM_PUTS("MBox NAK");
		qm_irq_unlock(key);

		CORE_HALT();
		break;

	case SLEEP_REQ:
		QM_PUTS("MBox REQ");
/*
 * There is a race condition where both cores want to go to
 * sleep. The policy is to make the x86 perform the SoC sleep
 * transition. Sensor will go to core sleep.
 */
#if QM_SENSOR
		soc_sleep(CORE_SLEEP);
		qm_irq_unlock(key);
#else
		/* Wait for other core to be ready. */
		while (!other_core_sleep_flag()) {
		}
		soc_sleep(SOC_SLEEP);
		qm_irq_unlock(key);
#endif
		break;

	case SLEEP_ACK:
		QM_PUTS("MBox ACK");

		/* Wait for other core to be actually ready for sleep mode. */
		while (!other_core_sleep_flag()) {
		}

		soc_sleep(SOC_SLEEP);
		qm_irq_unlock(key);
		break;

	default:
		QM_PUTS("Wrong message received");
		break;
	}
}