atheros: ar2315-spiflash: use mutex inplace of spinlock
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@gmail.com> SVN-Revision: 42491
This commit is contained in:
parent
ffa6091eef
commit
a28fd0dfd0
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/mtd/devices/ar2315.c
|
+++ 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
|
+ * MTD driver for the SPI Flash Memory support on Atheros AR2315
|
||||||
|
@ -53,6 +53,7 @@
|
||||||
+#include <linux/root_dev.h>
|
+#include <linux/root_dev.h>
|
||||||
+#include <linux/delay.h>
|
+#include <linux/delay.h>
|
||||||
+#include <linux/io.h>
|
+#include <linux/io.h>
|
||||||
|
+#include <linux/mutex.h>
|
||||||
+
|
+
|
||||||
+#include "ar2315_spiflash.h"
|
+#include "ar2315_spiflash.h"
|
||||||
+
|
+
|
||||||
|
@ -60,14 +61,12 @@
|
||||||
+
|
+
|
||||||
+#define busy_wait(_priv, _condition, _wait) do { \
|
+#define busy_wait(_priv, _condition, _wait) do { \
|
||||||
+ while (_condition) { \
|
+ while (_condition) { \
|
||||||
+ spin_unlock_bh(&_priv->lock); \
|
|
||||||
+ if (_wait > 1) \
|
+ if (_wait > 1) \
|
||||||
+ msleep(_wait); \
|
+ msleep(_wait); \
|
||||||
+ else if ((_wait == 1) && need_resched()) \
|
+ else if ((_wait == 1) && need_resched()) \
|
||||||
+ schedule(); \
|
+ schedule(); \
|
||||||
+ else \
|
+ else \
|
||||||
+ udelay(1); \
|
+ udelay(1); \
|
||||||
+ spin_lock_bh(&_priv->lock); \
|
|
||||||
+ } \
|
+ } \
|
||||||
+} while (0)
|
+} while (0)
|
||||||
+
|
+
|
||||||
|
@ -141,9 +140,7 @@
|
||||||
+ struct mtd_info mtd;
|
+ struct mtd_info mtd;
|
||||||
+ void __iomem *readaddr; /* memory mapped data for read */
|
+ void __iomem *readaddr; /* memory mapped data for read */
|
||||||
+ void __iomem *mmraddr; /* memory mapped register space */
|
+ void __iomem *mmraddr; /* memory mapped register space */
|
||||||
+ wait_queue_head_t wq;
|
+ struct mutex lock; /* serialize registers access */
|
||||||
+ spinlock_t lock;
|
|
||||||
+ int state;
|
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)
|
+#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)
|
||||||
|
@ -220,7 +217,6 @@
|
||||||
+ return reg;
|
+ return reg;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+/*
|
+/*
|
||||||
+ * Probe SPI flash device
|
+ * Probe SPI flash device
|
||||||
+ * Function returns 0 for failure.
|
+ * Function returns 0 for failure.
|
||||||
|
@ -229,14 +225,9 @@
|
||||||
+static int
|
+static int
|
||||||
+spiflash_probe_chip(struct platform_device *pdev, struct spiflash_priv *priv)
|
+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;
|
+ 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) {
|
+ switch (sig) {
|
||||||
+ case STM_8MBIT_SIGNATURE:
|
+ case STM_8MBIT_SIGNATURE:
|
||||||
+ flash_size = FLASH_1MB;
|
+ flash_size = FLASH_1MB;
|
||||||
|
@ -261,48 +252,13 @@
|
||||||
+ return flash_size;
|
+ 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
|
+static void
|
||||||
+spiflash_wait_complete(struct spiflash_priv *priv, unsigned int timeout)
|
+spiflash_wait_complete(struct spiflash_priv *priv, unsigned int timeout)
|
||||||
+{
|
+{
|
||||||
+ busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &
|
+ busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &
|
||||||
+ SPI_STATUS_WIP, timeout);
|
+ SPI_STATUS_WIP, timeout);
|
||||||
+ spiflash_done(priv);
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+
|
|
||||||
+static int
|
+static int
|
||||||
+spiflash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
+spiflash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||||
+{
|
+{
|
||||||
|
@ -313,8 +269,7 @@
|
||||||
+ if (instr->addr + instr->len > mtd->size)
|
+ if (instr->addr + instr->len > mtd->size)
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+
|
+
|
||||||
+ if (!spiflash_wait_ready(priv, FL_ERASING))
|
+ mutex_lock(&priv->lock);
|
||||||
+ return -EINTR;
|
|
||||||
+
|
+
|
||||||
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
|
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
|
||||||
+ reg = spiflash_wait_busy(priv);
|
+ reg = spiflash_wait_busy(priv);
|
||||||
|
@ -329,6 +284,8 @@
|
||||||
+
|
+
|
||||||
+ spiflash_wait_complete(priv, 20);
|
+ spiflash_wait_complete(priv, 20);
|
||||||
+
|
+
|
||||||
|
+ mutex_unlock(&priv->lock);
|
||||||
|
+
|
||||||
+ instr->state = MTD_ERASE_DONE;
|
+ instr->state = MTD_ERASE_DONE;
|
||||||
+ mtd_erase_callback(instr);
|
+ mtd_erase_callback(instr);
|
||||||
+
|
+
|
||||||
|
@ -349,11 +306,11 @@
|
||||||
+
|
+
|
||||||
+ *retlen = len;
|
+ *retlen = len;
|
||||||
+
|
+
|
||||||
+ if (!spiflash_wait_ready(priv, FL_READING))
|
+ mutex_lock(&priv->lock);
|
||||||
+ return -EINTR;
|
|
||||||
+
|
+
|
||||||
+ memcpy_fromio(buf, priv->readaddr + from, len);
|
+ memcpy_fromio(buf, priv->readaddr + from, len);
|
||||||
+ spiflash_done(priv);
|
+
|
||||||
|
+ mutex_unlock(&priv->lock);
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
|
@ -391,8 +348,7 @@
|
||||||
+ if (page_offset > STM_PAGE_SIZE)
|
+ if (page_offset > STM_PAGE_SIZE)
|
||||||
+ read_len -= (page_offset - STM_PAGE_SIZE);
|
+ read_len -= (page_offset - STM_PAGE_SIZE);
|
||||||
+
|
+
|
||||||
+ if (!spiflash_wait_ready(priv, FL_WRITING))
|
+ mutex_lock(&priv->lock);
|
||||||
+ return -EINTR;
|
|
||||||
+
|
+
|
||||||
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
|
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
|
||||||
+ spi_data = 0;
|
+ spi_data = 0;
|
||||||
|
@ -425,6 +381,8 @@
|
||||||
+
|
+
|
||||||
+ spiflash_wait_complete(priv, 1);
|
+ spiflash_wait_complete(priv, 1);
|
||||||
+
|
+
|
||||||
|
+ mutex_unlock(&priv->lock);
|
||||||
|
+
|
||||||
+ bytes_left -= read_len;
|
+ bytes_left -= read_len;
|
||||||
+ to += read_len;
|
+ to += read_len;
|
||||||
+ buf += read_len;
|
+ buf += read_len;
|
||||||
|
@ -435,14 +393,12 @@
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+#if defined CONFIG_MTD_REDBOOT_PARTS || CONFIG_MTD_MYLOADER_PARTS
|
+#if defined CONFIG_MTD_REDBOOT_PARTS || CONFIG_MTD_MYLOADER_PARTS
|
||||||
+static const char * const part_probe_types[] = {
|
+static const char * const part_probe_types[] = {
|
||||||
+ "cmdlinepart", "RedBoot", "MyLoader", NULL
|
+ "cmdlinepart", "RedBoot", "MyLoader", NULL
|
||||||
+};
|
+};
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+static int
|
+static int
|
||||||
+spiflash_probe(struct platform_device *pdev)
|
+spiflash_probe(struct platform_device *pdev)
|
||||||
+{
|
+{
|
||||||
|
@ -456,9 +412,7 @@
|
||||||
+ if (!priv)
|
+ if (!priv)
|
||||||
+ return -ENOMEM;
|
+ return -ENOMEM;
|
||||||
+
|
+
|
||||||
+ spin_lock_init(&priv->lock);
|
+ mutex_init(&priv->lock);
|
||||||
+ init_waitqueue_head(&priv->wq);
|
|
||||||
+ priv->state = FL_READY;
|
|
||||||
+ mtd = &priv->mtd;
|
+ mtd = &priv->mtd;
|
||||||
+
|
+
|
||||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user