/**
 * hsi_driver_cancel_write_interrupt - Cancel pending write interrupt.
 * @dev - hsi device channel where to cancel the pending interrupt.
 *
 * Return: -ECANCELED : write cancel success, data not transfered to TX FIFO
 *	   0 : transfer is already over, data already transfered to TX FIFO
 *
 * Note: whatever returned value, write callback will not be called after
 *       write cancel.
 */
int hsi_driver_cancel_write_interrupt(struct hsi_channel *ch)
{
	struct hsi_port *p = ch->hsi_port;
	unsigned int port = p->port_number;
	unsigned int channel = ch->channel_number;
	void __iomem *base = p->hsi_controller->base;
	u32 status_reg;
	long buff_offset;

	status_reg = hsi_inl(base,
			 HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));

	if (!(status_reg & HSI_HST_DATAACCEPT(channel))) {
		dev_dbg(&ch->dev->device, "Write cancel on not "
			"enabled channel %d ENABLE REG 0x%08X", channel,
			status_reg);
	}
	status_reg &= hsi_inl(base,
			HSI_SYS_MPU_STATUS_CH_REG(port, p->n_irq, channel));

	hsi_outl_and(~HSI_HST_DATAACCEPT(channel), base,
			HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));

	buff_offset = hsi_hst_bufstate_f_reg(p->hsi_controller, port, channel);
	if (buff_offset >= 0)
		hsi_outl_and(~HSI_BUFSTATE_CHANNEL(channel), base, buff_offset);
	hsi_reset_ch_write(ch);
	return status_reg & HSI_HST_DATAACCEPT(channel) ? 0 : -ECANCELED;
}
Esempio n. 2
0
static void do_channel_tx(struct hsi_channel *ch)
{
	struct hsi_dev *hsi_ctrl = ch->hsi_port->hsi_controller;
	void __iomem *base = hsi_ctrl->base;
	unsigned int n_ch;
	unsigned int n_p;
	unsigned int irq;
	long buff_offset;

	n_ch = ch->channel_number;
	n_p = ch->hsi_port->port_number;
	irq = ch->hsi_port->n_irq;

	spin_lock(&hsi_ctrl->lock);

	if (ch->write_data.addr == NULL) {
		hsi_outl_and(~HSI_HST_DATAACCEPT(n_ch), base,
				HSI_SYS_MPU_ENABLE_CH_REG(n_p, irq, n_ch));
		hsi_reset_ch_write(ch);
		spin_unlock(&hsi_ctrl->lock);
		(*ch->write_done)(ch->dev, 1);
	} else {
		buff_offset = hsi_hst_buffer_reg(hsi_ctrl, n_p, n_ch);
		if (buff_offset >= 0) {
			hsi_outl(*(ch->write_data.addr), base, buff_offset);
			ch->write_data.addr = NULL;
		}
		spin_unlock(&hsi_ctrl->lock);
	}
}
void hsi_driver_disable_read_interrupt(struct hsi_channel *ch)
{
	struct hsi_port *p = ch->hsi_port;
	unsigned int port = p->port_number;
	unsigned int channel = ch->channel_number;
	void __iomem *base = p->hsi_controller->base;

	hsi_outl_and(~HSI_HSR_DATAAVAILABLE(channel), base,
		     HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));
}
/* Enables the Data Available Interrupt of HSR for the given channel */
int hsi_driver_enable_read_interrupt(struct hsi_channel *ch, u32 * data)
{
	struct hsi_port *p = ch->hsi_port;
	unsigned int port = p->port_number;
	unsigned int channel = ch->channel_number;

	hsi_outl_or(HSI_HSR_DATAAVAILABLE(channel), p->hsi_controller->base,
		    HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));

	return 0;
}
/**
 * hsi_driver_cancel_read_interrupt - Cancel pending read interrupt.
 * @dev - hsi device channel where to cancel the pending interrupt.
 *
 * Return: -ECANCELED : read cancel success data not available at expected
 *			address.
 *	   0 : transfer is already over, data already available at expected
 *	       address.
 *
 * Note: whatever returned value, read callback will not be called after cancel.
 */
int hsi_driver_cancel_read_interrupt(struct hsi_channel *ch)
{
	struct hsi_port *p = ch->hsi_port;
	unsigned int port = p->port_number;
	unsigned int channel = ch->channel_number;
	void __iomem *base = p->hsi_controller->base;
	u32 status_reg;

	status_reg = hsi_inl(base,
			HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));
	if (!(status_reg & HSI_HSR_DATAAVAILABLE(channel))) {
		dev_dbg(&ch->dev->device, "Read cancel on not "
			"enabled channel %d ENABLE REG 0x%08X", channel,
			status_reg);
	}
	status_reg &= hsi_inl(base,
			HSI_SYS_MPU_STATUS_CH_REG(port, p->n_irq, channel));
	hsi_outl_and(~HSI_HSR_DATAAVAILABLE(channel), base,
			HSI_SYS_MPU_ENABLE_CH_REG(port, p->n_irq, channel));
	hsi_reset_ch_read(ch);
	return status_reg & HSI_HSR_DATAAVAILABLE(channel) ? 0 : -ECANCELED;
}
Esempio n. 6
0
static void do_channel_rx(struct hsi_channel *ch)
{
	struct hsi_dev *hsi_ctrl = ch->hsi_port->hsi_controller;
	void __iomem *base = ch->hsi_port->hsi_controller->base;
	unsigned int n_ch;
	unsigned int n_p;
	unsigned int irq;
	long buff_offset;
	int rx_poll = 0;
	int data_read = 0;

	n_ch = ch->channel_number;
	n_p = ch->hsi_port->port_number;
	irq = ch->hsi_port->n_irq;

	spin_lock(&hsi_ctrl->lock);

	if (ch->flags & HSI_CH_RX_POLL)
		rx_poll = 1;

	if (ch->read_data.addr) {
		buff_offset = hsi_hsr_buffer_reg(hsi_ctrl, n_p, n_ch);
		if (buff_offset >= 0) {
			data_read = 1;
			*(ch->read_data.addr) = hsi_inl(base, buff_offset);
		}
	}

	hsi_outl_and(~HSI_HSR_DATAAVAILABLE(n_ch), base,
				HSI_SYS_MPU_ENABLE_CH_REG(n_p, irq, n_ch));
	hsi_reset_ch_read(ch);

	spin_unlock(&hsi_ctrl->lock);

	if (rx_poll)
		hsi_port_event_handler(ch->hsi_port,
				HSI_EVENT_HSR_DATAAVAILABLE, (void *)n_ch);

	if (data_read)
		(*ch->read_done)(ch->dev, 1);
}