static int copy_scratchpad()

in slaves/w1_therm.c [1306:1358]


static int copy_scratchpad(struct w1_slave *sl)
{
	struct w1_master *dev_master = sl->master;
	int max_trying = W1_THERM_MAX_TRY;
	int t_write, ret = -ENODEV;
	bool strong_pullup;

	if (!sl->family_data)
		goto error;

	t_write = W1_THERM_EEPROM_WRITE_DELAY;
	strong_pullup = (w1_strong_pullup == 2 ||
					(!SLAVE_POWERMODE(sl) &&
					w1_strong_pullup));

	/* prevent the slave from going away in sleep */
	atomic_inc(THERM_REFCNT(sl->family_data));

	if (!bus_mutex_lock(&dev_master->bus_mutex)) {
		ret = -EAGAIN;	/* Didn't acquire the mutex */
		goto dec_refcnt;
	}

	while (max_trying-- && ret) { /* ret should be 0 */
		/* safe version to select slave */
		if (!reset_select_slave(sl)) {
			unsigned long sleep_rem;

			/* 10ms strong pullup (or delay) after the convert */
			if (strong_pullup)
				w1_next_pullup(dev_master, t_write);

			w1_write_8(dev_master, W1_COPY_SCRATCHPAD);

			if (strong_pullup) {
				sleep_rem = msleep_interruptible(t_write);
				if (sleep_rem != 0) {
					ret = -EINTR;
					goto mt_unlock;
				}
			}
			ret = 0;
		}

	}

mt_unlock:
	mutex_unlock(&dev_master->bus_mutex);
dec_refcnt:
	atomic_dec(THERM_REFCNT(sl->family_data));
error:
	return ret;
}