|
@@ -1217,6 +1217,33 @@ out:
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int omap2_mcspi_prepare_message(struct spi_master *master,
|
|
|
|
+ struct spi_message *msg)
|
|
|
|
+{
|
|
|
|
+ struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
|
|
|
|
+ struct omap2_mcspi_regs *ctx = &mcspi->ctx;
|
|
|
|
+ struct omap2_mcspi_cs *cs;
|
|
|
|
+
|
|
|
|
+ /* Only a single channel can have the FORCE bit enabled
|
|
|
|
+ * in its chconf0 register.
|
|
|
|
+ * Scan all channels and disable them except the current one.
|
|
|
|
+ * A FORCE can remain from a last transfer having cs_change enabled
|
|
|
|
+ */
|
|
|
|
+ list_for_each_entry(cs, &ctx->cs, node) {
|
|
|
|
+ if (msg->spi->controller_state == cs)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE)) {
|
|
|
|
+ cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE;
|
|
|
|
+ writel_relaxed(cs->chconf0,
|
|
|
|
+ cs->base + OMAP2_MCSPI_CHCONF0);
|
|
|
|
+ readl_relaxed(cs->base + OMAP2_MCSPI_CHCONF0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int omap2_mcspi_transfer_one(struct spi_master *master,
|
|
static int omap2_mcspi_transfer_one(struct spi_master *master,
|
|
struct spi_device *spi, struct spi_transfer *t)
|
|
struct spi_device *spi, struct spi_transfer *t)
|
|
{
|
|
{
|
|
@@ -1344,6 +1371,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
|
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
|
|
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
|
|
master->setup = omap2_mcspi_setup;
|
|
master->setup = omap2_mcspi_setup;
|
|
master->auto_runtime_pm = true;
|
|
master->auto_runtime_pm = true;
|
|
|
|
+ master->prepare_message = omap2_mcspi_prepare_message;
|
|
master->transfer_one = omap2_mcspi_transfer_one;
|
|
master->transfer_one = omap2_mcspi_transfer_one;
|
|
master->set_cs = omap2_mcspi_set_cs;
|
|
master->set_cs = omap2_mcspi_set_cs;
|
|
master->cleanup = omap2_mcspi_cleanup;
|
|
master->cleanup = omap2_mcspi_cleanup;
|