mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-06 23:34:23 -05:00
Merge tag '20201013212531.428538-1-dianders@chromium.org' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into i2c/for-5.11
v5.10-rc1 + 20201013212531.428538-1-dianders@chromium.org
This commit is contained in:
@@ -366,6 +366,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
||||
geni_se_select_mode(se, GENI_SE_FIFO);
|
||||
|
||||
writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
|
||||
geni_se_setup_m_cmd(se, I2C_READ, m_param);
|
||||
|
||||
if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
|
||||
geni_se_select_mode(se, GENI_SE_FIFO);
|
||||
@@ -373,8 +374,6 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
||||
dma_buf = NULL;
|
||||
}
|
||||
|
||||
geni_se_setup_m_cmd(se, I2C_READ, m_param);
|
||||
|
||||
time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
|
||||
if (!time_left)
|
||||
geni_i2c_abort_xfer(gi2c);
|
||||
@@ -408,6 +407,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
||||
geni_se_select_mode(se, GENI_SE_FIFO);
|
||||
|
||||
writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
|
||||
geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
|
||||
|
||||
if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
|
||||
geni_se_select_mode(se, GENI_SE_FIFO);
|
||||
@@ -415,8 +415,6 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
||||
dma_buf = NULL;
|
||||
}
|
||||
|
||||
geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
|
||||
|
||||
if (!dma_buf) /* Get FIFO IRQ */
|
||||
writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);
|
||||
|
||||
|
||||
@@ -266,36 +266,63 @@ EXPORT_SYMBOL(geni_se_init);
|
||||
static void geni_se_select_fifo_mode(struct geni_se *se)
|
||||
{
|
||||
u32 proto = geni_se_read_proto(se);
|
||||
u32 val;
|
||||
u32 val, val_old;
|
||||
|
||||
geni_se_irq_clear(se);
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
|
||||
/*
|
||||
* The RX path for the UART is asynchronous and so needs more
|
||||
* complex logic for enabling / disabling its interrupts.
|
||||
*
|
||||
* Specific notes:
|
||||
* - The done and TX-related interrupts are managed manually.
|
||||
* - We don't RX from the main sequencer (we use the secondary) so
|
||||
* we don't need the RX-related interrupts enabled in the main
|
||||
* sequencer for UART.
|
||||
*/
|
||||
if (proto != GENI_SE_UART) {
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
|
||||
val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
|
||||
val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
|
||||
}
|
||||
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
|
||||
if (proto != GENI_SE_UART)
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
|
||||
val |= S_CMD_DONE_EN;
|
||||
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
|
||||
}
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
|
||||
val &= ~GENI_DMA_MODE_EN;
|
||||
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
|
||||
}
|
||||
|
||||
static void geni_se_select_dma_mode(struct geni_se *se)
|
||||
{
|
||||
u32 val;
|
||||
u32 proto = geni_se_read_proto(se);
|
||||
u32 val, val_old;
|
||||
|
||||
geni_se_irq_clear(se);
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
|
||||
if (proto != GENI_SE_UART) {
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
|
||||
val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
|
||||
val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
|
||||
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
|
||||
val &= ~S_CMD_DONE_EN;
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
|
||||
}
|
||||
|
||||
val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
|
||||
val |= GENI_DMA_MODE_EN;
|
||||
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
|
||||
if (val != val_old)
|
||||
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -651,7 +678,7 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
|
||||
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
|
||||
writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
|
||||
writel_relaxed(len, se->base + SE_DMA_TX_LEN);
|
||||
writel(len, se->base + SE_DMA_TX_LEN);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_tx_dma_prep);
|
||||
@@ -688,7 +715,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
|
||||
/* RX does not have EOT buffer type bit. So just reset RX_ATTR */
|
||||
writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
|
||||
writel_relaxed(len, se->base + SE_DMA_RX_LEN);
|
||||
writel(len, se->base + SE_DMA_RX_LEN);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_rx_dma_prep);
|
||||
|
||||
Reference in New Issue
Block a user