static int sdw_handle_dp0_interrupt()

in bus.c [1350:1420]


static int sdw_handle_dp0_interrupt(struct sdw_slave *slave, u8 *slave_status)
{
	u8 clear, impl_int_mask;
	int status, status2, ret, count = 0;

	status = sdw_read_no_pm(slave, SDW_DP0_INT);
	if (status < 0) {
		dev_err(&slave->dev,
			"SDW_DP0_INT read failed:%d\n", status);
		return status;
	}

	do {
		clear = status & ~SDW_DP0_INTERRUPTS;

		if (status & SDW_DP0_INT_TEST_FAIL) {
			dev_err(&slave->dev, "Test fail for port 0\n");
			clear |= SDW_DP0_INT_TEST_FAIL;
		}

		/*
		 * Assumption: PORT_READY interrupt will be received only for
		 * ports implementing Channel Prepare state machine (CP_SM)
		 */

		if (status & SDW_DP0_INT_PORT_READY) {
			complete(&slave->port_ready[0]);
			clear |= SDW_DP0_INT_PORT_READY;
		}

		if (status & SDW_DP0_INT_BRA_FAILURE) {
			dev_err(&slave->dev, "BRA failed\n");
			clear |= SDW_DP0_INT_BRA_FAILURE;
		}

		impl_int_mask = SDW_DP0_INT_IMPDEF1 |
			SDW_DP0_INT_IMPDEF2 | SDW_DP0_INT_IMPDEF3;

		if (status & impl_int_mask) {
			clear |= impl_int_mask;
			*slave_status = clear;
		}

		/* clear the interrupts but don't touch reserved and SDCA_CASCADE fields */
		ret = sdw_write_no_pm(slave, SDW_DP0_INT, clear);
		if (ret < 0) {
			dev_err(&slave->dev,
				"SDW_DP0_INT write failed:%d\n", ret);
			return ret;
		}

		/* Read DP0 interrupt again */
		status2 = sdw_read_no_pm(slave, SDW_DP0_INT);
		if (status2 < 0) {
			dev_err(&slave->dev,
				"SDW_DP0_INT read failed:%d\n", status2);
			return status2;
		}
		/* filter to limit loop to interrupts identified in the first status read */
		status &= status2;

		count++;

		/* we can get alerts while processing so keep retrying */
	} while ((status & SDW_DP0_INTERRUPTS) && (count < SDW_READ_INTR_CLEAR_RETRY));

	if (count == SDW_READ_INTR_CLEAR_RETRY)
		dev_warn(&slave->dev, "Reached MAX_RETRY on DP0 read\n");

	return ret;
}