예제 #1
0
void spi_tty_write_worker(struct work_struct *work)
{
	int c;
	int crc;
	unsigned long flags;
	unsigned long start_t = 0;
	spi_msg_header header;
	struct spi_tty_s *spi_tty =
		container_of(work, struct spi_tty_s, write_work);

	start_t = jiffies;
	SPI_IPC_INFO("%s Enter\n", __func__);

	mutex_lock(&(spi_tty->work_lock));
	spin_lock_irqsave(&(spi_tty->port_lock), flags);

	while(
		((c = spi_tty_buf_data_avail(spi_tty->write_buf))
			|| (spi_tty->tx_null))
		&& (!spi_tty->throttle)
		&& (!spi_tty->spi_slave_dev->peer_is_dead))
	{
		if (spi_tty->tx_null)
			spi_tty->tx_null = 0;

		// initiate spi_big_trans
		memset(spi_big_trans.tx_buf, 0x0, SPI_TRANSACTION_LEN*2);
		spi_big_msg.actual_length = 0;

		c = MIN(c, SPI_MTU);
		spi_tty_buf_get(spi_tty->write_buf,
				spi_big_trans.tx_buf+SPI_MSG_HEADER_LEN,
				c);

		if (spi_tty->tty && spi_tty->open_count)
			tty_wakeup(spi_tty->tty);
		spin_unlock_irqrestore(&(spi_tty->port_lock), flags);

		header.type = 1;
		header.len = c;
		header.dtr = spi_tty->dtr;
		crc = spi_msg_cal_crc(&header);
		header.fcs = crc;
		spi_msg_set_header(spi_big_trans.tx_buf, &header);
		spi_big_trans.len = c + SPI_MSG_HEADER_LEN;
		spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN);
		spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c));
		spi_slave_sync(mdm6600_spi_dev.spi, &spi_big_msg);

		if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) {
			tx_count++;
			tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN;
			spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN);
		}else {
			pr_err("%s: spi_slave_sync() failed to transfer data!\n", __func__);
		}

		// wake up writes wait on queue
		wake_up_interruptible(&spi_tty->write_wait);

		spin_lock_irqsave(&(spi_tty->port_lock), flags);
	}

	spin_unlock_irqrestore(&(spi_tty->port_lock), flags);
	mutex_unlock(&(spi_tty->work_lock));
	SPI_IPC_INFO("%s Exit\n", __func__);
	tx_time += jiffies_to_msecs(jiffies - start_t);
}
예제 #2
0
static void spi_tty_write_worker(struct work_struct *work)
{
	int c;
	int crc;
	unsigned long flags;
	unsigned long start_t = 0;
	spi_msg_header header;
	struct spi_tty_s *spi_tty =
		container_of(work, struct spi_tty_s, write_work);

	start_t = jiffies;
	SPI_IPC_INFO("%s\n", __func__);

	mutex_lock(&(spi_tty->work_lock));
	spin_lock_irqsave(&(spi_tty->port_lock), flags);

	while(((c = spi_tty_buf_data_avail(spi_tty->write_buf))
		|| (spi_tty->tx_null))
		&& (!spi_tty->throttle)
		&& (!(spi_tty_dev && spi_tty_dev->peer_is_dead)))
	{
		SPI_IPC_INFO("%s: %d outgoing bytes\n", __func__, c);
		if (spi_tty->tx_null)
			spi_tty->tx_null = 0;

		// initiate spi_big_trans
		memset((char*)spi_big_trans.tx_buf, 0x0,
			SPI_TRANSACTION_LEN * 2);
		spi_big_msg.actual_length = 0;

		c = MIN(c, SPI_MTU);
		spi_tty_buf_get(spi_tty->write_buf,
			(char*)spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN,
			c);

		if (spi_tty->tty && spi_tty->open_count)
			tty_wakeup(spi_tty->tty);
		spin_unlock_irqrestore(&(spi_tty->port_lock), flags);

		header.type = 1;
		header.len = c;
		header.dtr = spi_tty->dtr;
		crc = spi_msg_cal_crc(&header);
		header.fcs = crc;
		spi_msg_set_header((u8*)spi_big_trans.tx_buf, &header);
#if SPI_TTY_FORCE_FULL_TRANSACTION
		spi_big_trans.len = SPI_TRANSACTION_LEN;
#else
		spi_big_trans.len = c + SPI_MSG_HEADER_LEN;
#endif
		spi_big_trans.speed_hz = SPI_SPEED_HZ;
		spi_big_trans.bits_per_word = 32;
		spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN);
		spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c));
		if (spi_tty_dev)
			spi_sync(spi_tty_dev->spi, &spi_big_msg);
		else
			pr_warning("%s: dropping data: no spi device "
				   "registered", __func__);

		if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) {
			tx_count++;
			tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN;
			spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN);
		}else {
			pr_err("%s: spi data transfer failed\n", __func__);
		}

		// wake up writes wait on queue
		wake_up_interruptible(&spi_tty->write_wait);

		spin_lock_irqsave(&(spi_tty->port_lock), flags);
	}

	spin_unlock_irqrestore(&(spi_tty->port_lock), flags);
	mutex_unlock(&(spi_tty->work_lock));
	SPI_IPC_INFO("%s: done\n", __func__);
	tx_time += jiffies_to_msecs(jiffies - start_t);
}