[OpenWrt-Devel] [PATCH 10/32] atheros: ar2315-spiflash: use mutex inplace of spinlock
Sergey Ryazanov
ryazanov.s.a at gmail.com
Thu Sep 11 22:00:27 EDT 2014
Use mutex inplace of spinlock to make code simple, also call
mutex_{lock,unlock} explicitly to avoid sparse warning about context
imbalance.
Signed-off-by: Sergey Ryazanov <ryazanov.s.a at gmail.com>
---
.../linux/atheros/patches-3.14/120-spiflash.patch | 74 ++++------------------
1 file changed, 14 insertions(+), 60 deletions(-)
diff --git a/target/linux/atheros/patches-3.14/120-spiflash.patch b/target/linux/atheros/patches-3.14/120-spiflash.patch
index 33f009b..8dbab10 100644
--- a/target/linux/atheros/patches-3.14/120-spiflash.patch
+++ b/target/linux/atheros/patches-3.14/120-spiflash.patch
@@ -23,7 +23,7 @@
--- /dev/null
+++ b/drivers/mtd/devices/ar2315.c
-@@ -0,0 +1,507 @@
+@@ -0,0 +1,461 @@
+
+/*
+ * MTD driver for the SPI Flash Memory support on Atheros AR2315
@@ -53,6 +53,7 @@
+#include <linux/root_dev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
++#include <linux/mutex.h>
+
+#include "ar2315_spiflash.h"
+
@@ -60,14 +61,12 @@
+
+#define busy_wait(_priv, _condition, _wait) do { \
+ while (_condition) { \
-+ spin_unlock_bh(&_priv->lock); \
+ if (_wait > 1) \
+ msleep(_wait); \
+ else if ((_wait == 1) && need_resched()) \
+ schedule(); \
+ else \
+ udelay(1); \
-+ spin_lock_bh(&_priv->lock); \
+ } \
+} while (0)
+
@@ -141,9 +140,7 @@
+ struct mtd_info mtd;
+ void __iomem *readaddr; /* memory mapped data for read */
+ void __iomem *mmraddr; /* memory mapped register space */
-+ wait_queue_head_t wq;
-+ spinlock_t lock;
-+ int state;
++ struct mutex lock; /* serialize registers access */
+};
+
+#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)
@@ -220,7 +217,6 @@
+ return reg;
+}
+
-+
+/*
+ * Probe SPI flash device
+ * Function returns 0 for failure.
@@ -229,14 +225,9 @@
+static int
+spiflash_probe_chip(struct platform_device *pdev, struct spiflash_priv *priv)
+{
-+ u32 sig;
++ u32 sig = spiflash_sendcmd(priv, SPI_RD_SIG, 0);
+ int flash_size;
+
-+ /* Read the signature on the flash device */
-+ spin_lock_bh(&priv->lock);
-+ sig = spiflash_sendcmd(priv, SPI_RD_SIG, 0);
-+ spin_unlock_bh(&priv->lock);
-+
+ switch (sig) {
+ case STM_8MBIT_SIGNATURE:
+ flash_size = FLASH_1MB;
@@ -261,48 +252,13 @@
+ return flash_size;
+}
+
-+
-+/* wait until the flash chip is ready and grab a lock */
-+static int spiflash_wait_ready(struct spiflash_priv *priv, int state)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+retry:
-+ spin_lock_bh(&priv->lock);
-+ if (priv->state != FL_READY) {
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&priv->wq, &wait);
-+ spin_unlock_bh(&priv->lock);
-+ schedule();
-+ remove_wait_queue(&priv->wq, &wait);
-+
-+ if (signal_pending(current))
-+ return 0;
-+
-+ goto retry;
-+ }
-+ priv->state = state;
-+
-+ return 1;
-+}
-+
-+static inline void spiflash_done(struct spiflash_priv *priv)
-+{
-+ priv->state = FL_READY;
-+ spin_unlock_bh(&priv->lock);
-+ wake_up(&priv->wq);
-+}
-+
+static void
+spiflash_wait_complete(struct spiflash_priv *priv, unsigned int timeout)
+{
+ busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &
+ SPI_STATUS_WIP, timeout);
-+ spiflash_done(priv);
+}
+
-+
-+
+static int
+spiflash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
@@ -313,8 +269,7 @@
+ if (instr->addr + instr->len > mtd->size)
+ return -EINVAL;
+
-+ if (!spiflash_wait_ready(priv, FL_ERASING))
-+ return -EINTR;
++ mutex_lock(&priv->lock);
+
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
+ reg = spiflash_wait_busy(priv);
@@ -329,6 +284,8 @@
+
+ spiflash_wait_complete(priv, 20);
+
++ mutex_unlock(&priv->lock);
++
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
@@ -349,11 +306,11 @@
+
+ *retlen = len;
+
-+ if (!spiflash_wait_ready(priv, FL_READING))
-+ return -EINTR;
++ mutex_lock(&priv->lock);
+
+ memcpy_fromio(buf, priv->readaddr + from, len);
-+ spiflash_done(priv);
++
++ mutex_unlock(&priv->lock);
+
+ return 0;
+}
@@ -391,8 +348,7 @@
+ if (page_offset > STM_PAGE_SIZE)
+ read_len -= (page_offset - STM_PAGE_SIZE);
+
-+ if (!spiflash_wait_ready(priv, FL_WRITING))
-+ return -EINTR;
++ mutex_lock(&priv->lock);
+
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
+ spi_data = 0;
@@ -425,6 +381,8 @@
+
+ spiflash_wait_complete(priv, 1);
+
++ mutex_unlock(&priv->lock);
++
+ bytes_left -= read_len;
+ to += read_len;
+ buf += read_len;
@@ -435,14 +393,12 @@
+ return 0;
+}
+
-+
+#if defined CONFIG_MTD_REDBOOT_PARTS || CONFIG_MTD_MYLOADER_PARTS
+static const char * const part_probe_types[] = {
+ "cmdlinepart", "RedBoot", "MyLoader", NULL
+};
+#endif
+
-+
+static int
+spiflash_probe(struct platform_device *pdev)
+{
@@ -456,9 +412,7 @@
+ if (!priv)
+ return -ENOMEM;
+
-+ spin_lock_init(&priv->lock);
-+ init_waitqueue_head(&priv->wq);
-+ priv->state = FL_READY;
++ mutex_init(&priv->lock);
+ mtd = &priv->mtd;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
--
1.8.1.5
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list