lantiq: spi driver fix

adds a missing wait busy. based on the UGW patch 2060..

Signed-off-by: John Crispin <blogic@openwrt.org>

SVN-Revision: 47158
This commit is contained in:
John Crispin 2015-10-07 12:12:35 +00:00
parent 325a69486e
commit 33f9165a63

View file

@ -18,13 +18,13 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/spi/Kconfig --- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig
@@ -626,6 +626,14 @@ config SPI_NUC900 @@ -626,6 +626,14 @@
help help
SPI driver for Nuvoton NUC900 series ARM SoCs SPI driver for Nuvoton NUC900 series ARM SoCs
+config SPI_XWAY +config SPI_XWAY
+ tristate "Lantiq XWAY SPI controller" + tristate "Lantiq SPI controller"
+ depends on LANTIQ && SOC_TYPE_XWAY + depends on LANTIQ
+ select SPI_BITBANG + select SPI_BITBANG
+ help + help
+ This driver supports the Lantiq SoC SPI controller in master + This driver supports the Lantiq SoC SPI controller in master
@ -35,14 +35,14 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
# #
--- a/drivers/spi/Makefile --- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile +++ b/drivers/spi/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_SPI_TXX9) += spi-txx9.o @@ -90,3 +90,4 @@
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o
+obj-$(CONFIG_SPI_XWAY) += spi-xway.o +obj-$(CONFIG_SPI_XWAY) += spi-xway.o
--- /dev/null --- /dev/null
+++ b/drivers/spi/spi-xway.c +++ b/drivers/spi/spi-xway.c
@@ -0,0 +1,975 @@ @@ -0,0 +1,989 @@
+/* +/*
+ * Lantiq SoC SPI controller + * Lantiq SoC SPI controller
+ * + *
@ -184,8 +184,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ +
+#define LTQ_SPI_IRNEN_F BIT(3) /* Frame end interrupt request */ +#define LTQ_SPI_IRNEN_F BIT(3) /* Frame end interrupt request */
+#define LTQ_SPI_IRNEN_E BIT(2) /* Error end interrupt request */ +#define LTQ_SPI_IRNEN_E BIT(2) /* Error end interrupt request */
+#define LTQ_SPI_IRNEN_T BIT(1) /* Transmit end interrupt request */ +#define LTQ_SPI_IRNEN_T BIT(0) /* Transmit end interrupt request */
+#define LTQ_SPI_IRNEN_R BIT(0) /* Receive end interrupt request */ +#define LTQ_SPI_IRNEN_R BIT(1) /* Receive end interrupt request */
+#define LTQ_SPI_IRNEN_T_XWAY BIT(1) /* Transmit end interrupt request */
+#define LTQ_SPI_IRNEN_R_XWAY BIT(0) /* Receive end interrupt request */
+#define LTQ_SPI_IRNEN_ALL 0xF +#define LTQ_SPI_IRNEN_ALL 0xF
+ +
+struct ltq_spi { +struct ltq_spi {
@ -214,6 +216,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ u16 rxfs; + u16 rxfs;
+ unsigned dma_support:1; + unsigned dma_support:1;
+ unsigned cfg_mode:1; + unsigned cfg_mode:1;
+
+ u32 irnen_t;
+ u32 irnen_r;
+}; +};
+ +
+static inline struct ltq_spi *ltq_spi_to_hw(struct spi_device *spi) +static inline struct ltq_spi *ltq_spi_to_hw(struct spi_device *spi)
@ -517,6 +522,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+{ +{
+ struct ltq_spi *hw = ltq_spi_to_hw(spi); + struct ltq_spi *hw = ltq_spi_to_hw(spi);
+ +
+ if (ltq_spi_wait_ready(hw))
+ dev_err(&spi->dev, "wait failed\n");
+
+ switch (cs) { + switch (cs) {
+ case BITBANG_CS_ACTIVE: + case BITBANG_CS_ACTIVE:
+ ltq_spi_bits_per_word_set(spi); + ltq_spi_bits_per_word_set(spi);
@ -547,8 +555,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ if (bits_per_word > 32) + if (bits_per_word > 32)
+ return -EINVAL; + return -EINVAL;
+ +
+ ltq_spi_config_mode_set(hw);
+
+ return 0; + return 0;
+} +}
+ +
@ -780,17 +786,17 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ if (hw->tx) { + if (hw->tx) {
+ /* Initially fill TX FIFO with as much data as possible */ + /* Initially fill TX FIFO with as much data as possible */
+ ltq_spi_txfifo_write(hw); + ltq_spi_txfifo_write(hw);
+ irq_flags |= LTQ_SPI_IRNEN_T; + irq_flags |= hw->irnen_t;
+ +
+ /* Always enable RX interrupt in Full Duplex mode */ + /* Always enable RX interrupt in Full Duplex mode */
+ if (hw->rx) + if (hw->rx)
+ irq_flags |= LTQ_SPI_IRNEN_R; + irq_flags |= hw->irnen_r;
+ } else if (hw->rx) { + } else if (hw->rx) {
+ /* Start RX clock */ + /* Start RX clock */
+ ltq_spi_rxreq_set(hw); + ltq_spi_rxreq_set(hw);
+ +
+ /* Enable RX interrupt to receive data from RX FIFOs */ + /* Enable RX interrupt to receive data from RX FIFOs */
+ irq_flags |= LTQ_SPI_IRNEN_R; + irq_flags |= hw->irnen_r;
+ } + }
+ +
+ /* Enable TX or RX interrupts */ + /* Enable TX or RX interrupts */
@ -895,10 +901,18 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ hw->bitbang.setup_transfer = ltq_spi_setup_transfer; + hw->bitbang.setup_transfer = ltq_spi_setup_transfer;
+ hw->bitbang.txrx_bufs = ltq_spi_txrx_bufs; + hw->bitbang.txrx_bufs = ltq_spi_txrx_bufs;
+ +
+ if (of_machine_is_compatible("lantiq,ase")) + if (of_machine_is_compatible("lantiq,ase")) {
+ master->num_chipselect = 3; + master->num_chipselect = 3;
+ else +
+ hw->irnen_t = LTQ_SPI_IRNEN_T_XWAY;
+ hw->irnen_r = LTQ_SPI_IRNEN_R_XWAY;
+ } else {
+ master->num_chipselect = 6; + master->num_chipselect = 6;
+
+ hw->irnen_t = LTQ_SPI_IRNEN_T;
+ hw->irnen_r = LTQ_SPI_IRNEN_R;
+ }
+
+ master->bus_num = pdev->id; + master->bus_num = pdev->id;
+ master->setup = ltq_spi_setup; + master->setup = ltq_spi_setup;
+ master->cleanup = ltq_spi_cleanup; + master->cleanup = ltq_spi_cleanup;