ramips: improve rt2880 spi wait ready function
use loops_per_jiffy, spi clock speed and write bytes to get the spi loop count. if loop to 0 than spi operation timeout. remove usleep. we only write 1 byte to spi device. use busy loop would be better. Signed-off-by: Michael Lee <igvtee@gmail.com> SVN-Revision: 47575
This commit is contained in:
parent
702c480dfe
commit
bf89d139e1
1 changed files with 15 additions and 16 deletions
|
@ -41,7 +41,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
|
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/spi/spi-rt2880.c
|
+++ b/drivers/spi/spi-rt2880.c
|
||||||
@@ -0,0 +1,480 @@
|
@@ -0,0 +1,479 @@
|
||||||
+/*
|
+/*
|
||||||
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
|
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
|
||||||
+ *
|
+ *
|
||||||
|
@ -70,8 +70,6 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+#define DRIVER_NAME "spi-rt2880"
|
+#define DRIVER_NAME "spi-rt2880"
|
||||||
+/* only one slave is supported*/
|
+/* only one slave is supported*/
|
||||||
+#define RALINK_NUM_CHIPSELECTS 1
|
+#define RALINK_NUM_CHIPSELECTS 1
|
||||||
+/* in usec */
|
|
||||||
+#define RALINK_SPI_WAIT_MAX_LOOP 2000
|
|
||||||
+
|
+
|
||||||
+#define RAMIPS_SPI_STAT 0x00
|
+#define RAMIPS_SPI_STAT 0x00
|
||||||
+#define RAMIPS_SPI_CFG 0x10
|
+#define RAMIPS_SPI_CFG 0x10
|
||||||
|
@ -173,6 +171,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+ void __iomem *base;
|
+ void __iomem *base;
|
||||||
+ unsigned int sys_freq;
|
+ unsigned int sys_freq;
|
||||||
+ unsigned int speed;
|
+ unsigned int speed;
|
||||||
|
+ u16 wait_loops;
|
||||||
+ struct clk *clk;
|
+ struct clk *clk;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
@ -238,6 +237,11 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
||||||
+ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale);
|
+ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale);
|
||||||
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
||||||
|
+
|
||||||
|
+ /* some tolerance. double and add 100 */
|
||||||
|
+ rs->wait_loops = (8 * HZ * loops_per_jiffy) /
|
||||||
|
+ (clk_get_rate(rs->clk) / rate);
|
||||||
|
+ rs->wait_loops = (rs->wait_loops << 1) + 100;
|
||||||
+ rs->speed = speed;
|
+ rs->speed = speed;
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
|
@ -273,20 +277,15 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static inline int rt2880_spi_wait_till_ready(struct rt2880_spi *rs)
|
+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
|
||||||
+{
|
+{
|
||||||
+ int i;
|
+ int loop = rs->wait_loops * len;
|
||||||
+
|
|
||||||
+ for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) {
|
|
||||||
+ u32 status;
|
|
||||||
+
|
|
||||||
+ status = rt2880_spi_read(rs, RAMIPS_SPI_STAT);
|
|
||||||
+ if ((status & SPISTAT_BUSY) == 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
+
|
||||||
|
+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
|
||||||
+ cpu_relax();
|
+ cpu_relax();
|
||||||
+ udelay(1);
|
+
|
||||||
+ }
|
+ if (loop)
|
||||||
|
+ return 0;
|
||||||
+
|
+
|
||||||
+ return -ETIMEDOUT;
|
+ return -ETIMEDOUT;
|
||||||
+}
|
+}
|
||||||
|
@ -308,7 +307,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+ for (count = 0; count < xfer->len; count++) {
|
+ for (count = 0; count < xfer->len; count++) {
|
||||||
+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, tx[count]);
|
+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, tx[count]);
|
||||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
|
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
|
||||||
+ err = rt2880_spi_wait_till_ready(rs);
|
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
|
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
|
@ -319,7 +318,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
|
||||||
+ if (rx) {
|
+ if (rx) {
|
||||||
+ for (count = 0; count < xfer->len; count++) {
|
+ for (count = 0; count < xfer->len; count++) {
|
||||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
|
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
|
||||||
+ err = rt2880_spi_wait_till_ready(rs);
|
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
|
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
|
|
Loading…
Reference in a new issue