int sdw_handle_slave_status()

in bus.c [1730:1839]


int sdw_handle_slave_status(struct sdw_bus *bus,
			    enum sdw_slave_status status[])
{
	enum sdw_slave_status prev_status;
	struct sdw_slave *slave;
	bool attached_initializing;
	int i, ret = 0;

	/* first check if any Slaves fell off the bus */
	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
		mutex_lock(&bus->bus_lock);
		if (test_bit(i, bus->assigned) == false) {
			mutex_unlock(&bus->bus_lock);
			continue;
		}
		mutex_unlock(&bus->bus_lock);

		slave = sdw_get_slave(bus, i);
		if (!slave)
			continue;

		if (status[i] == SDW_SLAVE_UNATTACHED &&
		    slave->status != SDW_SLAVE_UNATTACHED)
			sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
	}

	if (status[0] == SDW_SLAVE_ATTACHED) {
		dev_dbg(bus->dev, "Slave attached, programming device number\n");
		ret = sdw_program_device_num(bus);
		if (ret < 0)
			dev_err(bus->dev, "Slave attach failed: %d\n", ret);
		/*
		 * programming a device number will have side effects,
		 * so we deal with other devices at a later time
		 */
		return ret;
	}

	/* Continue to check other slave statuses */
	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
		mutex_lock(&bus->bus_lock);
		if (test_bit(i, bus->assigned) == false) {
			mutex_unlock(&bus->bus_lock);
			continue;
		}
		mutex_unlock(&bus->bus_lock);

		slave = sdw_get_slave(bus, i);
		if (!slave)
			continue;

		attached_initializing = false;

		switch (status[i]) {
		case SDW_SLAVE_UNATTACHED:
			if (slave->status == SDW_SLAVE_UNATTACHED)
				break;

			sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
			break;

		case SDW_SLAVE_ALERT:
			ret = sdw_handle_slave_alerts(slave);
			if (ret < 0)
				dev_err(&slave->dev,
					"Slave %d alert handling failed: %d\n",
					i, ret);
			break;

		case SDW_SLAVE_ATTACHED:
			if (slave->status == SDW_SLAVE_ATTACHED)
				break;

			prev_status = slave->status;
			sdw_modify_slave_status(slave, SDW_SLAVE_ATTACHED);

			if (prev_status == SDW_SLAVE_ALERT)
				break;

			attached_initializing = true;

			ret = sdw_initialize_slave(slave);
			if (ret < 0)
				dev_err(&slave->dev,
					"Slave %d initialization failed: %d\n",
					i, ret);

			break;

		default:
			dev_err(&slave->dev, "Invalid slave %d status:%d\n",
				i, status[i]);
			break;
		}

		ret = sdw_update_slave_status(slave, status[i]);
		if (ret < 0)
			dev_err(&slave->dev,
				"Update Slave status failed:%d\n", ret);
		if (attached_initializing) {
			dev_dbg(&slave->dev,
				"%s: signaling initialization completion for Slave %d\n",
				__func__, slave->dev_num);

			complete(&slave->initialization_complete);
		}
	}

	return ret;
}